const char *module_keyword = NULL, *module_name = NULL;
char *name;
- yasm_arch *arch;
+ yasm_arch_module *arch_module;
yasm_dbgfmt *dbgfmt;
yasm_objfmt *objfmt;
yasm_optimizer *optimizer;
- yasm_parser *parser;
+ yasm_parser_module *parser_module;
yasm_preproc *preproc;
lt_dlhandle handle;
switch (lmdata->type) {
case MODULE_ARCH:
strncpy(name, "yasm", 4);
- arch = lt_dlsym(handle, name);
- if (arch) {
- module_keyword = arch->keyword;
- module_name = arch->name;
+ arch_module = lt_dlsym(handle, name);
+ if (arch_module) {
+ module_keyword = arch_module->keyword;
+ module_name = arch_module->name;
}
break;
case MODULE_DBGFMT:
break;
case MODULE_PARSER:
strncpy(name+2, "yasm", 4);
- parser = lt_dlsym(handle, name+2);
- if (parser) {
- module_keyword = parser->keyword;
- module_name = parser->name;
+ parser_module = lt_dlsym(handle, name+2);
+ if (parser_module) {
+ module_keyword = parser_module->keyword;
+ module_name = parser_module->name;
}
break;
case MODULE_PREPROC:
/*@dependent@*/ /*@null@*/ void *get_module_data
(module_type type, const char *keyword, const char *symbol);
-#define load_arch(keyword) get_module_data(MODULE_ARCH, keyword, "arch")
+#define load_arch_module(keyword) get_module_data(MODULE_ARCH, keyword, "arch")
#define load_dbgfmt(keyword) \
get_module_data(MODULE_DBGFMT, keyword, "dbgfmt")
#define load_objfmt(keyword) \
get_module_data(MODULE_OBJFMT, keyword, "objfmt")
#define load_optimizer(keyword) \
get_module_data(MODULE_OPTIMIZER, keyword, "optimizer")
-#define load_parser(keyword) \
+#define load_parser_module(keyword) \
get_module_data(MODULE_PARSER, keyword, "parser")
#define load_preproc(keyword) \
get_module_data(MODULE_PREPROC, keyword, "preproc")
/*@null@*/ /*@only@*/ static char *machine_name = NULL;
static int special_options = 0;
/*@null@*/ /*@dependent@*/ static yasm_arch *cur_arch = NULL;
-/*@null@*/ /*@dependent@*/ static yasm_parser *cur_parser = NULL;
+/*@null@*/ /*@dependent@*/ static yasm_arch_module *cur_arch_module = NULL;
+/*@null@*/ /*@dependent@*/ static yasm_parser_module *cur_parser_module = NULL;
/*@null@*/ /*@dependent@*/ static yasm_preproc *cur_preproc = NULL;
/*@null@*/ /*@dependent@*/ static yasm_objfmt *cur_objfmt = NULL;
/*@null@*/ /*@dependent@*/ static yasm_optimizer *cur_optimizer = NULL;
static int warning_error = 0; /* warnings being treated as errors */
/*@null@*/ /*@dependent@*/ static FILE *open_obj(const char *mode);
-static void cleanup(/*@null@*/ yasm_sectionhead *sections);
+static void cleanup(/*@null@*/ yasm_object *object);
/* Forward declarations: cmd line parser handlers */
static int opt_special_handler(char *cmd, /*@null@*/ char *param, int extra);
main(int argc, char *argv[])
{
/*@null@*/ FILE *in = NULL, *obj = NULL;
- yasm_sectionhead *sections;
+ yasm_object *object = NULL;
+ yasm_section *def_sect;
size_t i;
#ifndef WIN32
int errors;
in_filename = yasm__xstrdup("-");
}
- /* Initialize line manager */
- yasm_std_linemgr.initialize();
- yasm_std_linemgr.set(in_filename, 1, 1);
-
/* Initialize intnum and floatnum */
yasm_intnum_initialize();
yasm_floatnum_initialize();
- /* Initialize symbol table */
- yasm_symrec_initialize();
-
/* handle preproc-only case here */
if (preproc_only) {
+ yasm_linemap *linemap;
char *preproc_buf = yasm_xmalloc(PREPROC_BUF_SIZE);
size_t got;
+ /* Initialize line manager */
+ linemap = yasm_linemap_create();
+ yasm_linemap_set(linemap, in_filename, 1, 1);
+
/* Default output to stdout if not specified */
if (!obj_filename)
obj = stdout;
apply_preproc_saved_options();
/* Pre-process until done */
- cur_preproc->initialize(in, in_filename, &yasm_std_linemgr);
+ cur_preproc->initialize(in, in_filename, linemap);
while ((got = cur_preproc->input(preproc_buf, PREPROC_BUF_SIZE)) != 0)
fwrite(preproc_buf, got, 1, obj);
fclose(obj);
if (yasm_get_num_errors(warning_error) > 0) {
- yasm_errwarn_output_all(&yasm_std_linemgr, warning_error,
- print_yasm_error, print_yasm_warning);
+ yasm_errwarn_output_all(linemap, warning_error, print_yasm_error,
+ print_yasm_warning);
if (obj != stdout)
remove(obj_filename);
yasm_xfree(preproc_buf);
+ yasm_linemap_destroy(linemap);
cleanup(NULL);
return EXIT_FAILURE;
}
yasm_xfree(preproc_buf);
+ yasm_linemap_destroy(linemap);
cleanup(NULL);
return EXIT_SUCCESS;
}
+ /* Create object */
+ object = yasm_object_create();
+
/* Default to x86 as the architecture */
- if (!cur_arch) {
- cur_arch = load_arch("x86");
- if (!cur_arch) {
+ if (!cur_arch_module) {
+ cur_arch_module = load_arch_module("x86");
+ if (!cur_arch_module) {
print_error(_("%s: could not load default %s"), _("FATAL"),
_("architecture"));
return EXIT_FAILURE;
}
}
- check_module_version(cur_arch, ARCH, "arch");
+ check_module_version(cur_arch_module, ARCH, "arch");
/* Set up architecture using the selected (or default) machine */
if (!machine_name)
- machine_name = yasm__xstrdup(cur_arch->default_machine_keyword);
-
- if (cur_arch->initialize(machine_name)) {
+ machine_name = yasm__xstrdup(cur_arch_module->default_machine_keyword);
+
+ cur_arch = cur_arch_module->create(machine_name);
+ if (!cur_arch) {
if (strcmp(machine_name, "help") == 0) {
- yasm_arch_machine *m = cur_arch->machines;
+ yasm_arch_machine *m = cur_arch_module->machines;
printf(_("Available %s for %s `%s':\n"), _("machines"),
- _("architecture"), cur_arch->keyword);
+ _("architecture"), cur_arch_module->keyword);
while (m->keyword && m->name) {
print_list_keyword_desc(m->name, m->keyword);
m++;
print_error(_("%s: `%s' is not a valid %s for %s `%s'"),
_("FATAL"), machine_name, _("machine"),
- _("architecture"), cur_arch->keyword);
+ _("architecture"), cur_arch_module->keyword);
return EXIT_FAILURE;
}
}
check_module_version(cur_optimizer, OPTIMIZER, "optimizer");
- yasm_arch_common_initialize(cur_arch);
- yasm_expr_initialize(cur_arch);
- yasm_bc_initialize(cur_arch);
-
/* If not already specified, default to bin as the object format. */
if (!cur_objfmt)
cur_objfmt = load_objfmt("bin");
/* Initialize the debug format */
if (cur_dbgfmt->initialize) {
- if (cur_dbgfmt->initialize(in_filename, obj_filename, &yasm_std_linemgr,
- cur_objfmt, cur_arch, machine_name))
+ if (cur_dbgfmt->initialize(in_filename, obj_filename, object,
+ cur_objfmt, cur_arch))
{
print_error(
_("%s: debug format `%s' does not work with object format `%s'"),
/* Initialize the object format */
if (cur_objfmt->initialize) {
- if (cur_objfmt->initialize(in_filename, obj_filename, cur_dbgfmt,
- cur_arch, machine_name)) {
+ if (cur_objfmt->initialize(in_filename, obj_filename, object,
+ cur_dbgfmt, cur_arch)) {
print_error(
_("%s: object format `%s' does not support architecture `%s' machine `%s'"),
- _("FATAL"), cur_objfmt->keyword, cur_arch->keyword,
+ _("FATAL"), cur_objfmt->keyword, cur_arch_module->keyword,
machine_name);
if (in != stdin)
fclose(in);
}
}
+ /* Add an initial "default" section to object */
+ def_sect = yasm_objfmt_add_default_section(cur_objfmt, object);
+
/* Default to NASM as the parser */
- if (!cur_parser) {
- cur_parser = load_parser("nasm");
- if (!cur_parser) {
+ if (!cur_parser_module) {
+ cur_parser_module = load_parser_module("nasm");
+ if (!cur_parser_module) {
print_error(_("%s: could not load default %s"), _("FATAL"),
_("parser"));
cleanup(NULL);
return EXIT_FAILURE;
}
}
- check_module_version(cur_parser, PARSER, "parser");
+ check_module_version(cur_parser_module, PARSER, "parser");
/* If not already specified, default to the parser's default preproc. */
if (!cur_preproc)
- cur_preproc = load_preproc(cur_parser->default_preproc_keyword);
+ cur_preproc = load_preproc(cur_parser_module->default_preproc_keyword);
else {
int matched_preproc = 0;
/* Check to see if the requested preprocessor is in the allowed list
* for the active parser.
*/
- for (i=0; cur_parser->preproc_keywords[i]; i++)
- if (yasm__strcasecmp(cur_parser->preproc_keywords[i],
+ for (i=0; cur_parser_module->preproc_keywords[i]; i++)
+ if (yasm__strcasecmp(cur_parser_module->preproc_keywords[i],
cur_preproc->keyword) == 0)
matched_preproc = 1;
if (!matched_preproc) {
print_error(_("%s: `%s' is not a valid %s for %s `%s'"),
_("FATAL"), cur_preproc->keyword, _("preprocessor"),
- _("parser"), cur_parser->keyword);
+ _("parser"), cur_parser_module->keyword);
if (in != stdin)
fclose(in);
cleanup(NULL);
apply_preproc_saved_options();
/* Get initial x86 BITS setting from object format */
- if (strcmp(cur_arch->keyword, "x86") == 0) {
- unsigned char *x86_mode_bits;
- x86_mode_bits = (unsigned char *)get_module_data(MODULE_ARCH, "x86",
- "mode_bits");
- if (x86_mode_bits)
- *x86_mode_bits = cur_objfmt->default_x86_mode_bits;
+ if (strcmp(cur_arch_module->keyword, "x86") == 0) {
+ cur_arch_module->set_var(cur_arch, "mode_bits",
+ cur_objfmt->default_x86_mode_bits);
}
/* Parse! */
- sections = cur_parser->do_parse(cur_preproc, cur_arch, cur_objfmt,
- &yasm_std_linemgr, in, in_filename, 0);
+ cur_parser_module->do_parse(object, cur_preproc, cur_arch, cur_objfmt, in,
+ in_filename, 0, def_sect);
/* Close input file */
if (in != stdin)
fclose(in);
if (yasm_get_num_errors(warning_error) > 0) {
- yasm_errwarn_output_all(&yasm_std_linemgr, warning_error,
+ yasm_errwarn_output_all(yasm_object_get_linemap(object), warning_error,
print_yasm_error, print_yasm_warning);
- cleanup(sections);
+ cleanup(object);
return EXIT_FAILURE;
}
- yasm_symrec_parser_finalize();
- cur_optimizer->optimize(sections);
+ yasm_symtab_parser_finalize(yasm_object_get_symtab(object));
+ cur_optimizer->optimize(object);
if (yasm_get_num_errors(warning_error) > 0) {
- yasm_errwarn_output_all(&yasm_std_linemgr, warning_error,
+ yasm_errwarn_output_all(yasm_object_get_linemap(object), warning_error,
print_yasm_error, print_yasm_warning);
- cleanup(sections);
+ cleanup(object);
return EXIT_FAILURE;
}
/* generate any debugging information */
if (cur_dbgfmt->generate) {
- cur_dbgfmt->generate(sections);
+ cur_dbgfmt->generate(object);
}
/* open the object file for output (if not already opened by dbg objfmt) */
if (!obj && strcmp(cur_objfmt->keyword, "dbg") != 0) {
obj = open_obj("wb");
if (!obj) {
- cleanup(sections);
+ cleanup(object);
return EXIT_FAILURE;
}
}
/* Write the object file */
- cur_objfmt->output(obj?obj:stderr, sections,
+ cur_objfmt->output(obj?obj:stderr, object,
strcmp(cur_dbgfmt->keyword, "null"));
/* Close object file */
* object file (to make sure it's not left newer than the source).
*/
if (yasm_get_num_errors(warning_error) > 0) {
- yasm_errwarn_output_all(&yasm_std_linemgr, warning_error,
+ yasm_errwarn_output_all(yasm_object_get_linemap(object), warning_error,
print_yasm_error, print_yasm_warning);
remove(obj_filename);
- cleanup(sections);
+ cleanup(object);
return EXIT_FAILURE;
}
- yasm_errwarn_output_all(&yasm_std_linemgr, warning_error,
+ yasm_errwarn_output_all(yasm_object_get_linemap(object), warning_error,
print_yasm_error, print_yasm_warning);
- cleanup(sections);
+ cleanup(object);
return EXIT_SUCCESS;
}
/*@=globstate =unrecog@*/
/* Cleans up all allocated structures. */
static void
-cleanup(yasm_sectionhead *sections)
+cleanup(yasm_object *object)
{
if (DO_FREE) {
if (cur_objfmt && cur_objfmt->cleanup)
cur_dbgfmt->cleanup();
if (cur_preproc)
cur_preproc->cleanup();
- if (sections)
- yasm_sections_delete(sections);
- yasm_symrec_cleanup();
+ if (object)
+ yasm_object_destroy(object);
if (cur_arch)
- cur_arch->cleanup();
+ cur_arch_module->destroy(cur_arch);
yasm_floatnum_cleanup();
yasm_intnum_cleanup();
yasm_errwarn_cleanup();
- yasm_std_linemgr.cleanup();
BitVector_Shutdown();
}
opt_arch_handler(/*@unused@*/ char *cmd, char *param, /*@unused@*/ int extra)
{
assert(param != NULL);
- cur_arch = load_arch(param);
- if (!cur_arch) {
+ cur_arch_module = load_arch_module(param);
+ if (!cur_arch_module) {
if (!strcmp("help", param)) {
printf(_("Available yasm %s:\n"), _("architectures"));
list_archs(print_list_keyword_desc);
opt_parser_handler(/*@unused@*/ char *cmd, char *param, /*@unused@*/ int extra)
{
assert(param != NULL);
- cur_parser = load_parser(param);
- if (!cur_parser) {
+ cur_parser_module = load_parser_module(param);
+ if (!cur_parser_module) {
if (!strcmp("help", param)) {
printf(_("Available yasm %s:\n"), _("parsers"));
list_parsers(print_list_keyword_desc);
libyasm_la_SOURCES += libyasm/file.c
libyasm_la_SOURCES += libyasm/section.c
libyasm_la_SOURCES += libyasm/arch.c
+libyasm_la_SOURCES += libyasm/objfmt.c
libyasm_la_SOURCES += libyasm/intnum.c
libyasm_la_SOURCES += libyasm/floatnum.c
libyasm_la_SOURCES += libyasm/hamt.c
libyasm_la_SOURCES += libyasm/valparam.c
libyasm_la_SOURCES += libyasm/errwarn.c
libyasm_la_SOURCES += libyasm/linemgr.c
+libyasm_la_SOURCES += libyasm/assocdat.c
+libyasm_la_SOURCES += libyasm/assocdat.h
libyasm_la_SOURCES += libyasm/xmalloc.c
libyasm_la_SOURCES += libyasm/xstrdup.c
libyasm_la_SOURCES += libyasm/strcasecmp.c
* POSSIBILITY OF SUCH DAMAGE.
*/
#define YASM_LIB_INTERNAL
+#define YASM_ARCH_INTERNAL
#include "util.h"
-/*@unused@*/ RCSID("$IdPath: yasm/libyasm/arch.c,v 1.11 2003/03/15 05:07:48 peter Exp $");
+/*@unused@*/ RCSID("$IdPath$");
#include "coretype.h"
#include "arch.h"
-static /*@dependent@*/ yasm_arch *cur_arch;
-
-void
-yasm_arch_common_initialize(yasm_arch *a)
+yasm_arch_module *
+yasm_arch_get_module(yasm_arch *arch)
{
- cur_arch = a;
+ return arch->module;
}
yasm_insn_operand *
-yasm_operand_new_reg(unsigned long reg)
+yasm_operand_create_reg(unsigned long reg)
{
yasm_insn_operand *retval = yasm_xmalloc(sizeof(yasm_insn_operand));
}
yasm_insn_operand *
-yasm_operand_new_segreg(unsigned long segreg)
+yasm_operand_create_segreg(unsigned long segreg)
{
yasm_insn_operand *retval = yasm_xmalloc(sizeof(yasm_insn_operand));
}
yasm_insn_operand *
-yasm_operand_new_mem(/*@only@*/ yasm_effaddr *ea)
+yasm_operand_create_mem(/*@only@*/ yasm_effaddr *ea)
{
yasm_insn_operand *retval = yasm_xmalloc(sizeof(yasm_insn_operand));
}
yasm_insn_operand *
-yasm_operand_new_imm(/*@only@*/ yasm_expr *val)
+yasm_operand_create_imm(/*@only@*/ yasm_expr *val)
{
yasm_insn_operand *retval;
const unsigned long *reg;
reg = yasm_expr_get_reg(&val, 0);
if (reg) {
- retval = yasm_operand_new_reg(*reg);
- yasm_expr_delete(val);
+ retval = yasm_operand_create_reg(*reg);
+ yasm_expr_destroy(val);
} else {
retval = yasm_xmalloc(sizeof(yasm_insn_operand));
retval->type = YASM_INSN__OPERAND_IMM;
}
void
-yasm_operand_print(FILE *f, int indent_level, const yasm_insn_operand *op)
+yasm_operand_print(const yasm_insn_operand *op, FILE *f, int indent_level,
+ yasm_arch *arch)
{
switch (op->type) {
case YASM_INSN__OPERAND_REG:
fprintf(f, "%*sReg=", indent_level, "");
- cur_arch->reg_print(f, op->data.reg);
+ arch->module->reg_print(arch, op->data.reg, f);
fprintf(f, "\n");
break;
case YASM_INSN__OPERAND_SEGREG:
fprintf(f, "%*sSegReg=", indent_level, "");
- cur_arch->segreg_print(f, op->data.reg);
+ arch->module->segreg_print(arch, op->data.reg, f);
fprintf(f, "\n");
break;
case YASM_INSN__OPERAND_MEMORY:
fprintf(f, "%*sMemory=\n", indent_level, "");
- yasm_ea_print(f, indent_level, op->data.ea);
+ yasm_ea_print(op->data.ea, f, indent_level);
break;
case YASM_INSN__OPERAND_IMM:
fprintf(f, "%*sImm=", indent_level, "");
- yasm_expr_print(f, op->data.val);
+ yasm_expr_print(op->data.val, f);
fprintf(f, "\n");
break;
}
if (content)
switch (cur->type) {
case YASM_INSN__OPERAND_MEMORY:
- yasm_ea_delete(cur->data.ea);
+ yasm_ea_destroy(cur->data.ea);
break;
case YASM_INSN__OPERAND_IMM:
- yasm_expr_delete(cur->data.val);
+ yasm_expr_destroy(cur->data.val);
break;
default:
break;
}
void
-yasm_ops_print(FILE *f, int indent_level, const yasm_insn_operandhead *headp)
+yasm_ops_print(const yasm_insn_operandhead *headp, FILE *f, int indent_level,
+ yasm_arch *arch)
{
yasm_insn_operand *cur;
STAILQ_FOREACH (cur, headp, link)
- yasm_operand_print(f, indent_level, cur);
+ yasm_operand_print(cur, f, indent_level, arch);
+}
+
+yasm_insn_operandhead *
+yasm_ops_create(void)
+{
+ yasm_insn_operandhead *headp = yasm_xmalloc(sizeof(yasm_insn_operandhead));
+ yasm_ops_initialize(headp);
+ return headp;
}
-/* Non-macro yasm_ops_initialize() for non-YASM_LIB_INTERNAL users. */
-#undef yasm_ops_initialize
void
-yasm_ops_initialize(yasm_insn_operandhead *headp)
+yasm_ops_destroy(yasm_insn_operandhead *headp, int content)
{
- STAILQ_INIT(headp);
+ yasm_ops_delete(headp, content);
+ yasm_xfree(headp);
}
/* Non-macro yasm_ops_first() for non-YASM_LIB_INTERNAL users. */
return STAILQ_FIRST(headp);
}
-/* Non-macro yasm_ops_next() for non-YASM_LIB_INTERNAL users. */
-#undef yasm_ops_next
+/* Non-macro yasm_operand_next() for non-YASM_LIB_INTERNAL users. */
+#undef yasm_operand_next
yasm_insn_operand *
-yasm_ops_next(yasm_insn_operand *cur)
+yasm_operand_next(yasm_insn_operand *cur)
{
return STAILQ_NEXT(cur, link);
}
#ifndef YASM_ARCH_H
#define YASM_ARCH_H
-/** Return value from yasm_arch::parse_check_id(). */
+/** Return value from yasm_arch_module::parse_check_id(). */
typedef enum {
YASM_ARCH_CHECK_ID_NONE = 0, /**< Just a normal identifier. */
YASM_ARCH_CHECK_ID_INSN, /**< An instruction. */
/*@reldef@*/ STAILQ_HEAD(yasm_insn_operandhead, yasm_insn_operand);
#endif
+/** Base #yasm_arch structure. Must be present as the first element in any
+ * #yasm_arch implementation.
+ */
+struct yasm_arch {
+ /** #yasm_arch_module implementation for this architecture. */
+ struct yasm_arch_module *module;
+};
+
/** "Flavor" of the parser.
* Different assemblers order instruction operands differently. Also, some
* differ on how exactly various registers are specified. There's no great
const char *keyword;
} yasm_arch_machine;
-/** Version number of #yasm_arch interface. Any functional change to the
- * #yasm_arch interface should simultaneously increment this number. This
- * version should be checked by #yasm_arch loaders to verify that the
- * expected version (the version defined by its libyasm header files) matches
- * the loaded module version (the version defined by the module's libyasm
- * header files). Doing this will ensure that the module version's function
- * definitions match the module loader's function definitions. The version
- * number must never be decreased.
+/** Version number of #yasm_arch_module interface. Any functional change to
+ * the #yasm_arch_module interface should simultaneously increment this number.
+ * This version should be checked by #yasm_arch_module loaders to verify that
+ * the expected version (the version defined by its libyasm header files)
+ * matches the loaded module version (the version defined by the module's
+ * libyasm header files). Doing this will ensure that the module version's
+ * function definitions match the module loader's function definitions. The
+ * version number must never be decreased.
*/
-#define YASM_ARCH_VERSION 1
+#define YASM_ARCH_VERSION 2
-/** YASM architecture interface.
+/** YASM architecture module interface.
* \note All "data" in parser-related functions (parse_*) needs to start the
* parse initialized to 0 to make it okay for a parser-related function
* to use/check previously stored data to see if it's been called before
* on the same piece of data.
*/
-struct yasm_arch {
+typedef struct yasm_arch_module {
/** Version (see #YASM_ARCH_VERSION). Should always be set to
* #YASM_ARCH_VERSION by the module source and checked against
* #YASM_ARCH_VERSION by the module loader.
/** Initialize architecture for use.
* \param machine keyword of machine in use (must be one listed in
* #machines)
- * \return Nonzero if machine not recognized.
+ * \return NULL if machine not recognized.
*/
- int (*initialize) (const char *machine);
+ /*@only@*/ yasm_arch * (*create) (const char *machine);
/** Clean up, free any architecture-allocated memory. */
- void (*cleanup) (void);
+ void (*destroy) (/*@only@*/ yasm_arch *arch);
+
+ /** Get machine name in use. */
+ const char * (*get_machine) (const yasm_arch *arch);
+
+ /** Set any arch-specific variables. For example, "mode_bits" in x86.
+ * \return Zero on success, non-zero on failure (variable does not exist).
+ */
+ int (*set_var) (yasm_arch *arch, const char *var, unsigned long val);
/** Switch available instructions/registers/etc based on a user-specified
* CPU identifier. Should modify behavior ONLY of parse_* functions! The
* bytecode and output functions should be able to handle any CPU.
* \param cpuid cpu identifier as in the input file
- * \param lindex line index (as from yasm_linemgr)
+ * \param line virtual line (from yasm_linemap)
*/
- void (*parse_cpu) (const char *cpuid, unsigned long lindex);
+ void (*parse_cpu) (yasm_arch *arch, const char *cpuid,
+ unsigned long line);
/** Check an generic identifier to see if it matches architecture specific
* names for instructions, registers, etc. Unrecognized identifiers should
* \param data extra identification information (yasm_arch-specific)
* [output]
* \param id identifier as in the input file
- * \param lindex line index (as from yasm_linemgr)
+ * \param line virtual line (from yasm_linemap)
* \return General type of identifier (#yasm_arch_check_id_retval).
*/
yasm_arch_check_id_retval (*parse_check_id)
- (unsigned long data[4], const char *id, unsigned long lindex);
+ (yasm_arch *arch, unsigned long data[4], const char *id,
+ unsigned long line);
/** Handle architecture-specific directives.
* Should modify behavior ONLY of parse functions, much like parse_cpu().
* \param objext_valparams object format extensions
* value/parameters
* \param headp list of sections
- * \param lindex line index (as from yasm_linemgr)
+ * \param line virtual line (as from yasm_linemap)
* \return Nonzero if directive was not recognized; 0 if directive was
* recognized, even if it wasn't valid.
*/
- int (*parse_directive) (const char *name, yasm_valparamhead *valparams,
+ int (*parse_directive) (yasm_arch *arch, const char *name,
+ yasm_valparamhead *valparams,
/*@null@*/ yasm_valparamhead *objext_valparams,
- yasm_sectionhead *headp, unsigned long lindex);
+ yasm_object *object, unsigned long line);
/** Create an instruction. Creates a bytecode by matching the
* instruction data and the parameters given with a valid instruction.
* \param cur_section currently active section
* \param prev_bc previously parsed bytecode in section (NULL if
* first bytecode in section)
- * \param lindex line index (as from yasm_linemgr)
+ * \param line virtual line (from yasm_linemap)
* \return If no match is found (the instruction is invalid), NULL,
* otherwise newly allocated bytecode containing instruction.
*/
/*@null@*/ yasm_bytecode * (*parse_insn)
- (const unsigned long data[4], int num_operands,
- /*@null@*/ yasm_insn_operandhead *operands, yasm_section *cur_section,
- /*@null@*/ yasm_bytecode *prev_bc, unsigned long lindex);
+ (yasm_arch *arch, const unsigned long data[4], int num_operands,
+ /*@null@*/ yasm_insn_operandhead *operands, yasm_bytecode *prev_bc,
+ unsigned long line);
/** Handle an instruction prefix.
* Modifies an instruction bytecode based on the prefix in data.
* \param bc bytecode (must be instruction bytecode)
* \param data prefix (from parse_check_id())
- * \param lindex line index (as from yasm_linemgr)
+ * \param line virtual line (from yasm_linemap)
*/
- void (*parse_prefix) (yasm_bytecode *bc, const unsigned long data[4],
- unsigned long lindex);
+ void (*parse_prefix) (yasm_arch *arch, yasm_bytecode *bc,
+ const unsigned long data[4], unsigned long line);
/** Handle an segment register instruction prefix.
* Modifies an instruction bytecode based on a segment register prefix.
* \param bc bytecode (must be instruction bytecode)
* \param segreg segment register (from parse_check_id())
- * \param lindex line index (as from yasm_linemgr)
+ * \param line virtual line (from yasm_linemap)
*/
- void (*parse_seg_prefix) (yasm_bytecode *bc, unsigned long segreg,
- unsigned long lindex);
+ void (*parse_seg_prefix) (yasm_arch *arch, yasm_bytecode *bc,
+ unsigned long segreg, unsigned long line);
/** Handle a memory expression segment override.
* Modifies an instruction bytecode based on a segment override in a
* memory expression.
* \param bc bytecode (must be instruction bytecode)
* \param segreg segment register (from parse_check_id())
- * \param lindex line index (as from yasm_linemgr)
- */
- void (*parse_seg_override) (yasm_effaddr *ea, unsigned long segreg,
- unsigned long lindex);
-
- /** Maximum used bytecode type value+1. Should be set to
- * #YASM_BYTECODE_TYPE_BASE if no additional bytecode types are defined
- * by the architecture.
- * \internal
- */
- const int bc_type_max;
-
- /** Delete a yasm_arch-defined bytecode.
- * \internal Do not call directly, instead call yasm_bc_delete().
- *
- * \copydoc yasm_bc_delete()
- */
- void (*bc_delete) (yasm_bytecode *bc);
-
- /** Print a yasm_arch-defined bytecode.
- * \internal Do not call directly, instead call yasm_bc_print().
- *
- * \copydoc yasm_bc_print()
+ * \param line virtual line (from yasm_linemap)
*/
- void (*bc_print) (FILE *f, int indent_level, const yasm_bytecode *bc);
-
- /** Resolve labels in a yasm_arch-defined bytecode.
- * \internal Do not call directly, instead call yasm_bc_resolve().
- *
- * \copydoc yasm_bc_resolve()
- */
- yasm_bc_resolve_flags (*bc_resolve)
- (yasm_bytecode *bc, int save, const yasm_section *sect,
- yasm_calc_bc_dist_func calc_bc_dist);
-
- /** Convert a yasm_arch-defined bytecode into its byte representation.
- * \internal Do not call directly, instead call yasm_bc_tobytes().
- *
- * \copydoc yasm_bc_tobytes()
- */
- int (*bc_tobytes) (yasm_bytecode *bc, unsigned char **bufp,
- const yasm_section *sect, void *d,
- yasm_output_expr_func output_expr);
+ void (*parse_seg_override) (yasm_arch *arch, yasm_effaddr *ea,
+ unsigned long segreg, unsigned long line);
/** Output #yasm_floatnum to buffer. Puts the value into the least
* significant bits of the destination, or may be shifted into more
* \param valsize size (in bits)
* \param shift left shift (in bits)
* \param warn enables standard overflow/underflow warnings
- * \param lindex line index; may be 0 if warn is 0.
+ * \param line virtual line; may be 0 if warn is 0.
* \return Nonzero on error.
*/
- int (*floatnum_tobytes) (const yasm_floatnum *flt, unsigned char *buf,
- size_t destsize, size_t valsize, size_t shift,
- int warn, unsigned long lindex);
+ int (*floatnum_tobytes) (yasm_arch *arch, const yasm_floatnum *flt,
+ unsigned char *buf, size_t destsize,
+ size_t valsize, size_t shift, int warn,
+ unsigned long line);
/** Output #yasm_intnum to buffer. Puts the value into the least
* significant bits of the destination, or may be shifted into more
* \param rel value is a relative displacement from bc
* \param warn enables standard warnings (value doesn't fit into
* valsize bits)
- * \param lindex line index; may be 0 if warn is 0
+ * \param line virtual line; may be 0 if warn is 0
* \return Nonzero on error.
*/
- int (*intnum_tobytes) (const yasm_intnum *intn, unsigned char *buf,
- size_t destsize, size_t valsize, int shift,
- const yasm_bytecode *bc, int rel, int warn,
- unsigned long lindex);
+ int (*intnum_tobytes) (yasm_arch *arch, const yasm_intnum *intn,
+ unsigned char *buf, size_t destsize, size_t valsize,
+ int shift, const yasm_bytecode *bc, int rel,
+ int warn, unsigned long line);
/** Get the equivalent byte size of a register.
* \param reg register
* \return 0 if there is no suitable equivalent size, otherwise the size.
*/
- unsigned int (*get_reg_size) (unsigned long reg);
+ unsigned int (*get_reg_size) (yasm_arch *arch, unsigned long reg);
/** Print a register. For debugging purposes.
* \param f file
* \param indent_level indentation level
* \param reg register
*/
- void (*reg_print) (FILE *f, unsigned long reg);
+ void (*reg_print) (yasm_arch *arch, unsigned long reg, FILE *f);
/** Print a segment register. For debugging purposes.
* \param f file
* \param indent_level indentation level
* \param segreg segment register
*/
- void (*segreg_print) (FILE *f, unsigned long segreg);
+ void (*segreg_print) (yasm_arch *arch, unsigned long segreg, FILE *f);
/** Create an effective address from an expression.
* \param e expression (kept, do not delete)
* \return Newly allocated effective address.
*/
- yasm_effaddr * (*ea_new_expr) (/*@keep@*/ yasm_expr *e);
-
- /** Delete the yasm_arch-specific data in an effective address.
- * May be NULL if no special deletion is required (e.g. there's no
- * dynamically allocated pointers in the effective address data).
- * \internal Do not call directly, instead call yasm_ea_delete().
- *
- * \copydoc yasm_ea_delete()
- */
- void (*ea_data_delete) (yasm_effaddr *ea);
-
- /** Print the yasm_arch-specific data in an effective address.
- * \internal Do not call directly, instead call yasm_ea_print().
- *
- * \copydoc yasm_ea_print()
- */
- void (*ea_data_print) (FILE *f, int indent_level, const yasm_effaddr *ea);
+ yasm_effaddr * (*ea_create) (yasm_arch *arch, /*@keep@*/ yasm_expr *e);
/** NULL-terminated list of machines for this architecture. */
yasm_arch_machine *machines;
/** Canonical "word" size in bytes. */
unsigned int wordsize;
-};
+} yasm_arch_module;
#ifdef YASM_LIB_INTERNAL
/** An instruction operand. */
};
#endif
-/** Common initializer for yasm_arch helper functions.
- * \param a architecture in use
+/** Get the yasm_arch_module implementation for a yasm_arch.
+ * \param arch architecture
+ * \return Module implementation.
*/
-void yasm_arch_common_initialize(yasm_arch *a);
+yasm_arch_module *yasm_arch_get_module(yasm_arch *arch);
/** Create an instruction operand from a register.
* \param reg register
* \return Newly allocated operand.
*/
-yasm_insn_operand *yasm_operand_new_reg(unsigned long reg);
+yasm_insn_operand *yasm_operand_create_reg(unsigned long reg);
/** Create an instruction operand from a segment register.
* \param segreg segment register
* \return Newly allocated operand.
*/
-yasm_insn_operand *yasm_operand_new_segreg(unsigned long segreg);
+yasm_insn_operand *yasm_operand_create_segreg(unsigned long segreg);
/** Create an instruction operand from an effective address.
* \param ea effective address
* \return Newly allocated operand.
*/
-yasm_insn_operand *yasm_operand_new_mem(/*@only@*/ yasm_effaddr *ea);
+yasm_insn_operand *yasm_operand_create_mem(/*@only@*/ yasm_effaddr *ea);
/** Create an instruction operand from an immediate expression.
* Looks for cases of a single register and creates a register variant of
* \param val immediate expression
* \return Newly allocated operand.
*/
-yasm_insn_operand *yasm_operand_new_imm(/*@only@*/ yasm_expr *val);
+yasm_insn_operand *yasm_operand_create_imm(/*@only@*/ yasm_expr *val);
/** Print an instruction operand. For debugging purposes.
+ * \param arch architecture
* \param f file
* \param indent_level indentation level
* \param op instruction operand
*/
-void yasm_operand_print(FILE *f, int indent_level,
- const yasm_insn_operand *op);
+void yasm_operand_print(const yasm_insn_operand *op, FILE *f, int indent_level,
+ yasm_arch *arch);
-/** Initialize a list of instruction operands.
- * \param headp list of instruction operands
+/** Create a new list of instruction operands.
+ * \return Newly allocated list.
*/
-void yasm_ops_initialize(yasm_insn_operandhead *headp);
+yasm_insn_operandhead *yasm_ops_create(void);
+
+/** Destroy a list of instruction operands (created with yasm_ops_create()).
+ * \param headp list of instruction operands
+ * \param content if nonzero, deletes content of each operand
+ */
+void yasm_ops_destroy(yasm_insn_operandhead *headp, int content);
/** Get the first operand in a list of instruction operands.
* \param headp list of instruction operands
* \param cur previous operand
* \return Next operand in list (NULL if cur was the last operand).
*/
-yasm_insn_operand *yasm_ops_next(yasm_insn_operand *cur);
+yasm_insn_operand *yasm_operand_next(yasm_insn_operand *cur);
#ifdef YASM_LIB_INTERNAL
#define yasm_ops_initialize(headp) STAILQ_INIT(headp)
#define yasm_ops_first(headp) STAILQ_FIRST(headp)
-#define yasm_ops_next(cur) STAILQ_NEXT(cur, link)
-#endif
+#define yasm_operand_next(cur) STAILQ_NEXT(cur, link)
-/** Delete (free allocated memory for) a list of instruction operands.
+/** Delete (free allocated memory for) a list of instruction operands (created
+ * with yasm_ops_initialize()).
* \param headp list of instruction operands
* \param content if nonzero, deletes content of each operand
*/
void yasm_ops_delete(yasm_insn_operandhead *headp, int content);
+#endif
/** Add data value to the end of a list of instruction operands.
* \note Does not make a copy of the operand; so don't pass this function
/*@returned@*/ /*@null@*/ yasm_insn_operand *op);
/** Print a list of instruction operands. For debugging purposes.
+ * \param arch architecture
* \param f file
* \param indent_level indentation level
* \param headp list of instruction operands
*/
-void yasm_ops_print(FILE *f, int indent_level,
- const yasm_insn_operandhead *headp);
+void yasm_ops_print(const yasm_insn_operandhead *headp, FILE *f,
+ int indent_level, yasm_arch *arch);
#endif
--- /dev/null
+/*
+ * YASM associated data storage (libyasm internal use)
+ *
+ * Copyright (C) 2003 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("$IdPath$");
+
+#include "coretype.h"
+#include "assocdat.h"
+
+
+typedef struct assoc_data_item {
+ const yasm_assoc_data_callback *callback;
+ void *data;
+} assoc_data_item;
+
+struct yasm__assoc_data {
+ assoc_data_item *vector;
+ size_t size;
+ size_t alloc;
+};
+
+
+yasm__assoc_data *
+yasm__assoc_data_create(void)
+{
+ yasm__assoc_data *assoc_data = yasm_xmalloc(sizeof(yasm__assoc_data));
+
+ assoc_data->size = 0;
+ assoc_data->alloc = 2;
+ assoc_data->vector = yasm_xmalloc(assoc_data->alloc *
+ sizeof(assoc_data_item));
+
+ return assoc_data;
+}
+
+void *
+yasm__assoc_data_get(yasm__assoc_data *assoc_data,
+ const yasm_assoc_data_callback *callback)
+{
+ size_t i;
+
+ if (!assoc_data)
+ return NULL;
+
+ for (i=0; i<assoc_data->size; i++) {
+ if (assoc_data->vector[i].callback == callback)
+ return assoc_data->vector[i].data;
+ }
+ return NULL;
+}
+
+yasm__assoc_data *
+yasm__assoc_data_add(yasm__assoc_data *assoc_data_arg,
+ const yasm_assoc_data_callback *callback, void *data)
+{
+ yasm__assoc_data *assoc_data;
+ assoc_data_item *item = NULL;
+ size_t i;
+
+ /* Create a new assoc_data if necessary */
+ if (assoc_data_arg)
+ assoc_data = assoc_data_arg;
+ else
+ assoc_data = yasm__assoc_data_create();
+
+ /* See if there's already assocated data for this callback */
+ for (i=0; i<assoc_data->size; i++) {
+ if (assoc_data->vector[i].callback == callback)
+ item = &assoc_data->vector[i];
+ }
+
+ /* No? Then append a new one */
+ if (!item) {
+ assoc_data->size++;
+ if (assoc_data->size > assoc_data->alloc) {
+ assoc_data->alloc *= 2;
+ assoc_data->vector =
+ yasm_xrealloc(assoc_data->vector,
+ assoc_data->alloc * sizeof(assoc_data_item));
+ }
+ item = &assoc_data->vector[assoc_data->size-1];
+ item->callback = callback;
+ item->data = NULL;
+ }
+
+ /* Delete existing data (if any) */
+ if (item->data)
+ item->callback->destroy(item->data);
+
+ item->data = data;
+
+ return assoc_data;
+}
+
+void
+yasm__assoc_data_destroy(yasm__assoc_data *assoc_data)
+{
+ size_t i;
+
+ if (!assoc_data)
+ return;
+
+ for (i=0; i<assoc_data->size; i++)
+ assoc_data->vector[i].callback->destroy(assoc_data->vector[i].data);
+ yasm_xfree(assoc_data->vector);
+ yasm_xfree(assoc_data);
+}
+
+void
+yasm__assoc_data_print(const yasm__assoc_data *assoc_data, FILE *f,
+ int indent_level)
+{
+ /*TODO*/
+}
--- /dev/null
+/**
+ * \file assocdat.h
+ * \brief YASM associated data storage (libyasm internal use)
+ *
+ * \rcs
+ * $IdPath$
+ * \endrcs
+ *
+ * \license
+ * Copyright (C) 2003 Peter Johnson
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * - 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.
+ * \endlicense
+ */
+#ifndef YASM_ASSOCDAT_H
+#define YASM_ASSOCDAT_H
+
+/** Associated data container. */
+typedef struct yasm__assoc_data yasm__assoc_data;
+
+/** Create an associated data container. */
+/*@only@*/ yasm__assoc_data *yasm__assoc_data_create(void);
+
+/** Get associated data for a data callback.
+ * \param assoc_data container of associated data
+ * \param callback callback used when adding data
+ * \return Associated data (NULL if none).
+ */
+/*@dependent@*/ /*@null@*/ void *yasm__assoc_data_get
+ (/*@null@*/ yasm__assoc_data *assoc_data,
+ const yasm_assoc_data_callback *callback);
+
+/** Add associated data to a associated data container.
+ * \attention Deletes any existing associated data for that data callback.
+ * \param assoc_data container of associated data
+ * \param callback callback
+ * \param data data to associate
+ */
+/*@only@*/ yasm__assoc_data *yasm__assoc_data_add
+ (/*@null@*/ /*@only@*/ yasm__assoc_data *assoc_data,
+ const yasm_assoc_data_callback *callback,
+ /*@only@*/ /*@null@*/ void *data);
+
+/** Destroy all associated data in a container. */
+void yasm__assoc_data_destroy
+ (/*@null@*/ /*@only@*/ yasm__assoc_data *assoc_data);
+
+/** Print all associated data in a container. */
+void yasm__assoc_data_print(const yasm__assoc_data *assoc_data, FILE *f,
+ int indent_level);
+
+#endif
#ifndef YASM_BC_INT_H
#define YASM_BC_INT_H
+typedef struct yasm_effaddr_callback {
+ void (*destroy) (yasm_effaddr *ea);
+ void (*print) (const yasm_effaddr *ea, FILE *f, int indent_level);
+} yasm_effaddr_callback;
+
struct yasm_effaddr {
+ const yasm_effaddr_callback *callback; /* callback functions */
+
/*@only@*/ /*@null@*/ yasm_expr *disp; /* address displacement */
unsigned char len; /* length of disp (in bytes), 0 if unknown,
* 0xff if unknown and required to be >0.
unsigned char sign; /* 1 if final imm is treated as signed */
};
+typedef struct yasm_bytecode_callback {
+ void (*destroy) (yasm_bytecode *bc);
+ void (*print) (const yasm_bytecode *bc, FILE *f, int indent_level);
+ yasm_bc_resolve_flags (*resolve)
+ (yasm_bytecode *bc, int save, yasm_calc_bc_dist_func calc_bc_dist);
+ int (*tobytes) (yasm_bytecode *bc, unsigned char **bufp, void *d,
+ yasm_output_expr_func output_expr,
+ /*@null@*/ yasm_output_reloc_func output_reloc);
+} yasm_bytecode_callback;
+
struct yasm_bytecode {
/*@reldef@*/ STAILQ_ENTRY(yasm_bytecode) link;
- yasm_bytecode_type type;
+ /*@null@*/ const yasm_bytecode_callback *callback;
+
+ /* Pointer to section containing bytecode; NULL if not part of a section. */
+ /*@dependent@*/ /*@null@*/ yasm_section *section;
/* number of times bytecode is repeated, NULL=1. */
/*@only@*/ /*@null@*/ yasm_expr *multiple;
unsigned long opt_flags;
};
-#define yasm_bcs__next(x) STAILQ_NEXT(x, link)
+/** Create a bytecode of any specified type.
+ * \param callback bytecode callback functions, if NULL, creates empty
+ * bytecode (may not be resolved or output)
+ * \param datasize size of type-specific data (in bytes)
+ * \param line virtual line (from yasm_linemap)
+ * \return Newly allocated bytecode of the specified type.
+ */
+/*@only@*/ yasm_bytecode *yasm_bc_create_common
+ (/*@null@*/ const yasm_bytecode_callback *callback, size_t datasize,
+ unsigned long line);
+
+#define yasm_bc__next(x) STAILQ_NEXT(x, link)
#endif
return(result);
}
-static wordptr from_Dec_term = NULL;
-static wordptr from_Dec_base = NULL;
-static wordptr from_Dec_prod = NULL;
-static wordptr from_Dec_rank = NULL;
-static wordptr from_Dec_temp = NULL;
+struct BitVector_from_Dec_static_data {
+ wordptr term;
+ wordptr base;
+ wordptr prod;
+ wordptr rank;
+ wordptr temp;
+};
-ErrCode BitVector_from_Dec_static_Boot(N_word bits)
+BitVector_from_Dec_static_data *BitVector_from_Dec_static_Boot(N_word bits)
{
+ BitVector_from_Dec_static_data *data;
+
+ data = yasm_xmalloc(sizeof(BitVector_from_Dec_static_data));
+
if (bits > 0)
{
- BitVector_from_Dec_static_Shutdown();
- from_Dec_term = BitVector_Create(BITS,FALSE);
- if (from_Dec_term == NULL)
- {
- return(ErrCode_Null);
- }
- from_Dec_base = BitVector_Create(BITS,FALSE);
- if (from_Dec_base == NULL)
- {
- BitVector_Destroy(from_Dec_term);
- return(ErrCode_Null);
- }
- from_Dec_prod = BitVector_Create(bits,FALSE);
- if (from_Dec_prod == NULL)
- {
- BitVector_Destroy(from_Dec_term);
- BitVector_Destroy(from_Dec_base);
- return(ErrCode_Null);
- }
- from_Dec_rank = BitVector_Create(bits,FALSE);
- if (from_Dec_rank == NULL)
- {
- BitVector_Destroy(from_Dec_term);
- BitVector_Destroy(from_Dec_base);
- BitVector_Destroy(from_Dec_prod);
- return(ErrCode_Null);
- }
- from_Dec_temp = BitVector_Create(bits,FALSE);
- if (from_Dec_temp == NULL)
- {
- BitVector_Destroy(from_Dec_term);
- BitVector_Destroy(from_Dec_base);
- BitVector_Destroy(from_Dec_prod);
- BitVector_Destroy(from_Dec_rank);
- return(ErrCode_Null);
- }
+ data->term = BitVector_Create(BITS,FALSE);
+ data->base = BitVector_Create(BITS,FALSE);
+ data->prod = BitVector_Create(bits,FALSE);
+ data->rank = BitVector_Create(bits,FALSE);
+ data->temp = BitVector_Create(bits,FALSE);
+ } else {
+ data->term = NULL;
+ data->base = NULL;
+ data->prod = NULL;
+ data->rank = NULL;
+ data->temp = NULL;
}
- return(ErrCode_Ok);
+ return data;
}
-void BitVector_from_Dec_static_Shutdown(void)
+void BitVector_from_Dec_static_Shutdown(BitVector_from_Dec_static_data *data)
{
- if (from_Dec_term != NULL)
- BitVector_Destroy(from_Dec_term);
- if (from_Dec_base != NULL)
- BitVector_Destroy(from_Dec_base);
- if (from_Dec_prod != NULL)
- BitVector_Destroy(from_Dec_prod);
- if (from_Dec_rank != NULL)
- BitVector_Destroy(from_Dec_rank);
- if (from_Dec_temp != NULL)
- BitVector_Destroy(from_Dec_temp);
+ if (data) {
+ BitVector_Destroy(data->term);
+ BitVector_Destroy(data->base);
+ BitVector_Destroy(data->prod);
+ BitVector_Destroy(data->rank);
+ BitVector_Destroy(data->temp);
+ }
+ yasm_xfree(data);
}
-ErrCode BitVector_from_Dec_static(wordptr addr, charptr string)
+ErrCode BitVector_from_Dec_static(BitVector_from_Dec_static_data *data,
+ wordptr addr, charptr string)
{
ErrCode error = ErrCode_Ok;
N_word bits = bits_(addr);
boolean minus;
boolean shift;
boolean carry;
- wordptr term = from_Dec_term;
- wordptr base = from_Dec_base;
- wordptr prod = from_Dec_prod;
- wordptr rank = from_Dec_rank;
- wordptr temp = from_Dec_temp;
+ wordptr term;
+ wordptr base;
+ wordptr prod;
+ wordptr rank;
+ wordptr temp;
N_word accu;
N_word powr;
N_word count;
if (bits > 0)
{
+ term = data->term;
+ base = data->base;
+ prod = data->prod;
+ rank = data->rank;
+ temp = data->temp;
+
length = strlen((char *) string);
if (length == 0) return(ErrCode_Pars);
digit = (int) *string;
/*@only@*/ charptr BitVector_to_Dec (wordptr addr);
ErrCode BitVector_from_Dec (/*@out@*/ wordptr addr, charptr string);
-ErrCode BitVector_from_Dec_static_Boot(N_word bits);
-void BitVector_from_Dec_static_Shutdown(void);
-ErrCode BitVector_from_Dec_static(/*@out@*/ wordptr addr, charptr string);
+typedef struct BitVector_from_Dec_static_data BitVector_from_Dec_static_data;
+BitVector_from_Dec_static_data *BitVector_from_Dec_static_Boot(N_word bits);
+void BitVector_from_Dec_static_Shutdown(/*@null@*/ BitVector_from_Dec_static_data *data);
+ErrCode BitVector_from_Dec_static(BitVector_from_Dec_static_data *data,
+ /*@out@*/ wordptr addr, charptr string);
/*@only@*/ charptr BitVector_to_Enum (wordptr addr);
ErrCode BitVector_from_Enum (/*@out@*/ wordptr addr, charptr string);
#include "objfmt.h"
#include "dbgfmt.h"
-#include "arch.h"
-
#include "bc-int.h"
#include "expr-int.h"
} data;
};
+/* Standard bytecode types */
+
typedef struct bytecode_data {
yasm_bytecode bc; /* base structure */
unsigned long boundary; /* alignment boundary */
} bytecode_align;
-typedef struct bytecode_objfmt_data {
- yasm_bytecode bc; /* base structure */
+/* Standard bytecode callback function prototypes */
+
+static void bc_data_destroy(yasm_bytecode *bc);
+static void bc_data_print(const yasm_bytecode *bc, FILE *f, int indent_level);
+static yasm_bc_resolve_flags bc_data_resolve
+ (yasm_bytecode *bc, int save, yasm_calc_bc_dist_func calc_bc_dist);
+static int bc_data_tobytes(yasm_bytecode *bc, unsigned char **bufp, void *d,
+ yasm_output_expr_func output_expr,
+ /*@null@*/ yasm_output_reloc_func output_reloc);
+
+static void bc_reserve_destroy(yasm_bytecode *bc);
+static void bc_reserve_print(const yasm_bytecode *bc, FILE *f,
+ int indent_level);
+static yasm_bc_resolve_flags bc_reserve_resolve
+ (yasm_bytecode *bc, int save, yasm_calc_bc_dist_func calc_bc_dist);
+static int bc_reserve_tobytes(yasm_bytecode *bc, unsigned char **bufp, void *d,
+ yasm_output_expr_func output_expr,
+ /*@null@*/ yasm_output_reloc_func output_reloc);
+
+static void bc_incbin_destroy(yasm_bytecode *bc);
+static void bc_incbin_print(const yasm_bytecode *bc, FILE *f,
+ int indent_level);
+static yasm_bc_resolve_flags bc_incbin_resolve
+ (yasm_bytecode *bc, int save, yasm_calc_bc_dist_func calc_bc_dist);
+static int bc_incbin_tobytes(yasm_bytecode *bc, unsigned char **bufp, void *d,
+ yasm_output_expr_func output_expr,
+ /*@null@*/ yasm_output_reloc_func output_reloc);
+
+static void bc_align_destroy(yasm_bytecode *bc);
+static void bc_align_print(const yasm_bytecode *bc, FILE *f, int indent_level);
+static yasm_bc_resolve_flags bc_align_resolve
+ (yasm_bytecode *bc, int save, yasm_calc_bc_dist_func calc_bc_dist);
+static int bc_align_tobytes(yasm_bytecode *bc, unsigned char **bufp, void *d,
+ yasm_output_expr_func output_expr,
+ /*@null@*/ yasm_output_reloc_func output_reloc);
+
+/* Standard bytecode callback structures */
+
+static const yasm_bytecode_callback bc_data_callback = {
+ bc_data_destroy,
+ bc_data_print,
+ bc_data_resolve,
+ bc_data_tobytes
+};
- unsigned int type; /* objfmt-specific type */
- /*@dependent@*/ yasm_objfmt *of; /* objfmt that created the data */
- /*@only@*/ void *data; /* objfmt-specific data */
-} bytecode_objfmt_data;
+static const yasm_bytecode_callback bc_reserve_callback = {
+ bc_reserve_destroy,
+ bc_reserve_print,
+ bc_reserve_resolve,
+ bc_reserve_tobytes
+};
-typedef struct bytecode_dbgfmt_data {
- yasm_bytecode bc; /* base structure */
+static const yasm_bytecode_callback bc_incbin_callback = {
+ bc_incbin_destroy,
+ bc_incbin_print,
+ bc_incbin_resolve,
+ bc_incbin_tobytes
+};
- unsigned int type; /* dbgfmt-specific type */
- /*@dependent@*/ yasm_dbgfmt *df; /* dbgfmt that created the data */
- /*@only@*/ void *data; /* dbgfmt-specific data */
-} bytecode_dbgfmt_data;
+static const yasm_bytecode_callback bc_align_callback = {
+ bc_align_destroy,
+ bc_align_print,
+ bc_align_resolve,
+ bc_align_tobytes
+};
/* Static structures for when NULL is passed to conversion functions. */
/* for Convert*ToBytes() */
unsigned char bytes_static[16];
-/*@dependent@*/ static yasm_arch *cur_arch;
-
-
-void
-yasm_bc_initialize(yasm_arch *a)
-{
- cur_arch = a;
-}
yasm_immval *
-yasm_imm_new_int(unsigned long int_val, unsigned long lindex)
+yasm_imm_create_int(unsigned long int_val, unsigned long line)
{
- return yasm_imm_new_expr(
- yasm_expr_new_ident(yasm_expr_int(yasm_intnum_new_uint(int_val)),
- lindex));
+ return yasm_imm_create_expr(
+ yasm_expr_create_ident(yasm_expr_int(yasm_intnum_create_uint(int_val)),
+ line));
}
yasm_immval *
-yasm_imm_new_expr(yasm_expr *expr_ptr)
+yasm_imm_create_expr(yasm_expr *expr_ptr)
{
yasm_immval *im = yasm_xmalloc(sizeof(yasm_immval));
/*@-nullstate@*/
void
-yasm_ea_delete(yasm_effaddr *ea)
+yasm_ea_destroy(yasm_effaddr *ea)
{
- if (cur_arch->ea_data_delete)
- cur_arch->ea_data_delete(ea);
- yasm_expr_delete(ea->disp);
+ ea->callback->destroy(ea);
+ yasm_expr_destroy(ea->disp);
yasm_xfree(ea);
}
/*@=nullstate@*/
/*@-nullstate@*/
void
-yasm_ea_print(FILE *f, int indent_level, const yasm_effaddr *ea)
+yasm_ea_print(const yasm_effaddr *ea, FILE *f, int indent_level)
{
fprintf(f, "%*sDisp=", indent_level, "");
- yasm_expr_print(f, ea->disp);
+ yasm_expr_print(ea->disp, f);
fprintf(f, "\n%*sLen=%u\n", indent_level, "", (unsigned int)ea->len);
fprintf(f, "%*sNoSplit=%u\n", indent_level, "", (unsigned int)ea->nosplit);
- if (cur_arch->ea_data_print)
- cur_arch->ea_data_print(f, indent_level, ea);
+ ea->callback->print(ea, f, indent_level);
}
/*@=nullstate@*/
yasm_bc_set_multiple(yasm_bytecode *bc, yasm_expr *e)
{
if (bc->multiple)
- bc->multiple = yasm_expr_new_tree(bc->multiple, YASM_EXPR_MUL, e,
- e->line);
+ bc->multiple = yasm_expr_create_tree(bc->multiple, YASM_EXPR_MUL, e,
+ e->line);
else
bc->multiple = e;
}
yasm_bytecode *
-yasm_bc_new_common(yasm_bytecode_type type, size_t size, unsigned long lindex)
+yasm_bc_create_common(const yasm_bytecode_callback *callback, size_t size,
+ unsigned long line)
{
yasm_bytecode *bc = yasm_xmalloc(size);
- bc->type = type;
+ bc->callback = callback;
+
+ bc->section = NULL;
bc->multiple = (yasm_expr *)NULL;
bc->len = 0;
- bc->line = lindex;
+ bc->line = line;
bc->offset = 0;
return bc;
}
-yasm_bytecode *
-yasm_bc_new_data(yasm_datavalhead *datahead, unsigned int size,
- unsigned long lindex)
+static void
+bc_data_destroy(yasm_bytecode *bc)
{
- bytecode_data *data;
-
- data = (bytecode_data *)
- yasm_bc_new_common(YASM_BC__DATA, sizeof(bytecode_data), lindex);
-
- data->datahead = *datahead;
- data->size = (unsigned char)size;
-
- return (yasm_bytecode *)data;
-}
-
-yasm_bytecode *
-yasm_bc_new_reserve(yasm_expr *numitems, unsigned int itemsize,
- unsigned long lindex)
-{
- bytecode_reserve *reserve;
-
- reserve = (bytecode_reserve *)
- yasm_bc_new_common(YASM_BC__RESERVE, sizeof(bytecode_reserve), lindex);
-
- /*@-mustfree@*/
- reserve->numitems = numitems;
- /*@=mustfree@*/
- reserve->itemsize = (unsigned char)itemsize;
-
- return (yasm_bytecode *)reserve;
+ bytecode_data *bc_data = (bytecode_data *)bc;
+ yasm_dvs_destroy(&bc_data->datahead);
}
-yasm_bytecode *
-yasm_bc_new_incbin(char *filename, yasm_expr *start, yasm_expr *maxlen,
- unsigned long lindex)
+static void
+bc_data_print(const yasm_bytecode *bc, FILE *f, int indent_level)
{
- bytecode_incbin *incbin;
-
- incbin = (bytecode_incbin *)
- yasm_bc_new_common(YASM_BC__INCBIN, sizeof(bytecode_incbin), lindex);
-
- /*@-mustfree@*/
- incbin->filename = filename;
- incbin->start = start;
- incbin->maxlen = maxlen;
- /*@=mustfree@*/
-
- return (yasm_bytecode *)incbin;
+ const bytecode_data *bc_data = (const bytecode_data *)bc;
+ fprintf(f, "%*s_Data_\n", indent_level, "");
+ fprintf(f, "%*sFinal Element Size=%u\n", indent_level+1, "",
+ (unsigned int)bc_data->size);
+ fprintf(f, "%*sElements:\n", indent_level+1, "");
+ yasm_dvs_print(&bc_data->datahead, f, indent_level+2);
}
-yasm_bytecode *
-yasm_bc_new_align(unsigned long boundary, unsigned long lindex)
-{
- bytecode_align *align;
-
- align = (bytecode_align *)
- yasm_bc_new_common(YASM_BC__ALIGN, sizeof(bytecode_align), lindex);
-
- align->boundary = boundary;
-
- return (yasm_bytecode *)align;
-}
-
-yasm_bytecode *
-yasm_bc_new_objfmt_data(unsigned int type, unsigned long len, yasm_objfmt *of,
- void *data, unsigned long lindex)
-{
- bytecode_objfmt_data *objfmt_data;
-
- objfmt_data = (bytecode_objfmt_data *)
- yasm_bc_new_common(YASM_BC__OBJFMT_DATA, sizeof(bytecode_objfmt_data),
- lindex);
-
- objfmt_data->type = type;
- objfmt_data->of = of;
- /*@-mustfree@*/
- objfmt_data->data = data;
- /*@=mustfree@*/
-
- /* Yes, this breaks the paradigm just a little. But this data is very
- * unlike other bytecode data--it's internally generated after the
- * other bytecodes have been resolved, and the length is ALWAYS known.
- */
- objfmt_data->bc.len = len;
-
- return (yasm_bytecode *)objfmt_data;
-}
-
-yasm_bytecode *
-yasm_bc_new_dbgfmt_data(unsigned int type, unsigned long len, yasm_dbgfmt *df,
- void *data, unsigned long lindex)
-{
- bytecode_dbgfmt_data *dbgfmt_data;
-
- dbgfmt_data = (bytecode_dbgfmt_data *)
- yasm_bc_new_common(YASM_BC__DBGFMT_DATA, sizeof(bytecode_dbgfmt_data),
- lindex);
-
- dbgfmt_data->type = type;
- dbgfmt_data->df = df;
- /*@-mustfree@*/
- dbgfmt_data->data = data;
- /*@=mustfree@*/
-
- /* Yes, this breaks the paradigm just a little. But this data is very
- * unlike other bytecode data--it's internally generated after the
- * other bytecodes have been resolved, and the length is ALWAYS known.
- */
- dbgfmt_data->bc.len = len;
-
- return (yasm_bytecode *)dbgfmt_data;
-}
-
-void
-yasm_bc_delete(yasm_bytecode *bc)
-{
- bytecode_data *data;
- bytecode_reserve *reserve;
- bytecode_incbin *incbin;
- bytecode_objfmt_data *objfmt_data;
- bytecode_dbgfmt_data *dbgfmt_data;
-
- if (!bc)
- return;
-
- /*@-branchstate@*/
- switch (bc->type) {
- case YASM_BC__EMPTY:
- break;
- case YASM_BC__DATA:
- data = (bytecode_data *)bc;
- yasm_dvs_delete(&data->datahead);
- break;
- case YASM_BC__RESERVE:
- reserve = (bytecode_reserve *)bc;
- yasm_expr_delete(reserve->numitems);
- break;
- case YASM_BC__INCBIN:
- incbin = (bytecode_incbin *)bc;
- yasm_xfree(incbin->filename);
- yasm_expr_delete(incbin->start);
- yasm_expr_delete(incbin->maxlen);
- break;
- case YASM_BC__ALIGN:
- break;
- case YASM_BC__OBJFMT_DATA:
- objfmt_data = (bytecode_objfmt_data *)bc;
- if (objfmt_data->of->bc_objfmt_data_delete)
- objfmt_data->of->bc_objfmt_data_delete(objfmt_data->type,
- objfmt_data->data);
- else
- yasm_internal_error(
- N_("objfmt can't handle its own objfmt data bytecode"));
- break;
- case YASM_BC__DBGFMT_DATA:
- dbgfmt_data = (bytecode_dbgfmt_data *)bc;
- if (dbgfmt_data->df->bc_dbgfmt_data_delete)
- dbgfmt_data->df->bc_dbgfmt_data_delete(dbgfmt_data->type,
- dbgfmt_data->data);
- else
- yasm_internal_error(
- N_("dbgfmt can't handle its own dbgfmt data bytecode"));
- break;
- default:
- if ((unsigned int)bc->type < (unsigned int)cur_arch->bc_type_max)
- cur_arch->bc_delete(bc);
- else
- yasm_internal_error(N_("Unknown bytecode type"));
- break;
- }
- /*@=branchstate@*/
-
- yasm_expr_delete(bc->multiple);
- yasm_xfree(bc);
-}
-
-void
-yasm_bc_print(FILE *f, int indent_level, const yasm_bytecode *bc)
-{
- const bytecode_data *data;
- const bytecode_reserve *reserve;
- const bytecode_incbin *incbin;
- const bytecode_align *align;
- const bytecode_objfmt_data *objfmt_data;
- const bytecode_dbgfmt_data *dbgfmt_data;
-
- switch (bc->type) {
- case YASM_BC__EMPTY:
- fprintf(f, "%*s_Empty_\n", indent_level, "");
- break;
- case YASM_BC__DATA:
- data = (const bytecode_data *)bc;
- fprintf(f, "%*s_Data_\n", indent_level, "");
- fprintf(f, "%*sFinal Element Size=%u\n", indent_level+1, "",
- (unsigned int)data->size);
- fprintf(f, "%*sElements:\n", indent_level+1, "");
- yasm_dvs_print(f, indent_level+2, &data->datahead);
- break;
- case YASM_BC__RESERVE:
- reserve = (const bytecode_reserve *)bc;
- fprintf(f, "%*s_Reserve_\n", indent_level, "");
- fprintf(f, "%*sNum Items=", indent_level, "");
- yasm_expr_print(f, reserve->numitems);
- fprintf(f, "\n%*sItem Size=%u\n", indent_level, "",
- (unsigned int)reserve->itemsize);
- break;
- case YASM_BC__INCBIN:
- incbin = (const bytecode_incbin *)bc;
- fprintf(f, "%*s_IncBin_\n", indent_level, "");
- fprintf(f, "%*sFilename=`%s'\n", indent_level, "",
- incbin->filename);
- fprintf(f, "%*sStart=", indent_level, "");
- if (!incbin->start)
- fprintf(f, "nil (0)");
- else
- yasm_expr_print(f, incbin->start);
- fprintf(f, "%*sMax Len=", indent_level, "");
- if (!incbin->maxlen)
- fprintf(f, "nil (unlimited)");
- else
- yasm_expr_print(f, incbin->maxlen);
- fprintf(f, "\n");
- break;
- case YASM_BC__ALIGN:
- align = (const bytecode_align *)bc;
- fprintf(f, "%*s_Align_\n", indent_level, "");
- fprintf(f, "%*sBoundary=%lu\n", indent_level, "", align->boundary);
- break;
- case YASM_BC__OBJFMT_DATA:
- objfmt_data = (const bytecode_objfmt_data *)bc;
- fprintf(f, "%*s_ObjFmt_Data_\n", indent_level, "");
- if (objfmt_data->of->bc_objfmt_data_print)
- objfmt_data->of->bc_objfmt_data_print(f, indent_level,
- objfmt_data->type,
- objfmt_data->data);
- else
- fprintf(f, "%*sUNKNOWN\n", indent_level, "");
- break;
- case YASM_BC__DBGFMT_DATA:
- dbgfmt_data = (const bytecode_dbgfmt_data *)bc;
- fprintf(f, "%*s_DbgFmt_Data_\n", indent_level, "");
- if (dbgfmt_data->df->bc_dbgfmt_data_print)
- dbgfmt_data->df->bc_dbgfmt_data_print(f, indent_level,
- dbgfmt_data->type,
- dbgfmt_data->data);
- else
- fprintf(f, "%*sUNKNOWN\n", indent_level, "");
- break;
- default:
- if ((unsigned int)bc->type < (unsigned int)cur_arch->bc_type_max)
- cur_arch->bc_print(f, indent_level, bc);
- else
- fprintf(f, "%*s_Unknown_\n", indent_level, "");
- break;
- }
- fprintf(f, "%*sMultiple=", indent_level, "");
- if (!bc->multiple)
- fprintf(f, "nil (1)");
- else
- yasm_expr_print(f, bc->multiple);
- fprintf(f, "\n%*sLength=%lu\n", indent_level, "", bc->len);
- fprintf(f, "%*sLine Index=%lu\n", indent_level, "", bc->line);
- fprintf(f, "%*sOffset=%lx\n", indent_level, "", bc->offset);
-}
-
-/*@null@*/ yasm_intnum *
-yasm_common_calc_bc_dist(yasm_section *sect, /*@null@*/ yasm_bytecode *precbc1,
- /*@null@*/ yasm_bytecode *precbc2)
+static yasm_bc_resolve_flags
+bc_data_resolve(yasm_bytecode *bc, int save,
+ yasm_calc_bc_dist_func calc_bc_dist)
{
- unsigned int dist;
- yasm_intnum *intn;
+ bytecode_data *bc_data = (bytecode_data *)bc;
+ yasm_dataval *dv;
+ size_t slen;
- if (precbc2) {
- dist = precbc2->offset + precbc2->len;
- if (precbc1) {
- if (dist < precbc1->offset + precbc1->len) {
- intn = yasm_intnum_new_uint(precbc1->offset + precbc1->len
- - dist);
- yasm_intnum_calc(intn, YASM_EXPR_NEG, NULL, precbc1->line);
- return intn;
- }
- dist -= precbc1->offset + precbc1->len;
- }
- return yasm_intnum_new_uint(dist);
- } else {
- if (precbc1) {
- intn = yasm_intnum_new_uint(precbc1->offset + precbc1->len);
- yasm_intnum_calc(intn, YASM_EXPR_NEG, NULL, precbc1->line);
- return intn;
- } else {
- return yasm_intnum_new_uint(0);
+ /* Count up element sizes, rounding up string length. */
+ STAILQ_FOREACH(dv, &bc_data->datahead, link) {
+ switch (dv->type) {
+ case DV_EMPTY:
+ break;
+ case DV_EXPR:
+ bc->len += bc_data->size;
+ break;
+ case DV_STRING:
+ slen = strlen(dv->data.str_val);
+ /* find count, rounding up to nearest multiple of size */
+ slen = (slen + bc_data->size - 1) / bc_data->size;
+ bc->len += slen*bc_data->size;
+ break;
}
}
+
+ return YASM_BC_RESOLVE_MIN_LEN;
}
-static yasm_bc_resolve_flags
-bc_resolve_data(bytecode_data *bc_data, unsigned long *len)
+static int
+bc_data_tobytes(yasm_bytecode *bc, unsigned char **bufp, void *d,
+ yasm_output_expr_func output_expr,
+ /*@unused@*/ yasm_output_reloc_func output_reloc)
{
+ bytecode_data *bc_data = (bytecode_data *)bc;
yasm_dataval *dv;
size_t slen;
+ size_t i;
+ unsigned char *bufp_orig = *bufp;
- /* Count up element sizes, rounding up string length. */
STAILQ_FOREACH(dv, &bc_data->datahead, link) {
switch (dv->type) {
case DV_EMPTY:
break;
case DV_EXPR:
- *len += bc_data->size;
+ if (output_expr(&dv->data.expn, *bufp, bc_data->size,
+ (size_t)(bc_data->size*8), 0,
+ (unsigned long)(*bufp-bufp_orig), bc, 0, 1, d))
+ return 1;
+ *bufp += bc_data->size;
break;
case DV_STRING:
slen = strlen(dv->data.str_val);
- /* find count, rounding up to nearest multiple of size */
- slen = (slen + bc_data->size - 1) / bc_data->size;
- *len += slen*bc_data->size;
+ strncpy((char *)*bufp, dv->data.str_val, slen);
+ *bufp += slen;
+ /* pad with 0's to nearest multiple of size */
+ slen %= bc_data->size;
+ if (slen > 0) {
+ slen = bc_data->size-slen;
+ for (i=0; i<slen; i++)
+ YASM_WRITE_8(*bufp, 0);
+ }
break;
}
}
- return YASM_BC_RESOLVE_MIN_LEN;
+ return 0;
+}
+
+yasm_bytecode *
+yasm_bc_create_data(yasm_datavalhead *datahead, unsigned int size,
+ unsigned long line)
+{
+ bytecode_data *data;
+
+ data = (bytecode_data *)
+ yasm_bc_create_common(&bc_data_callback, sizeof(bytecode_data), line);
+
+ data->datahead = *datahead;
+ data->size = (unsigned char)size;
+
+ return (yasm_bytecode *)data;
+}
+
+static void
+bc_reserve_destroy(yasm_bytecode *bc)
+{
+ bytecode_reserve *reserve = (bytecode_reserve *)bc;
+ yasm_expr_destroy(reserve->numitems);
+}
+
+static void
+bc_reserve_print(const yasm_bytecode *bc, FILE *f, int indent_level)
+{
+ const bytecode_reserve *reserve = (const bytecode_reserve *)bc;
+ fprintf(f, "%*s_Reserve_\n", indent_level, "");
+ fprintf(f, "%*sNum Items=", indent_level, "");
+ yasm_expr_print(reserve->numitems, f);
+ fprintf(f, "\n%*sItem Size=%u\n", indent_level, "",
+ (unsigned int)reserve->itemsize);
}
static yasm_bc_resolve_flags
-bc_resolve_reserve(bytecode_reserve *reserve, unsigned long *len,
- int save, unsigned long line, const yasm_section *sect,
+bc_reserve_resolve(yasm_bytecode *bc, int save,
yasm_calc_bc_dist_func calc_bc_dist)
{
+ bytecode_reserve *reserve = (bytecode_reserve *)bc;
yasm_bc_resolve_flags retval = YASM_BC_RESOLVE_MIN_LEN;
/*@null@*/ yasm_expr *temp;
yasm_expr **tempp;
* the circular reference error to filter through.
*/
if (temp && yasm_expr__contains(temp, YASM_EXPR_FLOAT))
- yasm__error(line,
+ yasm__error(bc->line,
N_("expression must not contain floating point value"));
else
- yasm__error(line,
+ yasm__error(bc->line,
N_("attempt to reserve non-constant quantity of space"));
retval = YASM_BC_RESOLVE_ERROR | YASM_BC_RESOLVE_UNKNOWN_LEN;
} else
- *len += yasm_intnum_get_uint(num)*reserve->itemsize;
- yasm_expr_delete(temp);
+ bc->len += yasm_intnum_get_uint(num)*reserve->itemsize;
+ yasm_expr_destroy(temp);
return retval;
}
+static int
+bc_reserve_tobytes(yasm_bytecode *bc, unsigned char **bufp, void *d,
+ yasm_output_expr_func output_expr,
+ /*@unused@*/ yasm_output_reloc_func output_reloc)
+{
+ yasm_internal_error(N_("bc_reserve_tobytes called"));
+ /*@notreached@*/
+ return 1;
+}
+
+yasm_bytecode *
+yasm_bc_create_reserve(yasm_expr *numitems, unsigned int itemsize,
+ unsigned long line)
+{
+ bytecode_reserve *reserve;
+
+ reserve = (bytecode_reserve *)
+ yasm_bc_create_common(&bc_reserve_callback, sizeof(bytecode_reserve),
+ line);
+
+ /*@-mustfree@*/
+ reserve->numitems = numitems;
+ /*@=mustfree@*/
+ reserve->itemsize = (unsigned char)itemsize;
+
+ return (yasm_bytecode *)reserve;
+}
+
+static void
+bc_incbin_destroy(yasm_bytecode *bc)
+{
+ bytecode_incbin *incbin = (bytecode_incbin *)bc;
+ yasm_xfree(incbin->filename);
+ yasm_expr_destroy(incbin->start);
+ yasm_expr_destroy(incbin->maxlen);
+}
+
+static void
+bc_incbin_print(const yasm_bytecode *bc, FILE *f, int indent_level)
+{
+ const bytecode_incbin *incbin = (const bytecode_incbin *)bc;
+ fprintf(f, "%*s_IncBin_\n", indent_level, "");
+ fprintf(f, "%*sFilename=`%s'\n", indent_level, "",
+ incbin->filename);
+ fprintf(f, "%*sStart=", indent_level, "");
+ if (!incbin->start)
+ fprintf(f, "nil (0)");
+ else
+ yasm_expr_print(incbin->start, f);
+ fprintf(f, "%*sMax Len=", indent_level, "");
+ if (!incbin->maxlen)
+ fprintf(f, "nil (unlimited)");
+ else
+ yasm_expr_print(incbin->maxlen, f);
+ fprintf(f, "\n");
+}
+
static yasm_bc_resolve_flags
-bc_resolve_incbin(bytecode_incbin *incbin, unsigned long *len, int save,
- unsigned long line, const yasm_section *sect,
+bc_incbin_resolve(yasm_bytecode *bc, int save,
yasm_calc_bc_dist_func calc_bc_dist)
{
+ bytecode_incbin *incbin = (bytecode_incbin *)bc;
FILE *f;
/*@null@*/ yasm_expr *temp;
yasm_expr **tempp;
num = yasm_expr_get_intnum(tempp, calc_bc_dist);
if (num)
start = yasm_intnum_get_uint(num);
- yasm_expr_delete(temp);
+ yasm_expr_destroy(temp);
if (!num)
return YASM_BC_RESOLVE_UNKNOWN_LEN;
}
num = yasm_expr_get_intnum(tempp, calc_bc_dist);
if (num)
maxlen = yasm_intnum_get_uint(num);
- yasm_expr_delete(temp);
+ yasm_expr_destroy(temp);
if (!num)
return YASM_BC_RESOLVE_UNKNOWN_LEN;
}
/* Open file and determine its length */
f = fopen(incbin->filename, "rb");
if (!f) {
- yasm__error(line, N_("`incbin': unable to open file `%s'"),
+ yasm__error(bc->line, N_("`incbin': unable to open file `%s'"),
incbin->filename);
return YASM_BC_RESOLVE_ERROR | YASM_BC_RESOLVE_UNKNOWN_LEN;
}
if (fseek(f, 0L, SEEK_END) < 0) {
- yasm__error(line, N_("`incbin': unable to seek on file `%s'"),
+ yasm__error(bc->line, N_("`incbin': unable to seek on file `%s'"),
incbin->filename);
return YASM_BC_RESOLVE_ERROR | YASM_BC_RESOLVE_UNKNOWN_LEN;
}
/* Compute length of incbin from start, maxlen, and len */
if (start > flen) {
- yasm__warning(YASM_WARN_GENERAL, line,
+ yasm__warning(YASM_WARN_GENERAL, bc->line,
N_("`incbin': start past end of file `%s'"),
incbin->filename);
start = flen;
if (incbin->maxlen)
if (maxlen < flen)
flen = maxlen;
- *len += flen;
+ bc->len += flen;
return YASM_BC_RESOLVE_MIN_LEN;
}
+static int
+bc_incbin_tobytes(yasm_bytecode *bc, unsigned char **bufp, void *d,
+ yasm_output_expr_func output_expr,
+ /*@unused@*/ yasm_output_reloc_func output_reloc)
+{
+ bytecode_incbin *incbin = (bytecode_incbin *)bc;
+ FILE *f;
+ /*@dependent@*/ /*@null@*/ const yasm_intnum *num;
+ unsigned long start = 0;
+
+ /* Convert start to integer value */
+ if (incbin->start) {
+ num = yasm_expr_get_intnum(&incbin->start, NULL);
+ if (!num)
+ yasm_internal_error(
+ N_("could not determine start in bc_tobytes_incbin"));
+ start = yasm_intnum_get_uint(num);
+ }
+
+ /* Open file */
+ f = fopen(incbin->filename, "rb");
+ if (!f) {
+ yasm__error(bc->line, N_("`incbin': unable to open file `%s'"),
+ incbin->filename);
+ return 1;
+ }
+
+ /* Seek to start of data */
+ if (fseek(f, (long)start, SEEK_SET) < 0) {
+ yasm__error(bc->line, N_("`incbin': unable to seek on file `%s'"),
+ incbin->filename);
+ fclose(f);
+ return 1;
+ }
+
+ /* Read len bytes */
+ if (fread(*bufp, (size_t)bc->len, 1, f) < (size_t)bc->len) {
+ yasm__error(bc->line,
+ N_("`incbin': unable to read %lu bytes from file `%s'"),
+ bc->len, incbin->filename);
+ fclose(f);
+ return 1;
+ }
+
+ *bufp += bc->len;
+ fclose(f);
+ return 0;
+}
+
+yasm_bytecode *
+yasm_bc_create_incbin(char *filename, yasm_expr *start, yasm_expr *maxlen,
+ unsigned long line)
+{
+ bytecode_incbin *incbin;
+
+ incbin = (bytecode_incbin *)
+ yasm_bc_create_common(&bc_incbin_callback, sizeof(bytecode_incbin),
+ line);
+
+ /*@-mustfree@*/
+ incbin->filename = filename;
+ incbin->start = start;
+ incbin->maxlen = maxlen;
+ /*@=mustfree@*/
+
+ return (yasm_bytecode *)incbin;
+}
+
+static void
+bc_align_destroy(yasm_bytecode *bc)
+{
+}
+
+static void
+bc_align_print(const yasm_bytecode *bc, FILE *f, int indent_level)
+{
+ const bytecode_align *align = (const bytecode_align *)bc;
+ fprintf(f, "%*s_Align_\n", indent_level, "");
+ fprintf(f, "%*sBoundary=%lu\n", indent_level, "", align->boundary);
+}
+
+static yasm_bc_resolve_flags
+bc_align_resolve(yasm_bytecode *bc, int save,
+ yasm_calc_bc_dist_func calc_bc_dist)
+{
+ yasm_internal_error(N_("TODO: align bytecode not implemented!"));
+ /*@notreached@*/
+ return YASM_BC_RESOLVE_ERROR;
+}
+
+static int
+bc_align_tobytes(yasm_bytecode *bc, unsigned char **bufp, void *d,
+ yasm_output_expr_func output_expr,
+ /*@unused@*/ yasm_output_reloc_func output_reloc)
+{
+ yasm_internal_error(N_("TODO: align bytecode not implemented!"));
+ /*@notreached@*/
+ return 1;
+}
+
+yasm_bytecode *
+yasm_bc_create_align(unsigned long boundary, unsigned long line)
+{
+ bytecode_align *align;
+
+ align = (bytecode_align *)
+ yasm_bc_create_common(&bc_align_callback, sizeof(bytecode_align),
+ line);
+
+ align->boundary = boundary;
+
+ return (yasm_bytecode *)align;
+}
+
+yasm_section *
+yasm_bc_get_section(yasm_bytecode *bc)
+{
+ return bc->section;
+}
+
+void
+yasm_bc_destroy(yasm_bytecode *bc)
+{
+ if (!bc)
+ return;
+
+ if (bc->callback)
+ bc->callback->destroy(bc);
+ yasm_expr_destroy(bc->multiple);
+ yasm_xfree(bc);
+}
+
+void
+yasm_bc_print(const yasm_bytecode *bc, FILE *f, int indent_level)
+{
+ if (!bc->callback)
+ fprintf(f, "%*s_Empty_\n", indent_level, "");
+ else
+ bc->callback->print(bc, f, indent_level);
+ fprintf(f, "%*sMultiple=", indent_level, "");
+ if (!bc->multiple)
+ fprintf(f, "nil (1)");
+ else
+ yasm_expr_print(bc->multiple, f);
+ fprintf(f, "\n%*sLength=%lu\n", indent_level, "", bc->len);
+ fprintf(f, "%*sLine Index=%lu\n", indent_level, "", bc->line);
+ fprintf(f, "%*sOffset=%lx\n", indent_level, "", bc->offset);
+}
+
+/*@null@*/ yasm_intnum *
+yasm_common_calc_bc_dist(/*@null@*/ yasm_bytecode *precbc1,
+ /*@null@*/ yasm_bytecode *precbc2)
+{
+ unsigned int dist;
+ yasm_intnum *intn;
+
+ if (precbc2) {
+ dist = precbc2->offset + precbc2->len;
+ if (precbc1) {
+ if (dist < precbc1->offset + precbc1->len) {
+ intn = yasm_intnum_create_uint(precbc1->offset + precbc1->len
+ - dist);
+ yasm_intnum_calc(intn, YASM_EXPR_NEG, NULL, precbc1->line);
+ return intn;
+ }
+ dist -= precbc1->offset + precbc1->len;
+ }
+ return yasm_intnum_create_uint(dist);
+ } else {
+ if (precbc1) {
+ intn = yasm_intnum_create_uint(precbc1->offset + precbc1->len);
+ yasm_intnum_calc(intn, YASM_EXPR_NEG, NULL, precbc1->line);
+ return intn;
+ } else {
+ return yasm_intnum_create_uint(0);
+ }
+ }
+}
+
yasm_bc_resolve_flags
-yasm_bc_resolve(yasm_bytecode *bc, int save, const yasm_section *sect,
+yasm_bc_resolve(yasm_bytecode *bc, int save,
yasm_calc_bc_dist_func calc_bc_dist)
{
yasm_bc_resolve_flags retval = YASM_BC_RESOLVE_MIN_LEN;
bc->len = 0; /* start at 0 */
- switch (bc->type) {
- case YASM_BC__EMPTY:
- yasm_internal_error(N_("got empty bytecode in bc_calc_len"));
- /*break;*/
- case YASM_BC__DATA:
- retval = bc_resolve_data((bytecode_data *)bc, &bc->len);
- break;
- case YASM_BC__RESERVE:
- retval = bc_resolve_reserve((bytecode_reserve *)bc, &bc->len,
- save, bc->line, sect, calc_bc_dist);
- break;
- case YASM_BC__INCBIN:
- retval = bc_resolve_incbin((bytecode_incbin *)bc, &bc->len,
- save, bc->line, sect, calc_bc_dist);
- break;
- case YASM_BC__ALIGN:
- /* TODO */
- yasm_internal_error(N_("TODO: align bytecode not implemented!"));
- /*break;*/
- case YASM_BC__OBJFMT_DATA:
- yasm_internal_error(N_("resolving objfmt data bytecode?"));
- /*break;*/
- default:
- if ((unsigned int)bc->type < (unsigned int)cur_arch->bc_type_max)
- retval = cur_arch->bc_resolve(bc, save, sect, calc_bc_dist);
- else
- yasm_internal_error(N_("Unknown bytecode type"));
- }
+ if (!bc->callback)
+ yasm_internal_error(N_("got empty bytecode in bc_resolve"));
+ else
+ retval = bc->callback->resolve(bc, save, calc_bc_dist);
/* Multiply len by number of multiples */
if (bc->multiple) {
}
} else
bc->len *= yasm_intnum_get_uint(num);
- yasm_expr_delete(temp);
+ yasm_expr_destroy(temp);
}
/* If we got an error somewhere along the line, clear out any calc len */
return retval;
}
-static int
-bc_tobytes_data(bytecode_data *bc_data, unsigned char **bufp,
- const yasm_section *sect, yasm_bytecode *bc, void *d,
- yasm_output_expr_func output_expr)
- /*@sets **bufp@*/
-{
- yasm_dataval *dv;
- size_t slen;
- size_t i;
- unsigned char *bufp_orig = *bufp;
-
- STAILQ_FOREACH(dv, &bc_data->datahead, link) {
- switch (dv->type) {
- case DV_EMPTY:
- break;
- case DV_EXPR:
- if (output_expr(&dv->data.expn, *bufp, bc_data->size,
- (size_t)(bc_data->size*8), 0,
- (unsigned long)(*bufp-bufp_orig), sect, bc, 0,
- 1, d))
- return 1;
- *bufp += bc_data->size;
- break;
- case DV_STRING:
- slen = strlen(dv->data.str_val);
- strncpy((char *)*bufp, dv->data.str_val, slen);
- *bufp += slen;
- /* pad with 0's to nearest multiple of size */
- slen %= bc_data->size;
- if (slen > 0) {
- slen = bc_data->size-slen;
- for (i=0; i<slen; i++)
- YASM_WRITE_8(*bufp, 0);
- }
- break;
- }
- }
-
- return 0;
-}
-
-static int
-bc_tobytes_incbin(bytecode_incbin *incbin, unsigned char **bufp,
- unsigned long len, unsigned long line)
- /*@sets **bufp@*/
-{
- FILE *f;
- /*@dependent@*/ /*@null@*/ const yasm_intnum *num;
- unsigned long start = 0;
-
- /* Convert start to integer value */
- if (incbin->start) {
- num = yasm_expr_get_intnum(&incbin->start, NULL);
- if (!num)
- yasm_internal_error(
- N_("could not determine start in bc_tobytes_incbin"));
- start = yasm_intnum_get_uint(num);
- }
-
- /* Open file */
- f = fopen(incbin->filename, "rb");
- if (!f) {
- yasm__error(line, N_("`incbin': unable to open file `%s'"),
- incbin->filename);
- return 1;
- }
-
- /* Seek to start of data */
- if (fseek(f, (long)start, SEEK_SET) < 0) {
- yasm__error(line, N_("`incbin': unable to seek on file `%s'"),
- incbin->filename);
- fclose(f);
- return 1;
- }
-
- /* Read len bytes */
- if (fread(*bufp, (size_t)len, 1, f) < (size_t)len) {
- yasm__error(line,
- N_("`incbin': unable to read %lu bytes from file `%s'"),
- len, incbin->filename);
- fclose(f);
- return 1;
- }
-
- *bufp += len;
- fclose(f);
- return 0;
-}
-
/*@null@*/ /*@only@*/ unsigned char *
yasm_bc_tobytes(yasm_bytecode *bc, unsigned char *buf, unsigned long *bufsize,
/*@out@*/ unsigned long *multiple, /*@out@*/ int *gap,
- const yasm_section *sect, void *d,
- yasm_output_expr_func output_expr,
- /*@null@*/ yasm_output_reloc_func output_reloc,
- /*@null@*/ yasm_output_bc_objfmt_data_func
- output_bc_objfmt_data)
+ void *d, yasm_output_expr_func output_expr,
+ /*@null@*/ yasm_output_reloc_func output_reloc)
/*@sets *buf@*/
{
/*@only@*/ /*@null@*/ unsigned char *mybuf = NULL;
unsigned char *origbuf, *destbuf;
/*@dependent@*/ /*@null@*/ const yasm_intnum *num;
- bytecode_objfmt_data *objfmt_data;
- bytecode_dbgfmt_data *dbgfmt_data;
unsigned long datasize;
int error = 0;
datasize = bc->len / (*multiple);
*bufsize = datasize;
- if (bc->type == YASM_BC__RESERVE) {
+ /* special case for reserve bytecodes */
+ if (bc->callback == &bc_reserve_callback) {
*gap = 1;
return NULL; /* we didn't allocate a buffer */
}
destbuf = buf;
}
- switch (bc->type) {
- case YASM_BC__EMPTY:
- yasm_internal_error(N_("got empty bytecode in bc_tobytes"));
- /*break;*/
- case YASM_BC__DATA:
- error = bc_tobytes_data((bytecode_data *)bc, &destbuf, sect, bc, d,
- output_expr);
- break;
- case YASM_BC__INCBIN:
- error = bc_tobytes_incbin((bytecode_incbin *)bc, &destbuf, bc->len,
- bc->line);
- break;
- case YASM_BC__ALIGN:
- /* TODO */
- yasm_internal_error(N_("TODO: align bytecode not implemented!"));
- /*break;*/
- case YASM_BC__OBJFMT_DATA:
- objfmt_data = (bytecode_objfmt_data *)bc;
- if (output_bc_objfmt_data)
- error = output_bc_objfmt_data(objfmt_data->type,
- objfmt_data->data, &destbuf);
- else
- yasm_internal_error(
- N_("Have objfmt data bytecode but no way to output it"));
- break;
- case YASM_BC__DBGFMT_DATA:
- dbgfmt_data = (bytecode_dbgfmt_data *)bc;
- if (dbgfmt_data->df->bc_dbgfmt_data_output)
- error = dbgfmt_data->df->bc_dbgfmt_data_output(bc,
- dbgfmt_data->type, dbgfmt_data->data, &destbuf,
- sect, output_reloc, d);
- else
- yasm_internal_error(
- N_("Have dbgfmt data bytecode but no way to output it"));
- break;
- default:
- if ((unsigned int)bc->type < (unsigned int)cur_arch->bc_type_max)
- error = cur_arch->bc_tobytes(bc, &destbuf, sect, d,
- output_expr);
- else
- yasm_internal_error(N_("Unknown bytecode type"));
- }
+ if (!bc->callback)
+ yasm_internal_error(N_("got empty bytecode in bc_tobytes"));
+ else
+ error = bc->callback->tobytes(bc, &destbuf, d, output_expr,
+ output_reloc);
if (!error && ((unsigned long)(destbuf - origbuf) != datasize))
yasm_internal_error(
return mybuf;
}
-yasm_bytecode *
-yasm_bcs_last(yasm_bytecodehead *headp)
-{
- return STAILQ_LAST(headp, yasm_bytecode, link);
-}
-
-void
-yasm_bcs_delete(yasm_bytecodehead *headp)
-{
- yasm_bytecode *cur, *next;
-
- cur = STAILQ_FIRST(headp);
- while (cur) {
- next = STAILQ_NEXT(cur, link);
- yasm_bc_delete(cur);
- cur = next;
- }
- STAILQ_INIT(headp);
- yasm_xfree(headp);
-}
-
-yasm_bytecode *
-yasm_bcs_append(yasm_bytecodehead *headp, yasm_bytecode *bc)
-{
- if (bc) {
- if (bc->type != YASM_BC__EMPTY) {
- STAILQ_INSERT_TAIL(headp, bc, link);
- return bc;
- } else {
- yasm_xfree(bc);
- }
- }
- return (yasm_bytecode *)NULL;
-}
-
-void
-yasm_bcs_print(FILE *f, int indent_level, const yasm_bytecodehead *headp)
-{
- yasm_bytecode *cur;
-
- STAILQ_FOREACH(cur, headp, link) {
- fprintf(f, "%*sNext Bytecode:\n", indent_level, "");
- yasm_bc_print(f, indent_level+1, cur);
- }
-}
-
-int
-yasm_bcs_traverse(yasm_bytecodehead *headp, void *d,
- int (*func) (yasm_bytecode *bc, /*@null@*/ void *d))
-{
- yasm_bytecode *cur;
-
- STAILQ_FOREACH(cur, headp, link) {
- int retval = func(cur, d);
- if (retval != 0)
- return retval;
- }
- return 0;
-}
-
yasm_dataval *
-yasm_dv_new_expr(yasm_expr *expn)
+yasm_dv_create_expr(yasm_expr *expn)
{
yasm_dataval *retval = yasm_xmalloc(sizeof(yasm_dataval));
}
yasm_dataval *
-yasm_dv_new_string(char *str_val)
+yasm_dv_create_string(char *str_val)
{
yasm_dataval *retval = yasm_xmalloc(sizeof(yasm_dataval));
}
void
-yasm_dvs_delete(yasm_datavalhead *headp)
+yasm_dvs_destroy(yasm_datavalhead *headp)
{
yasm_dataval *cur, *next;
next = STAILQ_NEXT(cur, link);
switch (cur->type) {
case DV_EXPR:
- yasm_expr_delete(cur->data.expn);
+ yasm_expr_destroy(cur->data.expn);
break;
case DV_STRING:
yasm_xfree(cur->data.str_val);
}
void
-yasm_dvs_print(FILE *f, int indent_level, const yasm_datavalhead *head)
+yasm_dvs_print(const yasm_datavalhead *head, FILE *f, int indent_level)
{
yasm_dataval *cur;
break;
case DV_EXPR:
fprintf(f, "%*sExpr=", indent_level, "");
- yasm_expr_print(f, cur->data.expn);
+ yasm_expr_print(cur->data.expn, f);
fprintf(f, "\n");
break;
case DV_STRING:
}
}
-yasm_bytecodehead *
-yasm_bcs_new(void)
-{
- yasm_bytecodehead *headp;
- headp = yasm_xmalloc(sizeof(yasm_bytecodehead));
- STAILQ_INIT(headp);
- return headp;
-}
-
-/* Non-macro yasm_bcs_first() for non-YASM_LIB_INTERNAL users. */
-#undef yasm_bcs_first
-yasm_bytecode *
-yasm_bcs_first(yasm_bytecodehead *headp)
-{
- return STAILQ_FIRST(headp);
-}
-
/* Non-macro yasm_dvs_initialize() for non-YASM_LIB_INTERNAL users. */
#undef yasm_dvs_initialize
void
typedef struct yasm_datavalhead yasm_datavalhead;
#ifdef YASM_LIB_INTERNAL
-/*@reldef@*/ STAILQ_HEAD(yasm_bytecodehead, yasm_bytecode);
/*@reldef@*/ STAILQ_HEAD(yasm_datavalhead, yasm_dataval);
-
-/** Built-in bytecode types. Additional types may be #yasm_arch defined
- * starting at #YASM_BYTECODE_TYPE_BASE.
- * \internal
- */
-typedef enum {
- YASM_BC__EMPTY = 0, /**< Empty; should not exist except temporarily. */
- YASM_BC__DATA, /**< One or more data value(s). */
- YASM_BC__RESERVE, /**< Reserved space. */
- YASM_BC__INCBIN, /**< Included binary file. */
- YASM_BC__ALIGN, /**< Alignment to a boundary. */
- YASM_BC__DBGFMT_DATA, /**< yasm_dbgfmt specific data. */
- YASM_BC__OBJFMT_DATA /**< yasm_objfmt specific data. */
-} yasm_bytecode_type;
-
-/** Starting yasm_bytecode_type numeric value available for yasm_arch use. */
-#define YASM_BYTECODE_TYPE_BASE YASM_BC__OBJFMT_DATA+1
#endif
-/** Initialize bytecode utility functions.
- * \param a architecture used during bytecode operations.
- */
-void yasm_bc_initialize(yasm_arch *a);
+/** Return value flags for yasm_bc_resolve(). */
+typedef enum {
+ YASM_BC_RESOLVE_NONE = 0, /**< Ok, but length is not minimum. */
+ YASM_BC_RESOLVE_ERROR = 1<<0, /**< Error found, output. */
+ YASM_BC_RESOLVE_MIN_LEN = 1<<1, /**< Length is minimum possible. */
+ YASM_BC_RESOLVE_UNKNOWN_LEN = 1<<2 /**< Length indeterminate. */
+} yasm_bc_resolve_flags;
/** Create an immediate value from an unsigned integer.
* \param int_val unsigned integer
- * \param lindex line index (as from yasm_linemgr) for error/warning
- * purposes.
+ * \param line virtual line (from yasm_linemap)
* \return Newly allocated immediate value.
*/
-/*@only@*/ yasm_immval *yasm_imm_new_int(unsigned long int_val,
- unsigned long lindex);
+/*@only@*/ yasm_immval *yasm_imm_create_int(unsigned long int_val,
+ unsigned long line);
/** Create an immediate value from an expression.
* \param e expression (kept, do not free).
* \return Newly allocated immediate value.
*/
-/*@only@*/ yasm_immval *yasm_imm_new_expr(/*@keep@*/ yasm_expr *e);
+/*@only@*/ yasm_immval *yasm_imm_create_expr(/*@keep@*/ yasm_expr *e);
/** Get the displacement portion of an effective address.
* \param ea effective address
/** Delete (free allocated memory for) an effective address.
* \param ea effective address (only pointer to it).
*/
-void yasm_ea_delete(/*@only@*/ yasm_effaddr *ea);
+void yasm_ea_destroy(/*@only@*/ yasm_effaddr *ea);
/** Print an effective address. For debugging purposes.
* \param f file
* \param indent_level indentation level
* \param ea effective address
*/
-void yasm_ea_print(FILE *f, int indent_level, const yasm_effaddr *ea);
+void yasm_ea_print(const yasm_effaddr *ea, FILE *f, int indent_level);
/** Set multiple field of a bytecode.
* A bytecode can be repeated a number of times when output. This function
*/
void yasm_bc_set_multiple(yasm_bytecode *bc, /*@keep@*/ yasm_expr *e);
-#ifdef YASM_LIB_INTERNAL
-/** Create a bytecode of any specified type.
- * \param type bytecode type
- * \param datasize size of type-specific data (in bytes)
- * \param lindex line index (as from yasm_linemgr) for the bytecode
- * \return Newly allocated bytecode of the specified type.
- */
-/*@only@*/ yasm_bytecode *yasm_bc_new_common(yasm_bytecode_type type,
- size_t datasize,
- unsigned long lindex);
-#endif
-
/** Create a bytecode containing data value(s).
* \param datahead list of data values (kept, do not free)
* \param size storage size (in bytes) for each data value
- * \param lindex line index (as from yasm_linemgr) for the bytecode
+ * \param line virtual line (from yasm_linemap)
* \return Newly allocated bytecode.
*/
-/*@only@*/ yasm_bytecode *yasm_bc_new_data(yasm_datavalhead *datahead,
- unsigned int size,
- unsigned long lindex);
+/*@only@*/ yasm_bytecode *yasm_bc_create_data
+ (yasm_datavalhead *datahead, unsigned int size, unsigned long line);
/** Create a bytecode reserving space.
* \param numitems number of reserve "items" (kept, do not free)
* \param itemsize reserved size (in bytes) for each item
- * \param lindex line index (as from yasm_linemgr) for the bytecode
+ * \param line virtual line (from yasm_linemap)
* \return Newly allocated bytecode.
*/
-/*@only@*/ yasm_bytecode *yasm_bc_new_reserve(/*@only@*/ yasm_expr *numitems,
- unsigned int itemsize,
- unsigned long lindex);
+/*@only@*/ yasm_bytecode *yasm_bc_create_reserve
+ (/*@only@*/ yasm_expr *numitems, unsigned int itemsize,
+ unsigned long line);
/** Create a bytecode that includes a binary file verbatim.
* \param filename full path to binary file (kept, do not free)
* (kept, do not free); may be NULL to indicate 0
* \param maxlen maximum number of bytes to read from the file (kept, do
* do not free); may be NULL to indicate no maximum
- * \param lindex line index (as from yasm_linemgr) for the bytecode
+ * \param line virtual line (from yasm_linemap) for the bytecode
* \return Newly allocated bytecode.
*/
-/*@only@*/ yasm_bytecode *yasm_bc_new_incbin
+/*@only@*/ yasm_bytecode *yasm_bc_create_incbin
(/*@only@*/ char *filename, /*@only@*/ /*@null@*/ yasm_expr *start,
- /*@only@*/ /*@null@*/ yasm_expr *maxlen, unsigned long lindex);
+ /*@only@*/ /*@null@*/ yasm_expr *maxlen, unsigned long line);
/** Create a bytecode that aligns the following bytecode to a boundary.
* \param boundary byte alignment (must be a power of two)
- * \param lindex line index (as from yasm_linemgr) for the bytecode
- * \return Newly allocated bytecode.
- */
-/*@only@*/ yasm_bytecode *yasm_bc_new_align(unsigned long boundary,
- unsigned long lindex);
-
-/** Create a bytecode that includes yasm_objfmt-specific data.
- * \param type yasm_objfmt-specific type
- * \param len length (in bytes) of data
- * \param of yasm_objfmt storing the data
- * \param data data (kept, do not free)
- * \param lindex line index (as from yasm_linemgr) for the bytecode
+ * \param line virtual line (from yasm_linemap)
* \return Newly allocated bytecode.
*/
-/*@only@*/ yasm_bytecode *yasm_bc_new_objfmt_data
- (unsigned int type, unsigned long len, yasm_objfmt *of,
- /*@only@*/ void *data, unsigned long lindex);
+/*@only@*/ yasm_bytecode *yasm_bc_create_align
+ (unsigned long boundary, unsigned long line);
-/** Create a bytecode that includes yasm_dbgfmt-specific data.
- * \param type yasm_dbgfmt-specific type
- * \param len length (in bytes) of data
- * \param df yasm_dbgfmt storing the data
- * \param data data (kept, do not free)
- * \param lindex line index (as from yasm_linemgr) for the bytecode
- * \return Newly allocated bytecode.
+/** Get the section that contains a particular bytecode.
+ * \param bc bytecode
+ * \return Section containing bc (can be NULL if bytecode is not part of a
+ * section).
*/
-/*@only@*/ yasm_bytecode *yasm_bc_new_dbgfmt_data
- (unsigned int type, unsigned long len, yasm_dbgfmt *df,
- /*@only@*/ void *data, unsigned long lindex);
-
+/*@dependent@*/ /*@null@*/ yasm_section *yasm_bc_get_section
+ (yasm_bytecode *bc);
+
/** Delete (free allocated memory for) a bytecode.
* \param bc bytecode (only pointer to it); may be NULL
*/
-void yasm_bc_delete(/*@only@*/ /*@null@*/ yasm_bytecode *bc);
+void yasm_bc_destroy(/*@only@*/ /*@null@*/ yasm_bytecode *bc);
/** Print a bytecode. For debugging purposes.
* \param f file
* \param indent_level indentation level
* \param bc bytecode
*/
-void yasm_bc_print(FILE *f, int indent_level, const yasm_bytecode *bc);
+void yasm_bc_print(const yasm_bytecode *bc, FILE *f, int indent_level);
/** Common version of calc_bc_dist that takes offsets from bytecodes.
* Should be used for the final stages of optimizers as well as in yasm_objfmt
* \see yasm_calc_bc_dist_func for parameter descriptions.
*/
/*@null@*/ yasm_intnum *yasm_common_calc_bc_dist
- (yasm_section *sect, /*@null@*/ yasm_bytecode *precbc1,
- /*@null@*/ yasm_bytecode *precbc2);
-
-/** Return value flags for yasm_bc_resolve(). */
-typedef enum {
- YASM_BC_RESOLVE_NONE = 0, /**< Ok, but length is not minimum. */
- YASM_BC_RESOLVE_ERROR = 1<<0, /**< Error found, output. */
- YASM_BC_RESOLVE_MIN_LEN = 1<<1, /**< Length is minimum possible. */
- YASM_BC_RESOLVE_UNKNOWN_LEN = 1<<2 /**< Length indeterminate. */
-} yasm_bc_resolve_flags;
+ (/*@null@*/ yasm_bytecode *precbc1, /*@null@*/ yasm_bytecode *precbc2);
/** Resolve labels in a bytecode, and calculate its length.
* Tries to minimize the length as much as possible.
* values returned by calc_bc_dist except temporarily to
* try to minimize the length); when nonzero, all fields
* in bc may be modified by this function
- * \param sect section containing the bytecode
* \param calc_bc_dist function used to determine bytecode distance
* \return Flags indicating whether the length is the minimum possible,
* indeterminate, and if there was an error recognized (and output)
* during execution.
*/
yasm_bc_resolve_flags yasm_bc_resolve(yasm_bytecode *bc, int save,
- const yasm_section *sect,
yasm_calc_bc_dist_func calc_bc_dist);
/** Convert a bytecode into its byte representation.
* \param gap if nonzero, indicates the data does not really need to
* exist in the object file; if nonzero, contents of buf
* are undefined [output]
- * \param sect section containing the bytecode
- * \param d data to pass to each call to output_expr
+ * \param d data to pass to each call to output_expr/output_reloc
* \param output_expr function to call to convert expressions into their byte
* representation
- * \param output_bc_objfmt_data function to call to convert yasm_objfmt data
- * bytecodes into their byte representation
* \param output_reloc function to call to output relocation entries
* for a single sym
* \return Newly allocated buffer that should be used instead of buf for
*/
/*@null@*/ /*@only@*/ unsigned char *yasm_bc_tobytes
(yasm_bytecode *bc, unsigned char *buf, unsigned long *bufsize,
- /*@out@*/ unsigned long *multiple, /*@out@*/ int *gap,
- const yasm_section *sect, void *d, yasm_output_expr_func output_expr,
- /*@null@*/ yasm_output_reloc_func output_reloc,
- /*@null@*/ yasm_output_bc_objfmt_data_func output_bc_objfmt_data)
+ /*@out@*/ unsigned long *multiple, /*@out@*/ int *gap, void *d,
+ yasm_output_expr_func output_expr,
+ /*@null@*/ yasm_output_reloc_func output_reloc)
/*@sets *buf@*/;
-/** Create list of bytecodes.
- * \return Newly allocated bytecode list.
- */
-/*@only@*/ yasm_bytecodehead *yasm_bcs_new(void);
-
-/** Get the first bytecode in a list of bytecodes.
- * \param headp bytecode list
- * \return First bytecode in list (NULL if list is empty).
- */
-/*@null@*/ yasm_bytecode *yasm_bcs_first(yasm_bytecodehead *headp);
-#ifdef YASM_LIB_INTERNAL
-#define yasm_bcs_first(headp) STAILQ_FIRST(headp)
-#endif
-
-/** Get the last bytecode in a list of bytecodes.
- * \param headp bytecode list
- * \return Last bytecode in list (NULL if list is empty).
- */
-/*@null@*/ yasm_bytecode *yasm_bcs_last(yasm_bytecodehead *headp);
-
-/** Delete (free allocated memory for) a list of bytecodes.
- * \param headp bytecode list
- */
-void yasm_bcs_delete(/*@only@*/ yasm_bytecodehead *headp);
-
-/** Add bytecode to the end of a list of bytecodes.
- * \note Does not make a copy of bc; so don't pass this function static or
- * local variables, and discard the bc pointer after calling this
- * function.
- * \param headp bytecode list
- * \param bc bytecode (may be NULL)
- * \return If bytecode was actually appended (it wasn't NULL or empty), the
- * bytecode; otherwise NULL.
- */
-/*@only@*/ /*@null@*/ yasm_bytecode *yasm_bcs_append
- (yasm_bytecodehead *headp,
- /*@returned@*/ /*@only@*/ /*@null@*/ yasm_bytecode *bc);
-
-/** Print a bytecode list. For debugging purposes.
- * \param f file
- * \param indent_level indentation level
- * \param headp bytecode list
- */
-void yasm_bcs_print(FILE *f, int indent_level, const yasm_bytecodehead *headp);
-
-/** Traverses a bytecode list, calling a function on each bytecode.
- * \param headp bytecode list
- * \param d data pointer passed to func on each call
- * \param func function
- * \return Stops early (and returns func's return value) if func returns a
- * nonzero value; otherwise 0.
- */
-int yasm_bcs_traverse(yasm_bytecodehead *headp, /*@null@*/ void *d,
- int (*func) (yasm_bytecode *bc, /*@null@*/ void *d));
-
/** Create a new data value from an expression.
* \param expn expression
* \return Newly allocated data value.
*/
-yasm_dataval *yasm_dv_new_expr(/*@keep@*/ yasm_expr *expn);
+yasm_dataval *yasm_dv_create_expr(/*@keep@*/ yasm_expr *expn);
/** Create a new data value from a float.
* \param flt floating point value
* \return Newly allocated data value.
*/
-yasm_dataval *yasm_dv_new_float(/*@keep@*/ yasm_floatnum *flt);
+yasm_dataval *yasm_dv_create_float(/*@keep@*/ yasm_floatnum *flt);
/** Create a new data value from a string.
* \param str_val string
* \return Newly allocated data value.
*/
-yasm_dataval *yasm_dv_new_string(/*@keep@*/ char *str_val);
+yasm_dataval *yasm_dv_create_string(/*@keep@*/ char *str_val);
/** Initialize a list of data values.
* \param headp list of data values
/** Delete (free allocated memory for) a list of data values.
* \param headp list of data values
*/
-void yasm_dvs_delete(yasm_datavalhead *headp);
+void yasm_dvs_destroy(yasm_datavalhead *headp);
/** Add data value to the end of a list of data values.
* \note Does not make a copy of the data value; so don't pass this function
* \param indent_level indentation level
* \param headp data value list
*/
-void yasm_dvs_print(FILE *f, int indent_level, const yasm_datavalhead *headp);
+void yasm_dvs_print(const yasm_datavalhead *headp, FILE *f, int indent_level);
#endif
#ifndef YASM_CORETYPE_H
#define YASM_CORETYPE_H
-/** Architecture interface. \see arch.h for details. */
+/** Architecture instance (mostly opaque type). \see arch.h for details. */
typedef struct yasm_arch yasm_arch;
/** Preprocessor interface. \see preproc.h for details. */
typedef struct yasm_preproc yasm_preproc;
-/** Parser interface. \see parser.h for details. */
+/** Parser instance (mostly opaque type). \see parser.h for details. */
typedef struct yasm_parser yasm_parser;
/** Optimizer interface. \see optimizer.h for details. */
typedef struct yasm_optimizer yasm_optimizer;
/** Debug format interface. \see dbgfmt.h for details. */
typedef struct yasm_dbgfmt yasm_dbgfmt;
+/** YASM associated data callback structure. Many data structures can have
+ * arbitrary data associated with them.
+ */
+typedef struct yasm_assoc_data_callback {
+ void (*destroy) (/*@only@*/ void *data);
+ void (*print) (void *data, FILE *f, int indent_level);
+} yasm_assoc_data_callback;
+
/** Bytecode (opaque type).
* \see bytecode.h for related functions.
* Define YASM_BC_INTERNAL to get visible internals.
*/
typedef struct yasm_bytecode yasm_bytecode;
-/** List of bytecodes (opaque type). \see bytecode.h for related functions. */
-typedef struct yasm_bytecodehead yasm_bytecodehead;
+
+/** Object (opaque type). \see section.h for related functions. */
+typedef struct yasm_object yasm_object;
/** Section (opaque type). \see section.h for related functions. */
typedef struct yasm_section yasm_section;
-/** List of sections (opaque type). \see section.h for related functions. */
-typedef struct yasm_sectionhead yasm_sectionhead;
+
+/** Symbol table (opaque type). \see symrec.h for related functions. */
+typedef struct yasm_symtab yasm_symtab;
/** Symbol record (opaque type). \see symrec.h for related functions. */
typedef struct yasm_symrec yasm_symrec;
*/
typedef struct yasm_floatnum yasm_floatnum;
-/** Line number management interface. \see linemgr.h for more details. */
-typedef struct yasm_linemgr yasm_linemgr;
+/** Line number mapping repository (opaque type). \see linemgr.h for related
+ * functions.
+ */
+typedef struct yasm_linemap yasm_linemap;
/** Value/parameter pair (opaque type).
* \see valparam.h for related functions.
YASM_SYM_EXTERN = 1 << 2 /**< If symbol is declared EXTERN */
} yasm_sym_vis;
-/** Determine the distance between the starting offsets of two bytecodes in a
- * section.
- * \param sect section containing the two bytecodes
- * \param precbc1 preceding bytecode to the first bytecode (NULL
- * indicates first bytecode in section)
- * \param precbc2 preceding bytecode to the second bytecode (NULL
- * indicates first bytecode in section)
+/** Determine the distance between the starting offsets of two bytecodes.
+ * \param precbc1 preceding bytecode to the first bytecode
+ * \param precbc2 preceding bytecode to the second bytecode
* \return Distance in bytes between the two bytecodes (bc2-bc1), or NULL if
* the distance was indeterminate.
*/
typedef /*@null@*/ yasm_intnum * (*yasm_calc_bc_dist_func)
- (yasm_section *sect, /*@null@*/ yasm_bytecode *precbc1,
- /*@null@*/ yasm_bytecode *precbc2);
+ (yasm_bytecode *precbc1, yasm_bytecode *precbc2);
/** Convert yasm_expr to its byte representation. Usually implemented by
* object formats to keep track of relocations and verify legal expressions.
* shift (standard warnings include truncation to boundary)
* \param offset offset (in bytes) of the expr contents from the start
* of the bytecode (sometimes needed for conditional jumps)
- * \param sect current section (usually passed into higher-level
- * calling function)
* \param bc current bytecode (usually passed into higher-level
* calling function)
* \param rel if nonzero, expr should be treated as PC/IP-relative
*/
typedef int (*yasm_output_expr_func)
(yasm_expr **ep, /*@out@*/ unsigned char *buf, size_t destsize,
- size_t valsize, int shift, unsigned long offset,
- /*@observer@*/ const yasm_section *sect, yasm_bytecode *bc, int rel,
- int warn, /*@null@*/ void *d) /*@uses *ep@*/;
+ size_t valsize, int shift, unsigned long offset, yasm_bytecode *bc,
+ int rel, int warn, /*@null@*/ void *d) /*@uses *ep@*/;
typedef int (*yasm_output_reloc_func)
(yasm_symrec *sym, yasm_bytecode *bc, unsigned char *buf, size_t destsize,
- size_t valsize, int rel, int warn, const yasm_section *sect, void *d);
-
-/** Convert a yasm_objfmt-specific data bytecode into its byte representation.
- * Usually implemented by object formats to output their own generated data.
- * \param type yasm_objfmt-specific type
- * \param data data
- * \param bufp (double) pointer to buffer for byte representation
- * \note bufp is guaranteed to have enough space to store the data into (as
- * given by the original yasm_bc_new_objfmt_data() call).
- * \return Nonzero if an error occurred, 0 otherwise.
- */
-typedef int (*yasm_output_bc_objfmt_data_func)
- (unsigned int type, /*@observer@*/ void *data, unsigned char **bufp)
- /*@sets **bufp@*/;
+ size_t valsize, int rel, int warn, void *d);
/** Sort an array using merge sort algorithm.
* \internal
* definitions match the module loader's function definitions. The version
* number must never be decreased.
*/
-#define YASM_DBGFMT_VERSION 1
+#define YASM_DBGFMT_VERSION 2
/** YASM debug format interface. */
struct yasm_dbgfmt {
* \return Nonzero if object format does not provide needed support.
*/
int (*initialize) (const char *in_filename, const char *obj_filename,
- yasm_linemgr *lm, yasm_objfmt *of, yasm_arch *a,
- const char *machine);
+ yasm_object *object, yasm_objfmt *of, yasm_arch *a);
/** Clean up anything allocated by initialize(). Function may be
* unimplemented (NULL) if not needed by the debug format.
/** DEBUG directive support.
* \param name directive name
* \param valparams value/parameters
- * \param lindex line index (as from yasm_linemgr)
+ * \param line virtual line (from yasm_linemap)
* \return Nonzero if directive was not recognized; 0 if directive was
* recognized even if it wasn't valid.
*/
int (*directive) (const char *name, yasm_valparamhead *valparams,
- unsigned long lindex);
+ unsigned long line);
/** Generate debugging information bytecodes
- * \param sections list of sections
+ * \param object object
*/
- void (*generate) (yasm_sectionhead *sections);
-
- /** Output debug format-specific bytecode data (YASM_BC_DBGFMT_DATA).
- * Function may be unimplemented (NULL) if no YASM_BC_DBGFMT_DATA is ever
- * allocated by the debug format.
- * \param type debug format-specific bytecode type
- * \param data debug format-specific data
- * \param buf provided buffer, as long as registered length
- */
- int (*bc_dbgfmt_data_output)(yasm_bytecode *bc, unsigned int type,
- const void *data, unsigned char **buf,
- const yasm_section *sect,
- yasm_output_reloc_func output_reloc,
- void *objfmt_d);
-
- /** Delete debug format-specific bytecode data (YASM_BC_DBGFMT_DATA).
- * Funtion may be unimplemented (NULL) if no YASM_BC_DBGFMT_DATA is ever
- * allocated by the debug format.
- * \param type debug format-specific bytecode type
- * \param data debug-format specific data
- */
- void (*bc_dbgfmt_data_delete)(unsigned int type, /*@only@*/ void *data);
-
- /** Print debug format-specific bytecode data (YASM_BC_DBGFMT_DATA). For
- * debugging purposes. Function may be unimplemented (NULL) if no
- * YASM_BC_DBGFMT_DATA is ever allocated by the debug format.
- * \param f file
- * \param indent_level indentation level
- * \param type debug format-specific bytecode type
- * \param data debug format-specific data
- */
- void (*bc_dbgfmt_data_print)(FILE *f, int indent_level, unsigned int type,
- const void *data);
+ void (*generate) (yasm_object *object);
};
#endif
* type is WE_PARSERERROR.
*/
static errwarn_data *
-errwarn_data_new(unsigned long lindex, int replace_parser_error)
+errwarn_data_new(unsigned long line, int replace_parser_error)
{
errwarn_data *first, *next, *ins_we, *we;
enum { INS_NONE, INS_HEAD, INS_AFTER } action = INS_NONE;
- /* Find the entry with either line=lindex or the last one with line<lindex.
+ /* Find the entry with either line=line or the last one with line<line.
* Start with the last entry added to speed the search.
*/
ins_we = previous_we;
action = INS_HEAD;
while (action == INS_NONE) {
next = SLIST_NEXT(ins_we, link);
- if (lindex < ins_we->line) {
+ if (line < ins_we->line) {
if (ins_we == first)
action = INS_HEAD;
else
ins_we = first;
} else if (!next)
action = INS_AFTER;
- else if (lindex >= ins_we->line && lindex < next->line)
+ else if (line >= ins_we->line && line < next->line)
action = INS_AFTER;
else
ins_we = next;
we = yasm_xmalloc(sizeof(errwarn_data));
we->type = WE_UNKNOWN;
- we->line = lindex;
+ we->line = line;
if (action == INS_HEAD)
SLIST_INSERT_HEAD(&errwarns, we, link);
return we;
}
-/* Register an error at line lindex. Does not print the error, only stores it
+/* Register an error at line line. Does not print the error, only stores it
* for output_all() to print.
*/
void
-yasm__error_va(unsigned long lindex, const char *fmt, va_list va)
+yasm__error_va(unsigned long line, const char *fmt, va_list va)
{
- errwarn_data *we = errwarn_data_new(lindex, 1);
+ errwarn_data *we = errwarn_data_new(line, 1);
we->type = WE_ERROR;
error_count++;
}
-/* Register an warning at line lindex. Does not print the warning, only stores
+/* Register an warning at line line. Does not print the warning, only stores
* it for output_all() to print.
*/
void
-yasm__warning_va(yasm_warn_class num, unsigned long lindex, const char *fmt,
+yasm__warning_va(yasm_warn_class num, unsigned long line, const char *fmt,
va_list va)
{
errwarn_data *we;
if (!(warn_class_enabled & (1UL<<num)))
return; /* warning is part of disabled class */
- we = errwarn_data_new(lindex, 0);
+ we = errwarn_data_new(line, 0);
we->type = WE_WARNING;
warning_count++;
}
-/* Register an error at line lindex. Does not print the error, only stores it
+/* Register an error at line line. Does not print the error, only stores it
* for output_all() to print.
*/
void
-yasm__error(unsigned long lindex, const char *fmt, ...)
+yasm__error(unsigned long line, const char *fmt, ...)
{
va_list va;
va_start(va, fmt);
- yasm__error_va(lindex, fmt, va);
+ yasm__error_va(line, fmt, va);
va_end(va);
}
-/* Register an warning at line lindex. Does not print the warning, only stores
+/* Register an warning at line line. Does not print the warning, only stores
* it for output_all() to print.
*/
void
-yasm__warning(yasm_warn_class num, unsigned long lindex, const char *fmt, ...)
+yasm__warning(yasm_warn_class num, unsigned long line, const char *fmt, ...)
{
va_list va;
va_start(va, fmt);
- yasm__warning_va(num, lindex, fmt, va);
+ yasm__warning_va(num, line, fmt, va);
va_end(va);
}
* system.
*/
void
-yasm__parser_error(unsigned long lindex, const char *s)
+yasm__parser_error(unsigned long line, const char *s)
{
- yasm__error(lindex, N_("parser error: %s"), s);
+ yasm__error(line, N_("parser error: %s"), s);
previous_we->type = WE_PARSERERROR;
}
}
void
-yasm_errwarn_output_all(yasm_linemgr *lm, int warning_as_error,
+yasm_errwarn_output_all(yasm_linemap *lm, int warning_as_error,
yasm_print_error_func print_error, yasm_print_warning_func print_warning)
{
errwarn_data *we;
/* Output error/warnings. */
SLIST_FOREACH(we, &errwarns, link) {
/* Output error/warning */
- lm->lookup(we->line, &filename, &line);
+ yasm_linemap_lookup(lm, we->line, &filename, &line);
if (we->type == WE_ERROR)
print_error(filename, line, we->msg);
else
/** Log an error. va_list version of yasm__error().
* \internal
- * \param lindex line index
+ * \param line virtual line
* \param message printf-like-format message
* \param va argument list for message
*/
-void yasm__error_va(unsigned long lindex, const char *message, va_list va);
+void yasm__error_va(unsigned long line, const char *message, va_list va);
/** Log a warning. va_list version of yasm__warning().
* \internal
* \param wclass warning class
- * \param lindex line index
+ * \param line virtual line
* \param message printf-like-format message
* \param va argument list for message
*/
-void yasm__warning_va(yasm_warn_class wclass, unsigned long lindex,
+void yasm__warning_va(yasm_warn_class wclass, unsigned long line,
const char *message, va_list va);
/** Log an error. Does not print it out immediately; yasm_errwarn_output_all()
* outputs errors and warnings.
* \internal
- * \param lindex line index
+ * \param line virtual line
* \param message printf-like-format message
* \param ... argument list for message
*/
-void yasm__error(unsigned long lindex, const char *message, ...)
+void yasm__error(unsigned long line, const char *message, ...)
/*@printflike@*/;
/** Log a warning. Does not print it out immediately;
* yasm_errwarn_output_all() outputs errors and warnings.
* \internal
* \param wclass warning class
- * \param lindex line index
+ * \param line virtual line
* \param message printf-like-format message
* \param ... argument list for message
*/
-void yasm__warning(yasm_warn_class wclass, unsigned long lindex,
+void yasm__warning(yasm_warn_class wclass, unsigned long line,
const char *message, ...) /*@printflike@*/;
/** Log a parser error. Parser errors can be overwritten by non-parser errors
* on the same line.
* \internal
- * \param lindex line index
+ * \param line virtual line
* \param message parser error message
*/
-void yasm__parser_error(unsigned long lindex, const char *message);
+void yasm__parser_error(unsigned long line, const char *message);
/** Enable a class of warnings.
* \param wclass warning class
(const char *fn, unsigned long line, const char *msg);
/** Outputs all errors and warnings.
- * \param lm line manager (to convert line indexes into filename/line pairs)
+ * \param lm line map (to convert virtual lines into filename/line pairs)
* \param warning_as_error if nonzero, treat warnings as errors
* \param print_error function called to print out errors
* \param print_warning function called to print out warnings
*/
void yasm_errwarn_output_all
- (yasm_linemgr *lm, int warning_as_error, yasm_print_error_func print_error,
+ (yasm_linemap *lm, int warning_as_error, yasm_print_error_func print_error,
yasm_print_warning_func print_warning);
/** Convert a possibly unprintable character into a printable string.
int (*func) (/*@null@*/ yasm_expr *e,
/*@null@*/ void *d));
-static /*@dependent@*/ yasm_arch *cur_arch;
-
-
-void
-yasm_expr_initialize(yasm_arch *a)
-{
- cur_arch = a;
-}
-
/* 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 *
-yasm_expr_new(yasm_expr_op op, yasm_expr__item *left, yasm_expr__item *right,
- unsigned long lindex)
+yasm_expr_create(yasm_expr_op op, yasm_expr__item *left,
+ yasm_expr__item *right, unsigned long line)
{
yasm_expr *ptr, *sube;
ptr = yasm_xmalloc(sizeof(yasm_expr));
}
}
- ptr->line = lindex;
+ ptr->line = line;
return ptr;
}
* absolute start expr + intnum(dist).
*/
if (e->terms[i].type == YASM_EXPR_SYM &&
- yasm_symrec_get_label(e->terms[i].data.sym, §, &precbc) &&
+ yasm_symrec_get_label(e->terms[i].data.sym, &precbc) &&
+ (sect = yasm_bc_get_section(precbc)) &&
yasm_section_is_absolute(sect) &&
- (dist = calc_bc_dist(sect, NULL, precbc))) {
+ (dist = calc_bc_dist(yasm_section_bcs_first(sect), precbc))) {
const yasm_expr *start = yasm_section_get_start(sect);
e->terms[i].type = YASM_EXPR_EXPR;
e->terms[i].data.expn =
- yasm_expr_new(YASM_EXPR_ADD,
- yasm_expr_expr(yasm_expr_copy(start)),
- yasm_expr_int(dist), e->line);
+ yasm_expr_create(YASM_EXPR_ADD,
+ yasm_expr_expr(yasm_expr_copy(start)),
+ yasm_expr_int(dist), e->line);
}
}
if (!yasm_intnum_is_neg1(intn))
continue;
- yasm_symrec_get_label(sym, §2, &precbc);
+ yasm_symrec_get_label(sym, &precbc);
+ 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 &&
- yasm_symrec_get_label(e->terms[j].data.sym, §, &precbc2) &&
+ yasm_symrec_get_label(e->terms[j].data.sym, &precbc2) &&
+ (sect = yasm_bc_get_section(precbc2)) &&
sect == sect2 &&
- (dist = calc_bc_dist(sect, precbc, precbc2))) {
+ (dist = calc_bc_dist(precbc, precbc2))) {
/* Change the symrec term to an integer */
e->terms[j].type = YASM_EXPR_INT;
e->terms[j].data.intn = dist;
/* Delete the matching (-1*symrec) term */
- yasm_expr_delete(sube);
+ yasm_expr_destroy(sube);
e->terms[i].type = YASM_EXPR_NONE;
break; /* stop looking for matching symrec term */
}
sube->line = e->line;
sube->numterms = 2;
sube->terms[0].type = YASM_EXPR_INT;
- sube->terms[0].data.intn = yasm_intnum_new_int(-1);
+ sube->terms[0].data.intn = yasm_intnum_create_int(-1);
sube->terms[1] = *ei; /* structure copy */
/* Replace original ExprItem with subexp */
e->op = YASM_EXPR_MUL;
e->numterms = 2;
e->terms[1].type = YASM_EXPR_INT;
- e->terms[1].data.intn = yasm_intnum_new_int(-1);
+ e->terms[1].data.intn = yasm_intnum_create_int(-1);
}
break;
default:
ne->line = e->line;
ne->numterms = 2;
ne->terms[0].type = YASM_EXPR_INT;
- ne->terms[0].data.intn = yasm_intnum_new_int(-1);
+ 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;
/* Look for simple "left" identities like 0+x, 1*x, etc. */
static int
-expr_can_delete_int_left(yasm_expr_op op, yasm_intnum *intn)
+expr_can_destroy_int_left(yasm_expr_op op, yasm_intnum *intn)
{
return ((yasm_intnum_is_pos1(intn) && op == YASM_EXPR_MUL) ||
(yasm_intnum_is_zero(intn) && op == YASM_EXPR_ADD) ||
/* Look for simple "right" identities like x+|-0, x*&/1 */
static int
-expr_can_delete_int_right(yasm_expr_op op, yasm_intnum *intn)
+expr_can_destroy_int_right(yasm_expr_op op, yasm_intnum *intn)
{
return ((yasm_intnum_is_pos1(intn) && op == YASM_EXPR_MUL) ||
(yasm_intnum_is_pos1(intn) && op == YASM_EXPR_DIV) ||
* Don't delete if the intnum is the only thing in the expn.
*/
if ((int_term == 0 && numterms > 1 &&
- expr_can_delete_int_left(e->op, e->terms[0].data.intn)) ||
+ expr_can_destroy_int_left(e->op, e->terms[0].data.intn)) ||
(int_term > 0 &&
- expr_can_delete_int_right(e->op, e->terms[int_term].data.intn))) {
+ expr_can_destroy_int_right(e->op, e->terms[int_term].data.intn))) {
/* Delete the intnum */
- yasm_intnum_delete(e->terms[int_term].data.intn);
+ 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.. */
if (i != int_term)
switch (e->terms[i].type) {
case YASM_EXPR_INT:
- yasm_intnum_delete(e->terms[i].data.intn);
+ yasm_intnum_destroy(e->terms[i].data.intn);
break;
case YASM_EXPR_FLOAT:
- yasm_floatnum_delete(e->terms[i].data.flt);
+ yasm_floatnum_destroy(e->terms[i].data.flt);
break;
case YASM_EXPR_EXPR:
- yasm_expr_delete(e->terms[i].data.expn);
+ yasm_expr_destroy(e->terms[i].data.expn);
break;
default:
break;
fold_numterms--;
level_numterms--;
/* make sure to delete folded intnum */
- yasm_intnum_delete(e->terms[i].data.intn);
+ yasm_intnum_destroy(e->terms[i].data.intn);
} else if (o != i) {
/* copy term if it changed places */
e->terms[o++] = e->terms[i];
e->op, sube->terms[j].data.intn,
e->line);
/* make sure to delete folded intnum */
- yasm_intnum_delete(sube->terms[j].data.intn);
+ yasm_intnum_destroy(sube->terms[j].data.intn);
}
} else {
if (o == first_int_term)
}
static int
-expr_delete_each(/*@only@*/ yasm_expr *e, /*@unused@*/ void *d)
+expr_destroy_each(/*@only@*/ yasm_expr *e, /*@unused@*/ void *d)
{
int i;
for (i=0; i<e->numterms; i++) {
switch (e->terms[i].type) {
case YASM_EXPR_INT:
- yasm_intnum_delete(e->terms[i].data.intn);
+ yasm_intnum_destroy(e->terms[i].data.intn);
break;
case YASM_EXPR_FLOAT:
- yasm_floatnum_delete(e->terms[i].data.flt);
+ yasm_floatnum_destroy(e->terms[i].data.flt);
break;
default:
break; /* none of the other types needs to be deleted */
/*@-mustfree@*/
void
-yasm_expr_delete(yasm_expr *e)
+yasm_expr_destroy(yasm_expr *e)
{
- expr_traverse_nodes_post(e, NULL, expr_delete_each);
+ expr_traverse_nodes_post(e, NULL, expr_destroy_each);
}
/*@=mustfree@*/
break;
}
if (sym) {
- /*@dependent@*/ yasm_section *sect;
/*@dependent@*/ /*@null@*/ yasm_bytecode *precbc;
/*@null@*/ yasm_intnum *intn;
- if (yasm_symrec_get_label(sym, §, &precbc)) {
- intn = calc_bc_dist(sect, NULL, precbc);
+ if (yasm_symrec_get_label(sym, &precbc)) {
+ intn = calc_bc_dist(yasm_section_bcs_first(
+ yasm_bc_get_section(precbc)), precbc);
if (!intn)
return NULL;
} else
- intn = yasm_intnum_new_uint(0);
+ intn = yasm_intnum_create_uint(0);
(*ep)->terms[symterm].type = YASM_EXPR_INT;
(*ep)->terms[symterm].data.intn = intn;
}
/*@=unqualifiedtrans =nullderef -nullstate -onlytrans@*/
void
-yasm_expr_print(FILE *f, const yasm_expr *e)
+yasm_expr_print(const yasm_expr *e, FILE *f)
{
char opstr[6];
int i;
break;
case YASM_EXPR_EXPR:
fprintf(f, "(");
- yasm_expr_print(f, e->terms[i].data.expn);
+ yasm_expr_print(e->terms[i].data.expn, f);
fprintf(f, ")");
break;
case YASM_EXPR_INT:
- yasm_intnum_print(f, e->terms[i].data.intn);
+ yasm_intnum_print(e->terms[i].data.intn, f);
break;
case YASM_EXPR_FLOAT:
- yasm_floatnum_print(f, e->terms[i].data.flt);
+ yasm_floatnum_print(e->terms[i].data.flt, f);
break;
case YASM_EXPR_REG:
- cur_arch->reg_print(f, e->terms[i].data.reg);
+ /* FIXME */
+ /*arch->module->reg_print(arch, e->terms[i].data.reg, f);*/
break;
case YASM_EXPR_NONE:
break;
/** Expression item (opaque type). \internal */
typedef struct yasm_expr__item yasm_expr__item;
-/** Initialize expression internal data structures.
- * \param a architecture in use
- */
-void yasm_expr_initialize(yasm_arch *a);
-
/** Create a new expression e=a op b.
* \param op operation
* \param a expression item a
* \param b expression item b (optional depending on op)
- * \param lindex line index (where expression defined)
+ * \param line virtual line (where expression defined)
* \return Newly allocated expression.
*/
-/*@only@*/ yasm_expr *yasm_expr_new
+/*@only@*/ yasm_expr *yasm_expr_create
(yasm_expr_op op, /*@only@*/ yasm_expr__item *a,
- /*@only@*/ /*@null@*/ yasm_expr__item *b, unsigned long lindex);
+ /*@only@*/ /*@null@*/ yasm_expr__item *b, unsigned long line);
/** Create a new symbol expression item.
* \param sym symbol
* \param i line index
* \return Newly allocated expression.
*/
-#define yasm_expr_new_tree(l,o,r,i) \
- yasm_expr_new ((o), yasm_expr_expr(l), yasm_expr_expr(r), i)
+#define yasm_expr_create_tree(l,o,r,i) \
+ yasm_expr_create ((o), yasm_expr_expr(l), yasm_expr_expr(r), i)
/** Create a new expression branch e=op r.
* \param o operation
* \param i line index
* \return Newly allocated expression.
*/
-#define yasm_expr_new_branch(o,r,i) \
- yasm_expr_new ((o), yasm_expr_expr(r), (yasm_expr__item *)NULL, i)
+#define yasm_expr_create_branch(o,r,i) \
+ yasm_expr_create ((o), yasm_expr_expr(r), (yasm_expr__item *)NULL, i)
/** Create a new expression identity e=r.
* \param r expression for identity within new expression
* \param i line index
* \return Newly allocated expression.
*/
-#define yasm_expr_new_ident(r,i) \
- yasm_expr_new (YASM_EXPR_IDENT, (r), (yasm_expr__item *)NULL, i)
+#define yasm_expr_create_ident(r,i) \
+ yasm_expr_create (YASM_EXPR_IDENT, (r), (yasm_expr__item *)NULL, i)
/** Duplicate an expression.
* \param e expression
/** Destroy (free allocated memory for) an expression.
* \param e expression
*/
-void yasm_expr_delete(/*@only@*/ /*@null@*/ yasm_expr *e);
+void yasm_expr_destroy(/*@only@*/ /*@null@*/ yasm_expr *e);
/** Determine if an expression is a specified operation (at the top level).
* \param e expression
(yasm_expr **ep, int simplify);
/** Print an expression. For debugging purposes.
- * \param f file
* \param e expression
+ * \param f file
*/
-void yasm_expr_print(FILE *f, /*@null@*/ const yasm_expr *e);
+void yasm_expr_print(/*@null@*/ const yasm_expr *e, FILE *f);
#endif
}
yasm_floatnum *
-yasm_floatnum_new(const char *str)
+yasm_floatnum_create(const char *str)
{
yasm_floatnum *flt;
int dec_exponent, dec_exp_add; /* decimal (powers of 10) exponent */
}
void
-yasm_floatnum_delete(yasm_floatnum *flt)
+yasm_floatnum_destroy(yasm_floatnum *flt)
{
BitVector_Destroy(flt->mantissa);
yasm_xfree(flt);
void
yasm_floatnum_calc(yasm_floatnum *acc, yasm_expr_op op,
- /*@unused@*/ yasm_floatnum *operand, unsigned long lindex)
+ /*@unused@*/ yasm_floatnum *operand, unsigned long line)
{
if (op != YASM_EXPR_NEG)
- yasm__error(lindex,
+ yasm__error(line,
N_("Unsupported floating-point arithmetic operation"));
else
acc->sign ^= 1;
int
yasm_floatnum_get_sized(const yasm_floatnum *flt, unsigned char *ptr,
size_t destsize, size_t valsize, size_t shift,
- int bigendian, int warn, unsigned long lindex)
+ int bigendian, int warn, unsigned long line)
{
int retval;
if (destsize*8 != valsize || shift>0 || bigendian) {
}
if (warn) {
if (retval < 0)
- yasm__warning(YASM_WARN_GENERAL, lindex,
+ yasm__warning(YASM_WARN_GENERAL, line,
N_("underflow in floating point expression"));
else if (retval > 0)
- yasm__warning(YASM_WARN_GENERAL, lindex,
+ yasm__warning(YASM_WARN_GENERAL, line,
N_("overflow in floating point expression"));
}
return retval;
}
void
-yasm_floatnum_print(FILE *f, const yasm_floatnum *flt)
+yasm_floatnum_print(const yasm_floatnum *flt, FILE *f)
{
unsigned char out[10];
unsigned char *str;
* \param str floating point decimal string
* \return Newly allocated floatnum.
*/
-/*@only@*/ yasm_floatnum *yasm_floatnum_new(const char *str);
+/*@only@*/ yasm_floatnum *yasm_floatnum_create(const char *str);
/** Duplicate a floatnum.
* \param flt floatnum
/** Destroy (free allocated memory for) a floatnum.
* \param flt floatnum
*/
-void yasm_floatnum_delete(/*@only@*/ yasm_floatnum *flt);
+void yasm_floatnum_destroy(/*@only@*/ yasm_floatnum *flt);
/** Floating point calculation function: acc = acc op operand.
* \note Not all operations in yasm_expr_op may be supported; unsupported
* \param acc floatnum accumulator
* \param op operation
* \param operand floatnum operand
- * \param lindex line index (of expression)
+ * \param line virtual line (of expression)
*/
void yasm_floatnum_calc(yasm_floatnum *acc, yasm_expr_op op,
- yasm_floatnum *operand, unsigned long lindex);
+ yasm_floatnum *operand, unsigned long line);
/** Convert a floatnum to single-precision and return as 32-bit value.
* The 32-bit value is a "standard" C value (eg, of unknown endian).
* \param shift left shift (in bits)
* \param bigendian endianness (nonzero=big, zero=little)
* \param warn enables standard overflow/underflow warnings
- * \param lindex line index; may be 0 if warn is 0.
+ * \param line virtual line; may be 0 if warn is 0.
* \return Nonzero if flt can't fit into the specified precision: -1 if
* underflow occurred, 1 if overflow occurred.
*/
int yasm_floatnum_get_sized(const yasm_floatnum *flt, unsigned char *ptr,
size_t destsize, size_t valsize, size_t shift,
- int bigendian, int warn, unsigned long lindex);
+ int bigendian, int warn, unsigned long line);
/** Basic check to see if size is valid for flt conversion (using
* yasm_floatnum_get_sized()). Doesn't actually check for underflow/overflow
* \param f file
* \param flt floatnum
*/
-void yasm_floatnum_print(FILE *f, const yasm_floatnum *flt);
+void yasm_floatnum_print(const yasm_floatnum *flt, FILE *f);
#endif
}
HAMT *
-HAMT_new(/*@exits@*/ void (*error_func) (const char *file, unsigned int line,
- const char *message))
+HAMT_create(/*@exits@*/ void (*error_func)
+ (const char *file, unsigned int line, const char *message))
{
/*@out@*/ HAMT *hamt = yasm_xmalloc(sizeof(HAMT));
int i;
}
void
-HAMT_delete(HAMT *hamt, void (*deletefunc) (/*@only@*/ void *data))
+HAMT_destroy(HAMT *hamt, void (*deletefunc) (/*@only@*/ void *data))
{
int i;
/* Creates new, empty, HAMT. error_func() is called when an internal error is
* encountered--it should NOT return to the calling function.
*/
-HAMT *HAMT_new(/*@exits@*/ void (*error_func) (const char *file,
- unsigned int line,
- const char *message));
+HAMT *HAMT_create(/*@exits@*/ void (*error_func)
+ (const char *file, unsigned int line, const char *message));
/* Deletes HAMT and all data associated with it using deletefunc() on each data
* item.
*/
-void HAMT_delete(/*@only@*/ HAMT *hamt,
- void (*deletefunc) (/*@only@*/ void *data));
+void HAMT_destroy(/*@only@*/ HAMT *hamt,
+ void (*deletefunc) (/*@only@*/ void *data));
/* Inserts key into HAMT, associating it with data.
* If the key is not present in the HAMT, inserts it, sets *replace to 1, and
/* static bitvects used for computation */
static /*@only@*/ wordptr result, spare, op1static, op2static;
+static /*@only@*/ BitVector_from_Dec_static_data *from_dec_data;
+
void
yasm_intnum_initialize(void)
spare = BitVector_Create(BITVECT_NATIVE_SIZE, FALSE);
op1static = BitVector_Create(BITVECT_NATIVE_SIZE, FALSE);
op2static = BitVector_Create(BITVECT_NATIVE_SIZE, FALSE);
- BitVector_from_Dec_static_Boot(BITVECT_NATIVE_SIZE);
+ from_dec_data = BitVector_from_Dec_static_Boot(BITVECT_NATIVE_SIZE);
}
void
yasm_intnum_cleanup(void)
{
- BitVector_from_Dec_static_Shutdown();
+ BitVector_from_Dec_static_Shutdown(from_dec_data);
BitVector_Destroy(op2static);
BitVector_Destroy(op1static);
BitVector_Destroy(spare);
}
yasm_intnum *
-yasm_intnum_new_dec(char *str, unsigned long lindex)
+yasm_intnum_create_dec(char *str, unsigned long line)
{
yasm_intnum *intn = yasm_xmalloc(sizeof(yasm_intnum));
intn->origsize = 0; /* no reliable way to figure this out */
- if (BitVector_from_Dec_static(conv_bv,
+ if (BitVector_from_Dec_static(from_dec_data, conv_bv,
(unsigned char *)str) == ErrCode_Ovfl)
- yasm__warning(YASM_WARN_GENERAL, lindex,
+ yasm__warning(YASM_WARN_GENERAL, line,
N_("Numeric constant too large for internal format"));
if (Set_Max(conv_bv) < 32) {
intn->type = INTNUM_UL;
}
yasm_intnum *
-yasm_intnum_new_bin(char *str, unsigned long lindex)
+yasm_intnum_create_bin(char *str, unsigned long line)
{
yasm_intnum *intn = yasm_xmalloc(sizeof(yasm_intnum));
intn->origsize = (unsigned char)strlen(str);
if(intn->origsize > BITVECT_NATIVE_SIZE)
- yasm__warning(YASM_WARN_GENERAL, lindex,
+ yasm__warning(YASM_WARN_GENERAL, line,
N_("Numeric constant too large for internal format"));
BitVector_from_Bin(conv_bv, (unsigned char *)str);
}
yasm_intnum *
-yasm_intnum_new_oct(char *str, unsigned long lindex)
+yasm_intnum_create_oct(char *str, unsigned long line)
{
yasm_intnum *intn = yasm_xmalloc(sizeof(yasm_intnum));
intn->origsize = strlen(str)*3;
if(intn->origsize > BITVECT_NATIVE_SIZE)
- yasm__warning(YASM_WARN_GENERAL, lindex,
+ yasm__warning(YASM_WARN_GENERAL, line,
N_("Numeric constant too large for internal format"));
BitVector_from_Oct(conv_bv, (unsigned char *)str);
}
yasm_intnum *
-yasm_intnum_new_hex(char *str, unsigned long lindex)
+yasm_intnum_create_hex(char *str, unsigned long line)
{
yasm_intnum *intn = yasm_xmalloc(sizeof(yasm_intnum));
intn->origsize = strlen(str)*4;
if(intn->origsize > BITVECT_NATIVE_SIZE)
- yasm__warning(YASM_WARN_GENERAL, lindex,
+ yasm__warning(YASM_WARN_GENERAL, line,
N_("Numeric constant too large for internal format"));
BitVector_from_Hex(conv_bv, (unsigned char *)str);
/*@-usedef -compdef -uniondef@*/
yasm_intnum *
-yasm_intnum_new_charconst_nasm(const char *str, unsigned long lindex)
+yasm_intnum_create_charconst_nasm(const char *str, unsigned long line)
{
yasm_intnum *intn = yasm_xmalloc(sizeof(yasm_intnum));
size_t len = strlen(str);
intn->origsize = len*8;
if(intn->origsize > BITVECT_NATIVE_SIZE)
- yasm__warning(YASM_WARN_GENERAL, lindex,
+ yasm__warning(YASM_WARN_GENERAL, line,
N_("Character constant too large for internal format"));
if (len > 4) {
/*@=usedef =compdef =uniondef@*/
yasm_intnum *
-yasm_intnum_new_uint(unsigned long i)
+yasm_intnum_create_uint(unsigned long i)
{
yasm_intnum *intn = yasm_xmalloc(sizeof(yasm_intnum));
}
yasm_intnum *
-yasm_intnum_new_int(long i)
+yasm_intnum_create_int(long i)
{
yasm_intnum *intn;
/* positive numbers can go through the uint() function */
if (i >= 0)
- return yasm_intnum_new_uint((unsigned long)i);
+ return yasm_intnum_create_uint((unsigned long)i);
BitVector_Empty(conv_bv);
BitVector_Chunk_Store(conv_bv, 32, 0, (unsigned long)(-i));
}
void
-yasm_intnum_delete(yasm_intnum *intn)
+yasm_intnum_destroy(yasm_intnum *intn)
{
if (intn->type == INTNUM_BV)
BitVector_Destroy(intn->val.bv);
/*@-nullderef -nullpass -branchstate@*/
void
yasm_intnum_calc(yasm_intnum *acc, yasm_expr_op op, yasm_intnum *operand,
- unsigned long lindex)
+ unsigned long line)
{
boolean carry = 0;
wordptr op1, op2 = NULL;
BitVector_LSB(result, !BitVector_equal(op1, op2));
break;
case YASM_EXPR_SEG:
- yasm__error(lindex, N_("invalid use of '%s'"), "SEG");
+ yasm__error(line, N_("invalid use of '%s'"), "SEG");
break;
case YASM_EXPR_WRT:
- yasm__error(lindex, N_("invalid use of '%s'"), "WRT");
+ yasm__error(line, N_("invalid use of '%s'"), "WRT");
break;
case YASM_EXPR_SEGOFF:
- yasm__error(lindex, N_("invalid use of '%s'"), ":");
+ yasm__error(line, N_("invalid use of '%s'"), ":");
break;
case YASM_EXPR_IDENT:
if (result)
void
yasm_intnum_get_sized(const yasm_intnum *intn, unsigned char *ptr,
size_t destsize, size_t valsize, int shift,
- int bigendian, int warn, unsigned long lindex)
+ int bigendian, int warn, unsigned long line)
{
wordptr op1 = op1static, op2;
unsigned char *buf;
/* General size warnings */
if (warn && !yasm_intnum_check_size(intn, valsize, rshift, 2))
- yasm__warning(YASM_WARN_GENERAL, lindex,
+ yasm__warning(YASM_WARN_GENERAL, line,
N_("value does not fit in %d bit field"), valsize);
/* Read the original data into a bitvect */
BitVector_Copy(conv_bv, op2);
BitVector_Move_Left(conv_bv, BITVECT_NATIVE_SIZE-rshift);
if (!BitVector_is_empty(conv_bv))
- yasm__warning(YASM_WARN_GENERAL, lindex,
+ yasm__warning(YASM_WARN_GENERAL, line,
N_("misaligned value, truncating to boundary"));
}
}
void
-yasm_intnum_print(FILE *f, const yasm_intnum *intn)
+yasm_intnum_print(const yasm_intnum *intn, FILE *f)
{
unsigned char *s;
/** Create a new intnum from a decimal string.
* \param str decimal string
- * \param lindex line index (where the number came from)
+ * \param line virtual line (where the number came from)
* \return Newly allocated intnum.
*/
-/*@only@*/ yasm_intnum *yasm_intnum_new_dec(char *str, unsigned long lindex);
+/*@only@*/ yasm_intnum *yasm_intnum_create_dec(char *str, unsigned long line);
/** Create a new intnum from a binary string.
* \param str binary string
- * \param lindex line index (where the number came from)
+ * \param line virtual line (where the number came from)
* \return Newly allocated intnum.
*/
-/*@only@*/ yasm_intnum *yasm_intnum_new_bin(char *str, unsigned long lindex);
+/*@only@*/ yasm_intnum *yasm_intnum_create_bin(char *str, unsigned long line);
/** Create a new intnum from an octal string.
* \param str octal string
- * \param lindex line index (where the number came from)
+ * \param line virtual line (where the number came from)
* \return Newly allocated intnum.
*/
-/*@only@*/ yasm_intnum *yasm_intnum_new_oct(char *str, unsigned long lindex);
+/*@only@*/ yasm_intnum *yasm_intnum_create_oct(char *str, unsigned long line);
/** Create a new intnum from a hexidecimal string.
* \param str hexidecimal string
- * \param lindex line index (where the number came from)
+ * \param line virtual line (where the number came from)
* \return Newly allocated intnum.
*/
-/*@only@*/ yasm_intnum *yasm_intnum_new_hex(char *str, unsigned long lindex);
+/*@only@*/ yasm_intnum *yasm_intnum_create_hex(char *str, unsigned long line);
/** Convert character constant to integer value, using NASM rules. NASM syntax
* supports automatic conversion from strings such as 'abcd' to a 32-bit
* integer value. This function performs those conversions.
* \param str character constant string
- * \param lindex line index (where the number came from)
+ * \param line virtual line (where the number came from)
* \return Newly allocated intnum.
*/
-/*@only@*/ yasm_intnum *yasm_intnum_new_charconst_nasm(const char *str,
- unsigned long lindex);
+/*@only@*/ yasm_intnum *yasm_intnum_create_charconst_nasm(const char *str,
+ unsigned long line);
/** Create a new intnum from an unsigned integer value.
* \param i unsigned integer value
* \return Newly allocated intnum.
*/
-/*@only@*/ yasm_intnum *yasm_intnum_new_uint(unsigned long i);
+/*@only@*/ yasm_intnum *yasm_intnum_create_uint(unsigned long i);
/** Create a new intnum from an signed integer value.
* \param i signed integer value
* \return Newly allocated intnum.
*/
-/*@only@*/ yasm_intnum *yasm_intnum_new_int(long i);
+/*@only@*/ yasm_intnum *yasm_intnum_create_int(long i);
/** Duplicate an intnum.
* \param intn intnum
/** Destroy (free allocated memory for) an intnum.
* \param intn intnum
*/
-void yasm_intnum_delete(/*@only@*/ yasm_intnum *intn);
+void yasm_intnum_destroy(/*@only@*/ yasm_intnum *intn);
/** Floating point calculation function: acc = acc op operand.
* \note Not all operations in yasm_expr_op may be supported; unsupported
* \param acc intnum accumulator
* \param op operation
* \param operand intnum operand
- * \param lindex line index (of expression)
+ * \param line virtual line (of expression)
*/
void yasm_intnum_calc(yasm_intnum *acc, yasm_expr_op op, yasm_intnum *operand,
- unsigned long lindex);
+ unsigned long line);
/** Simple value check for 0.
* \param acc intnum
* \param bigendian endianness (nonzero=big, zero=little)
* \param warn enables standard warnings (value doesn't fit into valsize
* bits)
- * \param lindex line index; may be 0 if warn is 0
+ * \param line virtual line; may be 0 if warn is 0
*/
void yasm_intnum_get_sized(const yasm_intnum *intn, unsigned char *ptr,
size_t destsize, size_t valsize, int shift,
- int bigendian, int warn, unsigned long lindex);
+ int bigendian, int warn, unsigned long line);
/** Check to see if intnum will fit without overflow into size bits.
* If is_signed is 1, intnum is treated as a signed number.
* \param f file
* \param intn intnum
*/
-void yasm_intnum_print(FILE *f, const yasm_intnum *intn);
+void yasm_intnum_print(const yasm_intnum *intn, FILE *f);
#endif
*/
#define YASM_LIB_INTERNAL
#include "util.h"
-/*@unused@*/ RCSID("$IdPath: yasm/libyasm/linemgr.c,v 1.33 2003/03/16 23:52:23 peter Exp $");
+/*@unused@*/ RCSID("$IdPath$");
#include "coretype.h"
#include "hamt.h"
/* Source lines tracking */
typedef struct {
- struct line_index_mapping *vector;
+ struct line_mapping *vector;
unsigned long size;
unsigned long allocated;
-} line_index_mapping_head;
+} line_mapping_head;
-typedef struct line_index_mapping {
- /* monotonically increasing line index */
- unsigned long index;
+typedef struct line_mapping {
+ /* monotonically increasing virtual line */
+ unsigned long line;
/* related info */
/* "original" source filename */
/*@null@*/ /*@dependent@*/ const char *filename;
/* "original" source base line number */
- unsigned long line;
+ unsigned long file_line;
/* "original" source line number increment (for following lines) */
unsigned long line_inc;
-} line_index_mapping;
+} line_mapping;
-typedef struct line_index_assoc_data_raw_head {
+typedef struct line_assoc_data_raw_head {
/*@only@*/ void **vector;
- /*@null@*/ void (*delete_func) (/*@only@*/ void *);
- unsigned long size;
-} line_index_assoc_data_raw_head;
+ const yasm_assoc_data_callback *callback;
+ size_t size;
+} line_assoc_data_raw_head;
-typedef struct line_index_assoc_data {
+typedef struct line_assoc_data {
/*@only@*/ void *data;
- /*@null@*/ void (*delete_func) (/*@only@*/ void *);
- int type;
-} line_index_assoc_data;
+ const yasm_assoc_data_callback *callback;
+} line_assoc_data;
-/* Shared storage for filenames */
-static /*@only@*/ /*@null@*/ HAMT *filename_table;
+struct yasm_linemap {
+ /* Shared storage for filenames */
+ /*@only@*/ /*@null@*/ HAMT *filenames;
-/* Virtual line number. Uniquely specifies every line read by the parser. */
-static unsigned long line_index;
-static /*@only@*/ /*@null@*/ line_index_mapping_head *line_index_map;
+ /* Current virtual line number. */
+ unsigned long current;
-/* Associated data arrays for odd data types (those likely to have data
- * associated for every line).
- */
-static line_index_assoc_data_raw_head *line_index_assoc_data_array;
-#define MAX_LINE_INDEX_ASSOC_DATA_ARRAY 8
+ /* Mappings from virtual to physical line numbers */
+ /*@only@*/ /*@null@*/ line_mapping_head *map;
+
+ /* Associated data arrays for odd data types (those likely to have data
+ * associated for every line).
+ */
+ /*@null@*/ /*@only@*/ line_assoc_data_raw_head *assoc_data_array;
+ size_t assoc_data_array_size;
+ size_t assoc_data_array_alloc;
+};
static void
filename_delete_one(/*@only@*/ void *d)
yasm_xfree(d);
}
-static void
-yasm_std_linemgr_set(const char *filename, unsigned long line,
- unsigned long line_inc)
+void
+yasm_linemap_set(yasm_linemap *linemap, const char *filename,
+ unsigned long file_line, unsigned long line_inc)
{
char *copy;
int replace = 0;
- line_index_mapping *mapping;
+ line_mapping *mapping;
/* Create a new mapping in the map */
- if (line_index_map->size >= line_index_map->allocated) {
+ if (linemap->map->size >= linemap->map->allocated) {
/* allocate another size bins when full for 2x space */
- line_index_map->vector =
- yasm_xrealloc(line_index_map->vector, 2*line_index_map->allocated
- *sizeof(line_index_mapping));
- line_index_map->allocated *= 2;
+ linemap->map->vector =
+ yasm_xrealloc(linemap->map->vector, 2*linemap->map->allocated
+ *sizeof(line_mapping));
+ linemap->map->allocated *= 2;
}
- mapping = &line_index_map->vector[line_index_map->size];
- line_index_map->size++;
+ mapping = &linemap->map->vector[linemap->map->size];
+ linemap->map->size++;
/* Fill it */
/* Copy the filename (via shared storage) */
copy = yasm__xstrdup(filename);
/*@-aliasunique@*/
- mapping->filename = HAMT_insert(filename_table, copy, copy, &replace,
+ mapping->filename = HAMT_insert(linemap->filenames, copy, copy, &replace,
filename_delete_one);
/*@=aliasunique@*/
- mapping->index = line_index;
- mapping->line = line;
+ mapping->line = linemap->current;
+ mapping->file_line = file_line;
mapping->line_inc = line_inc;
}
-static void
-yasm_std_linemgr_initialize(void)
+yasm_linemap *
+yasm_linemap_create(void)
{
- int i;
+ yasm_linemap *linemap = yasm_xmalloc(sizeof(yasm_linemap));
- filename_table = HAMT_new(yasm_internal_error_);
+ linemap->filenames = HAMT_create(yasm_internal_error_);
- line_index = 1;
+ linemap->current = 1;
/* initialize mapping vector */
- line_index_map = yasm_xmalloc(sizeof(line_index_mapping_head));
- line_index_map->vector = yasm_xmalloc(8*sizeof(line_index_mapping));
- line_index_map->size = 0;
- line_index_map->allocated = 8;
+ linemap->map = yasm_xmalloc(sizeof(line_mapping_head));
+ linemap->map->vector = yasm_xmalloc(8*sizeof(line_mapping));
+ linemap->map->size = 0;
+ linemap->map->allocated = 8;
/* initialize associated data arrays */
- line_index_assoc_data_array =
- yasm_xmalloc(MAX_LINE_INDEX_ASSOC_DATA_ARRAY *
- sizeof(line_index_assoc_data_raw_head));
- for (i=0; i<MAX_LINE_INDEX_ASSOC_DATA_ARRAY; i++) {
- line_index_assoc_data_array[i].vector = NULL;
- line_index_assoc_data_array[i].size = 0;
- }
+ linemap->assoc_data_array_size = 0;
+ linemap->assoc_data_array_alloc = 2;
+ linemap->assoc_data_array = yasm_xmalloc(linemap->assoc_data_array_alloc *
+ sizeof(line_assoc_data_raw_head));
+
+ return linemap;
}
-static void
-yasm_std_linemgr_cleanup(void)
+void
+yasm_linemap_destroy(yasm_linemap *linemap)
{
- if (line_index_assoc_data_array) {
- int i;
- for (i=0; i<MAX_LINE_INDEX_ASSOC_DATA_ARRAY; i++) {
- line_index_assoc_data_raw_head *adrh =
- &line_index_assoc_data_array[i];
- if (adrh->delete_func && adrh->vector) {
- unsigned int j;
+ if (linemap->assoc_data_array) {
+ size_t i;
+ for (i=0; i<linemap->assoc_data_array_size; i++) {
+ line_assoc_data_raw_head *adrh = &linemap->assoc_data_array[i];
+ if (adrh->vector) {
+ size_t j;
for (j=0; j<adrh->size; j++) {
if (adrh->vector[j])
- adrh->delete_func(adrh->vector[j]);
+ adrh->callback->destroy(adrh->vector[j]);
}
yasm_xfree(adrh->vector);
}
}
- yasm_xfree(line_index_assoc_data_array);
- line_index_assoc_data_array = NULL;
+ yasm_xfree(linemap->assoc_data_array);
}
- if (line_index_map) {
- yasm_xfree(line_index_map->vector);
- yasm_xfree(line_index_map);
- line_index_map = NULL;
+ if (linemap->map) {
+ yasm_xfree(linemap->map->vector);
+ yasm_xfree(linemap->map);
}
- if (filename_table) {
- HAMT_delete(filename_table, filename_delete_one);
- filename_table = NULL;
- }
+ if (linemap->filenames)
+ HAMT_destroy(linemap->filenames, filename_delete_one);
+
+ yasm_xfree(linemap);
}
-static unsigned long
-yasm_std_linemgr_get_current(void)
+unsigned long
+yasm_linemap_get_current(yasm_linemap *linemap)
{
- return line_index;
+ return linemap->current;
}
-static void
-yasm_std_linemgr_add_assoc_data(int type, /*@only@*/ void *data,
- /*@null@*/ void (*delete_func) (void *))
+void
+yasm_linemap_add_data(yasm_linemap *linemap,
+ const yasm_assoc_data_callback *callback, void *data,
+ /*@unused@*/ int every_hint)
{
- if ((type & 1) && type < MAX_LINE_INDEX_ASSOC_DATA_ARRAY*2) {
- line_index_assoc_data_raw_head *adrh =
- &line_index_assoc_data_array[type>>1];
-
- if (adrh->size == 0) {
- unsigned int i;
-
- adrh->size = 4;
- adrh->vector = yasm_xmalloc(adrh->size*sizeof(void *));
- adrh->delete_func = delete_func;
- for (i=0; i<adrh->size; i++)
- adrh->vector[i] = NULL;
- }
+ /* FIXME: Hint not supported yet. */
- while (line_index > adrh->size) {
- unsigned int i;
+ line_assoc_data_raw_head *adrh = NULL;
+ size_t i;
- /* allocate another size bins when full for 2x space */
- adrh->vector = yasm_xrealloc(adrh->vector,
- 2*adrh->size*sizeof(void *));
- for(i=adrh->size; i<adrh->size*2; i++)
- adrh->vector[i] = NULL;
- adrh->size *= 2;
+ /* See if there's already associated data for this callback */
+ for (i=0; !adrh && i<linemap->assoc_data_array_size; i++) {
+ if (linemap->assoc_data_array[i].callback == callback)
+ adrh = &linemap->assoc_data_array[i];
+ }
+
+ /* No? Then append a new one */
+ if (!adrh) {
+ linemap->assoc_data_array_size++;
+ if (linemap->assoc_data_array_size > linemap->assoc_data_array_alloc) {
+ linemap->assoc_data_array_alloc *= 2;
+ linemap->assoc_data_array =
+ yasm_xrealloc(linemap->assoc_data_array,
+ linemap->assoc_data_array_alloc *
+ sizeof(line_assoc_data_raw_head));
}
+ adrh = &linemap->assoc_data_array[linemap->assoc_data_array_size-1];
+
+ adrh->size = 4;
+ adrh->vector = yasm_xmalloc(adrh->size*sizeof(void *));
+ adrh->callback = callback;
+ for (i=0; i<adrh->size; i++)
+ adrh->vector[i] = NULL;
+ }
- adrh->vector[line_index-1] = data;
- if (adrh->delete_func != delete_func)
- yasm_internal_error(N_("multiple deletion functions specified"));
- } else {
- yasm_internal_error(N_("non-common data not supported yet"));
- delete_func(data);
+ while (linemap->current > adrh->size) {
+ /* allocate another size bins when full for 2x space */
+ adrh->vector = yasm_xrealloc(adrh->vector,
+ 2*adrh->size*sizeof(void *));
+ for (i=adrh->size; i<adrh->size*2; i++)
+ adrh->vector[i] = NULL;
+ adrh->size *= 2;
}
+
+ /* Delete existing data for that line (if any) */
+ if (adrh->vector[linemap->current-1])
+ adrh->callback->destroy(adrh->vector[linemap->current-1]);
+
+ adrh->vector[linemap->current-1] = data;
}
-static unsigned long
-yasm_std_linemgr_goto_next(void)
+unsigned long
+yasm_linemap_goto_next(yasm_linemap *linemap)
{
- return ++line_index;
+ return ++(linemap->current);
}
-static void
-yasm_std_linemgr_lookup(unsigned long lindex, const char **filename,
- unsigned long *line)
+void
+yasm_linemap_lookup(yasm_linemap *linemap, unsigned long line,
+ const char **filename, unsigned long *file_line)
{
- line_index_mapping *mapping;
+ line_mapping *mapping;
unsigned long vindex, step;
- assert(lindex <= line_index);
+ assert(line <= linemap->current);
/* Binary search through map to find highest line_index <= index */
- assert(line_index_map != NULL);
+ assert(linemap->map != NULL);
vindex = 0;
/* start step as the greatest power of 2 <= size */
step = 1;
- while (step*2<=line_index_map->size)
+ while (step*2<=linemap->map->size)
step*=2;
while (step>0) {
- if (vindex+step < line_index_map->size
- && line_index_map->vector[vindex+step].index <= lindex)
+ if (vindex+step < linemap->map->size
+ && linemap->map->vector[vindex+step].line <= line)
vindex += step;
step /= 2;
}
- mapping = &line_index_map->vector[vindex];
+ mapping = &linemap->map->vector[vindex];
*filename = mapping->filename;
- *line = mapping->line+mapping->line_inc*(lindex-mapping->index);
+ *file_line = mapping->file_line + mapping->line_inc*(line-mapping->line);
}
-static /*@dependent@*/ /*@null@*/ void *
-yasm_std_linemgr_lookup_data(unsigned long lindex, int type)
+void *
+yasm_linemap_get_data(yasm_linemap *linemap, unsigned long line,
+ const yasm_assoc_data_callback *callback)
{
- if ((type & 1) && type < MAX_LINE_INDEX_ASSOC_DATA_ARRAY*2) {
- line_index_assoc_data_raw_head *adrh =
- &line_index_assoc_data_array[type>>1];
-
- if (lindex > adrh->size)
- return NULL;
- return adrh->vector[lindex-1];
- } else
+ line_assoc_data_raw_head *adrh = NULL;
+ size_t i;
+
+ /* Linear search through data array */
+ for (i=0; !adrh && i<linemap->assoc_data_array_size; i++) {
+ if (linemap->assoc_data_array[i].callback == callback)
+ adrh = &linemap->assoc_data_array[i];
+ }
+
+ if (!adrh)
+ return NULL;
+
+ if (line > adrh->size)
return NULL;
-}
-yasm_linemgr yasm_std_linemgr = {
- yasm_std_linemgr_initialize,
- yasm_std_linemgr_cleanup,
- yasm_std_linemgr_get_current,
- yasm_std_linemgr_add_assoc_data,
- yasm_std_linemgr_goto_next,
- yasm_std_linemgr_set,
- yasm_std_linemgr_lookup,
- yasm_std_linemgr_lookup_data
-};
+ return adrh->vector[line-1];
+}
/* $IdPath$
- * YASM line manager (for parse stage) header file
+ * YASM virtual line mapping management functions
*
* Copyright (C) 2002 Peter Johnson
*
#ifndef YASM_LINEMGR_H
#define YASM_LINEMGR_H
-/* Standard data types appropriate for use with add_assoc_data(). */
-typedef enum yasm_linemgr_std_type {
- /* Source line, a 0-terminated, allocated string. */
- YASM_LINEMGR_STD_TYPE_SOURCE = 1,
- /* User-defined types start here. Use odd numbers (low bit set) for types
- * very likely to have data associated for every line.
- */
- YASM_LINEMGR_STD_TYPE_USER = 4
-} yasm_linemgr_std_type;
+/* Create a new line mapping repository. */
+yasm_linemap *yasm_linemap_create(void);
-struct yasm_linemgr {
- /* Initialize cur_lindex and any manager internal data structures. */
- void (*initialize) (void);
+/* Cleans up any memory allocated. */
+void yasm_linemap_destroy(yasm_linemap *linemap);
- /* Cleans up any memory allocated. */
- void (*cleanup) (void);
+/* Returns the current line index. */
+unsigned long yasm_linemap_get_current(yasm_linemap *linemap);
- /* Returns the current line index. */
- unsigned long (*get_current) (void);
-
- /* Associates data with the current line index.
- * Deletes old data associated with type if present.
- * The function delete_func is used to delete the data (if non-NULL).
- * All data of a particular type needs to have the exact same deletion
- * function specified to this function on every call.
- */
- void (*add_assoc_data) (int type, /*@only@*/ void *data,
- /*@null@*/ void (*delete_func) (void *));
-
- /* Goes to the next line (increments the current line index), returns
- * the current (new) line index.
- */
- unsigned long (*goto_next) (void);
-
- /* Sets a new file/line association starting point at the current line
- * index. line_inc indicates how much the "real" line is incremented by
- * for each line index increment (0 is perfectly legal).
- */
- void (*set) (const char *filename, unsigned long line,
- unsigned long line_inc);
+/** Get associated data for a virtual line and data callback.
+ * \param linemap linemap
+ * \param line virtual line
+ * \param callback callback used when adding data
+ * \return Associated data (NULL if none).
+ */
+/*@dependent@*/ /*@null@*/ void *yasm_linemap_get_data
+ (yasm_linemap *linemap, unsigned long line,
+ const yasm_assoc_data_callback *callback);
- /* Look up the associated actual file and line for a line index. */
- void (*lookup) (unsigned long lindex, /*@out@*/ const char **filename,
- /*@out@*/ unsigned long *line);
+/** Add associated data to the current virtual line.
+ * \attention Deletes any existing associated data for that data callback for
+ * the current virtual line.
+ * \param linemap linemap
+ * \param callback callback
+ * \param data data to associate
+ * \param every_hint non-zero if data is likely to be associated with every
+ * line; zero if not.
+ */
+void yasm_linemap_add_data(yasm_linemap *linemap,
+ const yasm_assoc_data_callback *callback,
+ /*@only@*/ /*@null@*/ void *data, int every_hint);
- /* Returns data associated with line index and type.
- * Returns NULL if no data of that type was associated with that line.
- */
- /*@dependent@*/ /*@null@*/ void * (*lookup_data) (unsigned long lindex,
- int type);
-};
+/* Goes to the next line (increments the current virtual line), returns
+ * the current (new) virtual line.
+ */
+unsigned long yasm_linemap_goto_next(yasm_linemap *linemap);
-extern yasm_linemgr yasm_std_linemgr;
+/* Sets a new file/line physical association starting point at the current
+ * virtual line. line_inc indicates how much the "real" line is incremented
+ * by for each virtual line increment (0 is perfectly legal).
+ */
+void yasm_linemap_set(yasm_linemap *linemap, const char *filename,
+ unsigned long file_line, unsigned long line_inc);
+/* Look up the associated physical file and line for a virtual line. */
+void yasm_linemap_lookup(yasm_linemap *linemap, unsigned long line,
+ /*@out@*/ const char **filename,
+ /*@out@*/ unsigned long *file_line);
#endif
--- /dev/null
+/*
+ * Object format interface
+ *
+ * Copyright (C) 2003 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
+#define YASM_ARCH_INTERNAL
+#include "util.h"
+/*@unused@*/ RCSID("$IdPath$");
+
+#include "coretype.h"
+#include "valparam.h"
+
+#include "objfmt.h"
+
+
+yasm_section *
+yasm_objfmt_add_default_section(yasm_objfmt *objfmt, yasm_object *object)
+{
+ yasm_section *retval;
+ yasm_valparamhead vps;
+ yasm_valparam *vp;
+
+ vp = yasm_vp_create(yasm__xstrdup(objfmt->default_section_name), NULL);
+ yasm_vps_initialize(&vps);
+ yasm_vps_append(&vps, vp);
+ retval = objfmt->section_switch(object, &vps, NULL, 0);
+ yasm_vps_delete(&vps);
+
+ return retval;
+}
* definitions match the module loader's function definitions. The version
* number must never be decreased.
*/
-#define YASM_OBJFMT_VERSION 0
+#define YASM_OBJFMT_VERSION 1
/** YASM object format interface. */
struct yasm_objfmt {
* \param obj_filename object filename (e.g. "file.o")
* \param df debug format in use
* \param a architecture in use
- * \param machine machine (of architecture) in use
* \return Nonzero if architecture/machine combination not supported.
*/
int (*initialize) (const char *in_filename, const char *obj_filename,
- yasm_dbgfmt *df, yasm_arch *a, const char *machine);
+ yasm_object *object, yasm_dbgfmt *df, yasm_arch *a);
/** Write out (post-optimized) sections to the object file.
* This function may call yasm_symrec_* functions as necessary (including
* yasm_symrec_traverse()) to retrieve symbolic information.
* \param f output object file
- * \param sections list of sections
+ * \param object object
* \param all_syms if nonzero, all symbols should be included in the
* object file
* \note The list of sections may include sections that will not actually
* be output into the object file.
*/
- void (*output) (FILE *f, yasm_sectionhead *sections, int all_syms);
+ void (*output) (FILE *f, yasm_object *object, int all_syms);
/** Cleans up anything allocated by initialize(). Function may be
* unimplemented (NULL) if not needed by the object format.
void (*cleanup) (void);
/** Switch object file sections. The first val of the valparams should
- * be the section name. Calls yasm_section_switch() to actually change
- * the active section.
- * \param headp list of sections
+ * be the section name. Calls yasm_object_get_general() to actually get
+ * the section.
+ * \param object object
* \param valparams value/parameters
* \param objext_valparams object format-specific value/parameters
- * \param lindex line index (as from yasm_linemgr)
+ * \param line virtual line (from yasm_linemap)
* \return NULL on error, otherwise new section.
*/
/*@observer@*/ /*@null@*/ yasm_section *
- (*sections_switch)(yasm_sectionhead *headp,
- yasm_valparamhead *valparams,
- /*@null@*/ yasm_valparamhead *objext_valparams,
- unsigned long lindex);
-
- /** Delete yasm_section object format-specific data. Function may be
- * unimplemented (NULL) if no data is ever allocated in sections_switch().
- * \param data object format-specific data
- */
- void (*section_data_delete)(/*@only@*/ void *data);
-
- /** Print yasm_section object format-specific data. For debugging
- * purposes. Function may be unimplemented (NULL) if no data is ever
- * allocated in sections_switch() by the object format.
- * \param f file
- * \param indent_level indentation level
- * \param data object format-specific data
- */
- void (*section_data_print)(FILE *f, int indent_level, void *data);
+ (*section_switch)(yasm_object *object, yasm_valparamhead *valparams,
+ /*@null@*/ yasm_valparamhead *objext_valparams,
+ unsigned long line);
/** Declare an "extern" (importing from another module) symbol. Should
* call yasm_symrec_set_of_data() to store data. Function may be
* declaration.
* \param sym symbol
* \param objext_valparams object format-specific value/paramaters
- * \param lindex line index (from yasm_linemgr)
+ * \param line virtual line (from yasm_linemap)
*/
void (*extern_declare)(yasm_symrec *sym,
/*@null@*/ yasm_valparamhead *objext_valparams,
- unsigned long lindex);
+ unsigned long line);
/** Declare a "global" (exporting to other modules) symbol. Should call
* yasm_symrec_set_of_data() to store data. Function may be unimplemented
* (NULL) if object format doesn't care about such a declaration.
* \param sym symbol
* \param objext_valparams object format-specific value/paramaters
- * \param lindex line index (from yasm_linemgr)
+ * \param line virtual line (from yasm_linemap)
*/
void (*global_declare)(yasm_symrec *sym,
/*@null@*/ yasm_valparamhead *objext_valparams,
- unsigned long lindex);
+ unsigned long line);
/** Declare a "common" (shared space with other modules) symbol. Should
* call yasm_symrec_set_of_data() to store data. Function may be
* \param sym symbol
* \param size common data size
* \param objext_valparams object format-specific value/paramaters
- * \param lindex line index (from yasm_linemgr)
+ * \param line virtual line (from yasm_linemap)
*/
void (*common_declare)(yasm_symrec *sym, /*@only@*/ yasm_expr *size,
/*@null@*/ yasm_valparamhead *objext_valparams,
- unsigned long lindex);
-
- /** Delete object format-specific symbol data. Function may be
- * unimplemented (NULL) if yasm_symrec_set_of_data() is never called by the
- * object format.
- * \param data object format-specific data
- */
- void (*symrec_data_delete)(/*@only@*/ void *data);
-
- /** Print object format-specific symbol data. For debugging purposes.
- * Function may be unimplemented (NULL) if yasm_symrec_set_of_data() is
- * never called by the object format.
- * \param f file
- * \param indent_level indentation level
- * \param data object format-specific data
- */
- void (*symrec_data_print)(FILE *f, int indent_level, void *data);
+ unsigned long line);
/** Handle object format-specific directives.
* \param name directive name
* \param valparams value/parameters
* \param objext_valparams object format-specific value/parameters
- * \param headp list of sections
- * \param lindex line index (as from yasm_linemgr)
+ * \param object object
+ * \param line virtual line (from yasm_linemap)
* \return Nonzero if directive was not recognized; 0 if directive was
* recognized, even if it wasn't valid.
*/
int (*directive)(const char *name, yasm_valparamhead *valparams,
/*@null@*/ yasm_valparamhead *objext_valparams,
- yasm_sectionhead *headp, unsigned long lindex);
-
- /** Delete object format-specific bytecode data (YASM_BC_OBJFMT_DATA).
- * Function may be unimplemented (NULL) if no YASM_BC_OBJFMT_DATA is ever
- * allocated by the object format.
- * \param type object format-specific bytecode type
- * \param data object format-specific data
- */
- void (*bc_objfmt_data_delete)(unsigned int type, /*@only@*/ void *data);
-
- /** Print object format-specific bytecode data (YASM_BC_OBJFMT_DATA). For
- * debugging purposes. Function may be unimplemented (NULL) if no
- * YASM_BC_OBJFMT_DATA is ever allocated by the object format.
- * \param f file
- * \param indent_level indentation level
- * \param type object format-specific bytecode type
- * \param data object format-specific data
- */
- void (*bc_objfmt_data_print)(FILE *f, int indent_level, unsigned int type,
- const void *data);
+ yasm_object *object, unsigned long line);
};
+
+/** Add a default section to an object.
+ * \param objfmt object format
+ * \param object object
+ * \return Default section.
+ */
+yasm_section *yasm_objfmt_add_default_section(yasm_objfmt *objfmt,
+ yasm_object *object);
#endif
* definitions match the module loader's function definitions. The version
* number must never be decreased.
*/
-#define YASM_OPTIMIZER_VERSION 0
+#define YASM_OPTIMIZER_VERSION 1
/* Interface to the optimizer module(s) */
struct yasm_optimizer {
* object file. (A failure is indicated by calling ErrorAt() from within
* this function).
*/
- void (*optimize) (yasm_sectionhead *sections);
+ void (*optimize) (yasm_object *object);
};
#endif
#ifndef YASM_PARSER_H
#define YASM_PARSER_H
-/** Version number of #yasm_parser interface. Any functional change to the
- * #yasm_parser interface should simultaneously increment this number. This
- * version should be checked by #yasm_parser loaders to verify that the
- * expected version (the version defined by its libyasm header files) matches
- * the loaded module version (the version defined by the module's libyasm
- * header files). Doing this will ensure that the module version's function
- * definitions match the module loader's function definitions. The version
- * number must never be decreased.
+/** Version number of #yasm_parser_module interface. Any functional change to
+ * the #yasm_parser_module interface should simultaneously increment this
+ * number. This version should be checked by #yasm_parser_module loaders to
+ * verify that the expected version (the version defined by its libyasm header
+ * files) matches the loaded module version (the version defined by the
+ * module's libyasm header files). Doing this will ensure that the module
+ * version's function definitions match the module loader's function
+ * definitions. The version number must never be decreased.
*/
-#define YASM_PARSER_VERSION 0
+#define YASM_PARSER_VERSION 1
/* Interface to the parser module(s) -- the "front end" of the assembler */
-struct yasm_parser {
+typedef struct yasm_parser_module {
/** Version (see #YASM_PARSER_VERSION). Should always be set to
* #YASM_PARSER_VERSION by the module source and checked against
* #YASM_PARSER_VERSION by the module loader.
* the input filename.
*
* save_input is nonzero if the parser needs to save the original lines of
- * source in the input file into the linemgr via linemgr->add_assoc_data().
- *
- * This function returns the starting section of a linked list of sections
- * (whatever was in the file).
+ * source in the input file into the linemap via yasm_linemap_add_data().
*/
- /*@only@*/ yasm_sectionhead *(*do_parse)
- (yasm_preproc *pp, yasm_arch *a, yasm_objfmt *of, yasm_linemgr *lm,
- FILE *f, const char *in_filename, int save_input);
-};
+ void (*do_parse) (yasm_object *object, yasm_preproc *pp, yasm_arch *a,
+ yasm_objfmt *of, FILE *f, const char *in_filename,
+ int save_input, yasm_section *def_sect);
+} yasm_parser_module;
#endif
* definitions match the module loader's function definitions. The version
* number must never be decreased.
*/
-#define YASM_PREPROC_VERSION 0
+#define YASM_PREPROC_VERSION 1
/* Interface to the preprocesor module(s) */
struct yasm_preproc {
* This function also takes the FILE * to the initial starting file and
* the filename.
*/
- void (*initialize) (FILE *f, const char *in_filename, yasm_linemgr *lm);
+ void (*initialize) (FILE *f, const char *in_filename, yasm_linemap *lm);
/* Cleans up any allocated memory. */
void (*cleanup) (void);
#include "coretype.h"
#include "valparam.h"
+#include "assocdat.h"
+#include "linemgr.h"
#include "errwarn.h"
#include "intnum.h"
#include "expr.h"
+#include "symrec.h"
#include "bytecode.h"
#include "section.h"
#include "objfmt.h"
+#include "bc-int.h"
+
+
+struct yasm_object {
+ yasm_symtab *symtab;
+ yasm_linemap *linemap;
+
+ /*@reldef@*/ STAILQ_HEAD(yasm_sectionhead, yasm_section) sections;
+};
struct yasm_section {
/*@reldef@*/ STAILQ_ENTRY(yasm_section) link;
+ /*@dependent@*/ yasm_object *object; /* Pointer to parent object */
+
enum { SECTION_GENERAL, SECTION_ABSOLUTE } type;
union {
/* SECTION_GENERAL data */
struct general {
/*@owned@*/ char *name; /* strdup()'ed name (given by user) */
-
- /* object-format-specific data */
- /*@null@*/ /*@dependent@*/ yasm_objfmt *of;
- /*@null@*/ /*@owned@*/ void *of_data;
} general;
} data;
+ /* associated data; NULL if none */
+ /*@null@*/ /*@only@*/ yasm__assoc_data *assoc_data;
+
/*@owned@*/ yasm_expr *start; /* Starting address of section contents */
unsigned long opt_flags; /* storage for optimizer flags */
int res_only; /* allow only resb family of bytecodes? */
/* the bytecodes for the section's contents */
- /*@only@*/ yasm_bytecodehead *bc;
+ /*@reldef@*/ STAILQ_HEAD(yasm_bytecodehead, yasm_bytecode) bcs;
};
-/*@reldef@*/ STAILQ_HEAD(yasm_sectionhead, yasm_section);
+static void yasm_section_destroy(/*@only@*/ yasm_section *sect);
-static void yasm_section_delete(/*@only@*/ yasm_section *sect);
/*@-compdestroy@*/
-yasm_sectionhead *
-yasm_sections_new(yasm_section **def, yasm_objfmt *of)
+yasm_object *
+yasm_object_create(void)
{
- yasm_sectionhead *headp;
- yasm_valparamhead vps;
- yasm_valparam *vp;
-
- /* Initialize linked list */
- headp = yasm_xmalloc(sizeof(yasm_sectionhead));
- STAILQ_INIT(headp);
-
- /* Add an initial "default" section */
- vp = yasm_vp_new(yasm__xstrdup(of->default_section_name), NULL);
- yasm_vps_initialize(&vps);
- yasm_vps_append(&vps, vp);
- *def = of->sections_switch(headp, &vps, NULL, 0);
- yasm_vps_delete(&vps);
-
- return headp;
+ yasm_object *object = yasm_xmalloc(sizeof(yasm_object));
+
+ /* Create empty symtab and linemap */
+ object->symtab = yasm_symtab_create();
+ object->linemap = yasm_linemap_create();
+
+ /* Initialize sections linked list */
+ STAILQ_INIT(&object->sections);
+
+ return object;
}
/*@=compdestroy@*/
/*@-onlytrans@*/
yasm_section *
-yasm_sections_switch_general(yasm_sectionhead *headp, const char *name,
- yasm_expr *start, int res_only, int *isnew,
- unsigned long lindex)
+yasm_object_get_general(yasm_object *object, const char *name,
+ yasm_expr *start, int res_only, int *isnew,
+ unsigned long line)
{
yasm_section *s;
+ yasm_bytecode *bc;
/* Search through current sections to see if we already have one with
* that name.
*/
- STAILQ_FOREACH(s, headp, link) {
+ STAILQ_FOREACH(s, &object->sections, link) {
if (s->type == SECTION_GENERAL &&
strcmp(s->data.general.name, name) == 0) {
*isnew = 0;
/* Okay, the name is valid; now allocate and initialize */
s = yasm_xcalloc(1, sizeof(yasm_section));
- STAILQ_INSERT_TAIL(headp, s, link);
+ STAILQ_INSERT_TAIL(&object->sections, s, link);
+ s->object = object;
s->type = SECTION_GENERAL;
s->data.general.name = yasm__xstrdup(name);
- s->data.general.of = NULL;
- s->data.general.of_data = NULL;
+ s->assoc_data = NULL;
if (start)
s->start = start;
else
- s->start = yasm_expr_new_ident(yasm_expr_int(yasm_intnum_new_uint(0)),
- lindex);
- s->bc = yasm_bcs_new();
+ s->start =
+ yasm_expr_create_ident(yasm_expr_int(yasm_intnum_create_uint(0)),
+ line);
+
+ /* Initialize bytecodes with one empty bytecode (acts as "prior" for first
+ * real bytecode in section.
+ */
+ STAILQ_INIT(&s->bcs);
+ bc = yasm_bc_create_common(NULL, sizeof(yasm_bytecode), 0);
+ bc->section = s;
+ STAILQ_INSERT_TAIL(&s->bcs, bc, link);
- s->opt_flags = 0;
s->res_only = res_only;
*isnew = 1;
/*@-onlytrans@*/
yasm_section *
-yasm_sections_switch_absolute(yasm_sectionhead *headp, yasm_expr *start)
+yasm_object_create_absolute(yasm_object *object, yasm_expr *start,
+ unsigned long line)
{
yasm_section *s;
+ yasm_bytecode *bc;
s = yasm_xcalloc(1, sizeof(yasm_section));
- STAILQ_INSERT_TAIL(headp, s, link);
+ STAILQ_INSERT_TAIL(&object->sections, s, link);
+ s->object = object;
s->type = SECTION_ABSOLUTE;
s->start = start;
- s->bc = yasm_bcs_new();
- s->opt_flags = 0;
+ /* Initialize bytecodes with one empty bytecode (acts as "prior" for first
+ * real bytecode in section.
+ */
+ STAILQ_INIT(&s->bcs);
+ bc = yasm_bc_create_common(NULL, sizeof(yasm_bytecode), 0);
+ bc->section = s;
+ STAILQ_INSERT_TAIL(&s->bcs, bc, link);
+
s->res_only = 1;
return s;
}
/*@=onlytrans@*/
+yasm_symtab *
+yasm_object_get_symtab(const yasm_object *object)
+{
+ return object->symtab;
+}
+
+yasm_linemap *
+yasm_object_get_linemap(const yasm_object *object)
+{
+ return object->linemap;
+}
+
int
yasm_section_is_absolute(yasm_section *sect)
{
sect->opt_flags = opt_flags;
}
-void
-yasm_section_set_of_data(yasm_section *sect, yasm_objfmt *of, void *of_data)
+yasm_object *
+yasm_section_get_object(const yasm_section *sect)
{
- /* Check to see if section type supports of_data */
- if (sect->type != SECTION_GENERAL) {
- if (of->section_data_delete)
- of->section_data_delete(of_data);
- else
- yasm_internal_error(
- N_("don't know how to delete objfmt-specific section data"));
- return;
- }
-
- /* Delete current of_data if present */
- if (sect->data.general.of_data && sect->data.general.of) {
- yasm_objfmt *of2 = sect->data.general.of;
- if (of2->section_data_delete)
- of2->section_data_delete(sect->data.general.of_data);
- else
- yasm_internal_error(
- N_("don't know how to delete objfmt-specific section data"));
- }
-
- /* Assign new of_data */
- sect->data.general.of = of;
- sect->data.general.of_data = of_data;
+ return sect->object;
}
void *
-yasm_section_get_of_data(yasm_section *sect)
+yasm_section_get_data(yasm_section *sect,
+ const yasm_assoc_data_callback *callback)
{
- if (sect->type == SECTION_GENERAL)
- return sect->data.general.of_data;
- else
- return NULL;
+ return yasm__assoc_data_get(sect->assoc_data, callback);
+}
+
+void
+yasm_section_add_data(yasm_section *sect,
+ const yasm_assoc_data_callback *callback, void *data)
+{
+ sect->assoc_data = yasm__assoc_data_add(sect->assoc_data, callback, data);
}
void
-yasm_sections_delete(yasm_sectionhead *headp)
+yasm_object_destroy(yasm_object *object)
{
yasm_section *cur, *next;
- cur = STAILQ_FIRST(headp);
+ /* Delete sections */
+ cur = STAILQ_FIRST(&object->sections);
while (cur) {
next = STAILQ_NEXT(cur, link);
- yasm_section_delete(cur);
+ yasm_section_destroy(cur);
cur = next;
}
- STAILQ_INIT(headp);
- yasm_xfree(headp);
+
+ /* Delete symbol table and line mappings */
+ yasm_symtab_destroy(object->symtab);
+ yasm_linemap_destroy(object->linemap);
+
+ yasm_xfree(object);
}
void
-yasm_sections_print(FILE *f, int indent_level, const yasm_sectionhead *headp)
+yasm_object_print(const yasm_object *object, FILE *f, int indent_level)
{
yasm_section *cur;
-
- STAILQ_FOREACH(cur, headp, link) {
+
+ /* Print symbol table */
+ fprintf(f, "%*sSymbol Table:\n", indent_level, "");
+ yasm_symtab_print(object->symtab, f, indent_level+1);
+
+ /* Print sections and bytecodes */
+ STAILQ_FOREACH(cur, &object->sections, link) {
fprintf(f, "%*sSection:\n", indent_level, "");
- yasm_section_print(f, indent_level+1, cur, 1);
+ yasm_section_print(cur, f, indent_level+1, 1);
}
}
int
-yasm_sections_traverse(yasm_sectionhead *headp, /*@null@*/ void *d,
- int (*func) (yasm_section *sect, /*@null@*/ void *d))
+yasm_object_sections_traverse(yasm_object *object, /*@null@*/ void *d,
+ int (*func) (yasm_section *sect,
+ /*@null@*/ void *d))
{
yasm_section *cur;
-
- STAILQ_FOREACH(cur, headp, link) {
+
+ STAILQ_FOREACH(cur, &object->sections, link) {
int retval = func(cur, d);
if (retval != 0)
return retval;
/*@-onlytrans@*/
yasm_section *
-yasm_sections_find_general(yasm_sectionhead *headp, const char *name)
+yasm_object_find_general(yasm_object *object, const char *name)
{
yasm_section *cur;
- STAILQ_FOREACH(cur, headp, link) {
+ STAILQ_FOREACH(cur, &object->sections, link) {
if (cur->type == SECTION_GENERAL &&
strcmp(cur->data.general.name, name) == 0)
return cur;
}
/*@=onlytrans@*/
-yasm_bytecodehead *
-yasm_section_get_bytecodes(yasm_section *sect)
+yasm_bytecode *
+yasm_section_bcs_first(yasm_section *sect)
+{
+ return STAILQ_FIRST(§->bcs);
+}
+
+yasm_bytecode *
+yasm_section_bcs_last(yasm_section *sect)
{
- return sect->bc;
+ return STAILQ_LAST(§->bcs, yasm_bytecode, link);
+}
+
+yasm_bytecode *
+yasm_section_bcs_append(yasm_section *sect, yasm_bytecode *bc)
+{
+ if (bc) {
+ if (bc->callback) {
+ bc->section = sect; /* record parent section */
+ STAILQ_INSERT_TAIL(§->bcs, bc, link);
+ return bc;
+ } else
+ yasm_xfree(bc);
+ }
+ return (yasm_bytecode *)NULL;
+}
+
+int
+yasm_section_bcs_traverse(yasm_section *sect, void *d,
+ int (*func) (yasm_bytecode *bc, /*@null@*/ void *d))
+{
+ yasm_bytecode *cur = STAILQ_FIRST(§->bcs);
+
+ /* Skip our locally created empty bytecode first. */
+ cur = STAILQ_NEXT(cur, link);
+
+ /* Iterate through the remainder, if any. */
+ while (cur) {
+ int retval = func(cur, d);
+ if (retval != 0)
+ return retval;
+ cur = STAILQ_NEXT(cur, link);
+ }
+ return 0;
}
const char *
void
yasm_section_set_start(yasm_section *sect, yasm_expr *start,
- unsigned long lindex)
+ unsigned long line)
{
- yasm_expr_delete(sect->start);
+ yasm_expr_destroy(sect->start);
sect->start = start;
}
}
static void
-yasm_section_delete(yasm_section *sect)
+yasm_section_destroy(yasm_section *sect)
{
+ yasm_bytecode *cur, *next;
+
if (!sect)
return;
if (sect->type == SECTION_GENERAL) {
yasm_xfree(sect->data.general.name);
- if (sect->data.general.of_data && sect->data.general.of) {
- yasm_objfmt *of = sect->data.general.of;
- if (of->section_data_delete)
- of->section_data_delete(sect->data.general.of_data);
- else
- yasm_internal_error(
- N_("don't know how to delete objfmt-specific section data"));
- }
}
- yasm_expr_delete(sect->start);
- yasm_bcs_delete(sect->bc);
+ yasm__assoc_data_destroy(sect->assoc_data);
+ yasm_expr_destroy(sect->start);
+
+ /* Delete bytecodes */
+ cur = STAILQ_FIRST(§->bcs);
+ while (cur) {
+ next = STAILQ_NEXT(cur, link);
+ yasm_bc_destroy(cur);
+ cur = next;
+ }
+
yasm_xfree(sect);
}
void
-yasm_section_print(FILE *f, int indent_level, const yasm_section *sect,
+yasm_section_print(const yasm_section *sect, FILE *f, int indent_level,
int print_bcs)
{
if (!sect) {
fprintf(f, "%*stype=", indent_level, "");
switch (sect->type) {
case SECTION_GENERAL:
- fprintf(f, "general\n%*sname=%s\n%*sobjfmt data:\n", indent_level,
- "", sect->data.general.name, indent_level, "");
- indent_level++;
- if (sect->data.general.of_data && sect->data.general.of) {
- yasm_objfmt *of = sect->data.general.of;
- if (of->section_data_print)
- of->section_data_print(f, indent_level,
- sect->data.general.of_data);
- else
- fprintf(f, "%*sUNKNOWN\n", indent_level, "");
- } else
- fprintf(f, "%*s(none)\n", indent_level, "");
- indent_level--;
+ fprintf(f, "general\n%*sname=%s\n", indent_level, "",
+ sect->data.general.name, indent_level, "");
break;
case SECTION_ABSOLUTE:
fprintf(f, "absolute\n");
}
fprintf(f, "%*sstart=", indent_level, "");
- yasm_expr_print(f, sect->start);
+ yasm_expr_print(sect->start, f);
fprintf(f, "\n");
+ if (sect->assoc_data) {
+ fprintf(f, "%*sAssociated data:\n", indent_level, "");
+ yasm__assoc_data_print(sect->assoc_data, f, indent_level+1);
+ }
+
if (print_bcs) {
+ yasm_bytecode *cur;
+
fprintf(f, "%*sBytecodes:\n", indent_level, "");
- yasm_bcs_print(f, indent_level+1, sect->bc);
+
+ STAILQ_FOREACH(cur, §->bcs, link) {
+ fprintf(f, "%*sNext Bytecode:\n", indent_level+1, "");
+ yasm_bc_print(cur, f, indent_level+2);
+ }
}
}
#ifndef YASM_SECTION_H
#define YASM_SECTION_H
-/** Create a new section list. A default section is created as the
- * first section.
- * \param def returned; default section
- * \param of object format in use
- * \return Newly allocated section list.
+/** Create a new object. A default section is created as the first section.
+ * An empty symbol table (yasm_symtab) and line mapping (yasm_linemap) are
+ * automatically created.
+ * \return Newly allocated object.
*/
-/*@only@*/ yasm_sectionhead *yasm_sections_new
- (/*@out@*/ /*@dependent@*/ yasm_section **def, yasm_objfmt *of);
+/*@only@*/ yasm_object *yasm_object_create(void);
/** Create a new, or continue an existing, general section. The section is
- * added to a section list if there's not already a section by that name.
- * \param headp section list
+ * added to the object if there's not already a section by that name.
+ * \param object object
* \param name section name
* \param start starting address (ignored if section already exists),
* NULL if 0 or don't care.
* \param res_only if nonzero, only space-reserving bytecodes are allowed in
* the section (ignored if section already exists)
* \param isnew output; set to nonzero if section did not already exist
- * \param lindex line index of section declaration (ignored if section
+ * \param line virtual line of section declaration (ignored if section
* already exists)
* \return New section.
*/
-/*@dependent@*/ yasm_section *yasm_sections_switch_general
- (yasm_sectionhead *headp, const char *name,
+/*@dependent@*/ yasm_section *yasm_object_get_general
+ (yasm_object *object, const char *name,
/*@null@*/ /*@only@*/ yasm_expr *start, int res_only,
- /*@out@*/ int *isnew, unsigned long lindex);
+ /*@out@*/ int *isnew, unsigned long line);
/** Create a new absolute section. No checking is performed at creation to
* check for overlaps with other absolute sections.
- * \param headp section list
+ * \param object object
* \param start starting address (expression)
+ * \param line virtual line of section declaration
* \return New section.
*/
-/*@dependent@*/ yasm_section *yasm_sections_switch_absolute
- (yasm_sectionhead *headp, /*@keep@*/ yasm_expr *start);
+/*@dependent@*/ yasm_section *yasm_object_create_absolute
+ (yasm_object *object, /*@keep@*/ yasm_expr *start, unsigned long line);
+
+/** Delete (free allocated memory for) an object. All sections in the
+ * object and all bytecodes within those sections are also deleted.
+ * \param object object
+ */
+void yasm_object_destroy(/*@only@*/ yasm_object *object);
+
+/** Print an object. For debugging purposes.
+ * \param object object
+ * \param f file
+ * \param indent_level indentation level
+ */
+void yasm_object_print(const yasm_object *object, FILE *f, int indent_level);
+
+/** Traverses all sections in an object, calling a function on each section.
+ * \param object object
+ * \param d data pointer passed to func on each call
+ * \param func function
+ * \return Stops early (and returns func's return value) if func returns a
+ * nonzero value; otherwise 0.
+ */
+int yasm_object_sections_traverse
+ (yasm_object *object, /*@null@*/ void *d,
+ int (*func) (yasm_section *sect, /*@null@*/ void *d));
+
+/** Find a general section in an object, based on its name.
+ * \param object object
+ * \param name section name
+ * \return Section matching name, or NULL if no match found.
+ */
+/*@dependent@*/ /*@null@*/ yasm_section *yasm_object_find_general
+ (yasm_object *object, const char *name);
+
+/** Get an object's symbol table (#yasm_symtab).
+ * \param object object
+ * \return Symbol table.
+ */
+/*@dependent@*/ yasm_symtab *yasm_object_get_symtab(const yasm_object *object);
+
+/** Get an object's line mappings (#yasm_linemap).
+ * \param object object
+ * \return Line mappings.
+ */
+/*@dependent@*/ yasm_linemap *yasm_object_get_linemap
+ (const yasm_object *object);
/** Determine if a section is absolute or general.
* \param sect section
*/
void yasm_section_set_opt_flags(yasm_section *sect, unsigned long opt_flags);
-/** Get yasm_objfmt-specific data. For yasm_objfmt use only.
+/** Get object owner of a section.
* \param sect section
- * \return Object format-specific data.
+ * \return Object this section is a part of.
*/
-/*@dependent@*/ /*@null@*/ void *yasm_section_get_of_data(yasm_section *sect);
+yasm_object *yasm_section_get_object(const yasm_section *sect);
-/** Set yasm_objfmt-specific data. For yasm_objfmt use only.
- * \attention Deletes any existing of_data.
+/** Get assocated data for a section and data callback.
* \param sect section
- * \param of object format
- * \param of_data object format-specific data.
+ * \param callback callback used when adding data
+ * \return Associated data (NULL if none).
*/
-void yasm_section_set_of_data(yasm_section *sect, yasm_objfmt *of,
- /*@null@*/ /*@only@*/ void *of_data);
+/*@dependent@*/ /*@null@*/ void *yasm_section_get_data
+ (yasm_section *sect, const yasm_assoc_data_callback *callback);
-/** Delete (free allocated memory for) a section list. All sections in the
- * section list and all bytecodes within those sections are also deleted.
- * \param headp section list
+/** Add associated data to a section.
+ * \attention Deletes any existing associated data for that data callback.
+ * \param sect section
+ * \param callback callback
+ * \param data data to associate
*/
-void yasm_sections_delete(/*@only@*/ yasm_sectionhead *headp);
+void yasm_section_add_data(yasm_section *sect,
+ const yasm_assoc_data_callback *callback,
+ /*@null@*/ /*@only@*/ void *data);
-/** Print a section list. For debugging purposes.
- * \param f file
- * \param indent_level indentation level
- * \param headp section list
+/** Get the first bytecode in a section.
+ * \param sect section
+ * \return First bytecode in section (at least one empty bytecode is always
+ * present).
*/
-void yasm_sections_print(FILE *f, int indent_level,
- const yasm_sectionhead *headp);
+yasm_bytecode *yasm_section_bcs_first(yasm_section *sect);
-/** Traverses a section list, calling a function on each bytecode.
- * \param headp bytecode list
- * \param d data pointer passed to func on each call
- * \param func function
- * \return Stops early (and returns func's return value) if func returns a
- * nonzero value; otherwise 0.
+/** Get the last bytecode in a section.
+ * \param sect section
+ * \return Last bytecode in section (at least one empty bytecode is always
+ * present).
*/
-int yasm_sections_traverse(yasm_sectionhead *headp, /*@null@*/ void *d,
- int (*func) (yasm_section *sect,
- /*@null@*/ void *d));
+yasm_bytecode *yasm_section_bcs_last(yasm_section *sect);
-/** Find a section based on its name.
- * \param headp section list
- * \param name section name
- * \return Section matching name, or NULL if no match found.
+/** Add bytecode to the end of a section.
+ * \note Does not make a copy of bc; so don't pass this function static or
+ * local variables, and discard the bc pointer after calling this
+ * function.
+ * \param sect section
+ * \param bc bytecode (may be NULL)
+ * \return If bytecode was actually appended (it wasn't NULL or empty), the
+ * bytecode; otherwise NULL.
*/
-/*@dependent@*/ /*@null@*/ yasm_section *yasm_sections_find_general
- (yasm_sectionhead *headp, const char *name);
+/*@only@*/ /*@null@*/ yasm_bytecode *yasm_section_bcs_append
+ (yasm_section *sect,
+ /*@returned@*/ /*@only@*/ /*@null@*/ yasm_bytecode *bc);
-/** Get bytecode list of a section.
- * \param sect section
- * \return Bytecode list.
+/** Traverses all bytecodes in a section, calling a function on each bytecode.
+ * \param sect section
+ * \param d data pointer passed to func on each call
+ * \param func function
+ * \return Stops early (and returns func's return value) if func returns a
+ * nonzero value; otherwise 0.
*/
-/*@dependent@*/ yasm_bytecodehead *yasm_section_get_bytecodes
- (yasm_section *sect);
+int yasm_section_bcs_traverse
+ (yasm_section *sect, /*@null@*/ void *d,
+ int (*func) (yasm_bytecode *bc, /*@null@*/ void *d));
/** Get name of a section.
* \param sect section
/** Change starting address of a section.
* \param sect section
* \param start starting address
- * \param lindex line index
+ * \param line virtual line
*/
void yasm_section_set_start(yasm_section *sect, /*@only@*/ yasm_expr *start,
- unsigned long lindex);
+ unsigned long line);
/** Get starting address of a section.
* \param sect section
* \param sect section
* \param print_bcs if nonzero, print bytecodes within section
*/
-void yasm_section_print(FILE *f, int indent_level,
- /*@null@*/ const yasm_section *sect, int print_bcs);
+void yasm_section_print(/*@null@*/ const yasm_section *sect, FILE *f,
+ int indent_level, int print_bcs);
+
#endif
*/
#define YASM_LIB_INTERNAL
#include "util.h"
-/*@unused@*/ RCSID("$IdPath: yasm/libyasm/symrec.c,v 1.60 2003/03/15 05:07:48 peter Exp $");
+/*@unused@*/ RCSID("$IdPath$");
#ifdef STDC_HEADERS
# include <limits.h>
#include "coretype.h"
#include "hamt.h"
+#include "assocdat.h"
#include "errwarn.h"
#include "floatnum.h"
unsigned long line; /* symbol was first declared or used on */
union {
yasm_expr *expn; /* equ value */
- struct label_s { /* bytecode immediately preceding a label */
- /*@dependent@*/ /*@null@*/ yasm_section *sect;
- /*@dependent@*/ /*@null@*/ yasm_bytecode *bc;
- } label;
- } value;
- /* objfmt-specific data */
- /*@null@*/ /*@dependent@*/ yasm_objfmt *of;
- /*@null@*/ /*@owned@*/ void *of_data;
+ /* bytecode immediately preceding a label */
+ /*@dependent@*/ yasm_bytecode *precbc;
+ } value;
- /* storage for optimizer flags */
- unsigned long opt_flags;
+ /* associated data; NULL if none */
+ /*@null@*/ /*@only@*/ yasm__assoc_data *assoc_data;
};
-/* The symbol table: a hash array mapped trie (HAMT). */
-static /*@only@*/ HAMT *sym_table;
-
/* Linked list of symbols not in the symbol table. */
typedef struct non_table_symrec_s {
/*@reldef@*/ SLIST_ENTRY(non_table_symrec_s) link;
/*@owned@*/ yasm_symrec *rec;
} non_table_symrec;
-typedef /*@reldef@*/ SLIST_HEAD(nontablesymhead_s, non_table_symrec_s)
- nontablesymhead;
-static /*@only@*/ nontablesymhead *non_table_syms;
+struct yasm_symtab {
+ /* The symbol table: a hash array mapped trie (HAMT). */
+ /*@only@*/ HAMT *sym_table;
+ /* Symbols not in the table */
+ SLIST_HEAD(nontablesymhead_s, non_table_symrec_s) non_table_syms;
+};
-void
-yasm_symrec_initialize(void)
+
+yasm_symtab *
+yasm_symtab_create(void)
{
- sym_table = HAMT_new(yasm_internal_error_);
- non_table_syms = yasm_xmalloc(sizeof(nontablesymhead));
- SLIST_INIT(non_table_syms);
+ yasm_symtab *symtab = yasm_xmalloc(sizeof(yasm_symtab));
+ symtab->sym_table = HAMT_create(yasm_internal_error_);
+ SLIST_INIT(&symtab->non_table_syms);
+ return symtab;
}
static void
-symrec_delete_one(/*@only@*/ void *d)
+symrec_destroy_one(/*@only@*/ void *d)
{
yasm_symrec *sym = d;
yasm_xfree(sym->name);
if (sym->type == SYM_EQU)
- yasm_expr_delete(sym->value.expn);
- if (sym->of_data && sym->of) {
- if (sym->of->symrec_data_delete)
- sym->of->symrec_data_delete(sym->of_data);
- else
- yasm_internal_error(
- N_("don't know how to delete objfmt-specific data"));
- }
+ yasm_expr_destroy(sym->value.expn);
+ yasm__assoc_data_destroy(sym->assoc_data);
yasm_xfree(sym);
}
rec->type = SYM_UNKNOWN;
rec->line = 0;
rec->visibility = YASM_SYM_LOCAL;
- rec->of = NULL;
- rec->of_data = NULL;
- rec->opt_flags = 0;
+ rec->assoc_data = NULL;
return rec;
}
static /*@partial@*/ /*@dependent@*/ yasm_symrec *
-symrec_get_or_new_in_table(/*@only@*/ char *name)
+symtab_get_or_new_in_table(yasm_symtab *symtab, /*@only@*/ char *name)
{
yasm_symrec *rec = symrec_new_common(name);
int replace = 0;
rec->status = SYM_NOSTATUS;
- return HAMT_insert(sym_table, name, rec, &replace, symrec_delete_one);
+ return HAMT_insert(symtab->sym_table, name, rec, &replace,
+ symrec_destroy_one);
}
static /*@partial@*/ /*@dependent@*/ yasm_symrec *
-symrec_get_or_new_not_in_table(/*@only@*/ char *name)
+symtab_get_or_new_not_in_table(yasm_symtab *symtab, /*@only@*/ char *name)
{
non_table_symrec *sym = yasm_xmalloc(sizeof(non_table_symrec));
sym->rec = symrec_new_common(name);
sym->rec->status = SYM_NOTINTABLE;
- SLIST_INSERT_HEAD(non_table_syms, sym, link);
+ SLIST_INSERT_HEAD(&symtab->non_table_syms, sym, link);
return sym->rec;
}
/* create a new symrec */
/*@-freshtrans -mustfree@*/
static /*@partial@*/ /*@dependent@*/ yasm_symrec *
-symrec_get_or_new(const char *name, int in_table)
+symtab_get_or_new(yasm_symtab *symtab, const char *name, int in_table)
{
char *symname = yasm__xstrdup(name);
if (in_table)
- return symrec_get_or_new_in_table(symname);
+ return symtab_get_or_new_in_table(symtab, symname);
else
- return symrec_get_or_new_not_in_table(symname);
+ return symtab_get_or_new_not_in_table(symtab, symname);
}
/*@=freshtrans =mustfree@*/
/* Call a function with each symrec. Stops early if 0 returned by func.
Returns 0 if stopped early. */
int
-yasm_symrec_traverse(void *d, int (*func) (yasm_symrec *sym, void *d))
+yasm_symtab_traverse(yasm_symtab *symtab, void *d,
+ int (*func) (yasm_symrec *sym, void *d))
{
- return HAMT_traverse(sym_table, d, (int (*) (void *, void *))func);
+ return HAMT_traverse(symtab->sym_table, d, (int (*) (void *, void *))func);
}
yasm_symrec *
-yasm_symrec_use(const char *name, unsigned long lindex)
+yasm_symtab_use(yasm_symtab *symtab, const char *name, unsigned long line)
{
- yasm_symrec *rec = symrec_get_or_new(name, 1);
+ yasm_symrec *rec = symtab_get_or_new(symtab, name, 1);
if (rec->line == 0)
- rec->line = lindex; /* set line number of first use */
+ rec->line = line; /* set line number of first use */
rec->status |= SYM_USED;
return rec;
}
static /*@dependent@*/ yasm_symrec *
-symrec_define(const char *name, sym_type type, int in_table,
- unsigned long lindex)
+symtab_define(yasm_symtab *symtab, const char *name, sym_type type,
+ int in_table, unsigned long line)
{
- yasm_symrec *rec = symrec_get_or_new(name, in_table);
+ yasm_symrec *rec = symtab_get_or_new(symtab, name, in_table);
/* Has it been defined before (either by DEFINED or COMMON/EXTERN)? */
if ((rec->status & SYM_DEFINED) ||
(rec->visibility & (YASM_SYM_COMMON | YASM_SYM_EXTERN))) {
- yasm__error(lindex,
+ yasm__error(line,
N_("duplicate definition of `%s'; first defined on line %lu"),
name, rec->line);
} else {
- rec->line = lindex; /* set line number of definition */
+ rec->line = line; /* set line number of definition */
rec->type = type;
rec->status |= SYM_DEFINED;
}
}
yasm_symrec *
-yasm_symrec_define_equ(const char *name, yasm_expr *e, unsigned long lindex)
+yasm_symtab_define_equ(yasm_symtab *symtab, const char *name, yasm_expr *e,
+ unsigned long line)
{
- yasm_symrec *rec = symrec_define(name, SYM_EQU, 1, lindex);
+ yasm_symrec *rec = symtab_define(symtab, name, SYM_EQU, 1, line);
rec->value.expn = e;
rec->status |= SYM_VALUED;
return rec;
}
yasm_symrec *
-yasm_symrec_define_label(const char *name, yasm_section *sect,
+yasm_symtab_define_label(yasm_symtab *symtab, const char *name,
yasm_bytecode *precbc, int in_table,
- unsigned long lindex)
+ unsigned long line)
{
- yasm_symrec *rec = symrec_define(name, SYM_LABEL, in_table, lindex);
- rec->value.label.sect = sect;
- rec->value.label.bc = precbc;
+ yasm_symrec *rec;
+ rec = symtab_define(symtab, name, SYM_LABEL, in_table, line);
+ rec->value.precbc = precbc;
return rec;
}
yasm_symrec *
-yasm_symrec_declare(const char *name, yasm_sym_vis vis, unsigned long lindex)
+yasm_symtab_define_label2(const char *name, yasm_bytecode *precbc,
+ int in_table, unsigned long line)
{
- yasm_symrec *rec = symrec_get_or_new(name, 1);
+ return yasm_symtab_define_label(yasm_object_get_symtab(
+ yasm_section_get_object(yasm_bc_get_section(precbc))), name, precbc,
+ in_table, line);
+}
+
+yasm_symrec *
+yasm_symtab_declare(yasm_symtab *symtab, const char *name, yasm_sym_vis vis,
+ unsigned long line)
+{
+ yasm_symrec *rec = symtab_get_or_new(symtab, name, 1);
/* Allowable combinations:
* Existing State-------------- vis New State-------------------
((rec->visibility & YASM_SYM_EXTERN) && (vis == YASM_SYM_EXTERN)))))
rec->visibility |= vis;
else
- yasm__error(lindex,
+ yasm__error(line,
N_("duplicate definition of `%s'; first defined on line %lu"),
name, rec->line);
return rec;
}
-const char *
-yasm_symrec_get_name(const yasm_symrec *sym)
-{
- return sym->name;
-}
-
-yasm_sym_vis
-yasm_symrec_get_visibility(const yasm_symrec *sym)
-{
- return sym->visibility;
-}
-
-const yasm_expr *
-yasm_symrec_get_equ(const yasm_symrec *sym)
-{
- if (sym->type == SYM_EQU)
- return sym->value.expn;
- return (const yasm_expr *)NULL;
-}
-
-int
-yasm_symrec_get_label(const yasm_symrec *sym,
- yasm_symrec_get_label_sectionp *sect,
- yasm_symrec_get_label_bytecodep *precbc)
-{
- if (sym->type != SYM_LABEL) {
- *sect = (yasm_symrec_get_label_sectionp)0xDEADBEEF;
- *precbc = (yasm_symrec_get_label_bytecodep)0xDEADBEEF;
- return 0;
- }
- *sect = sym->value.label.sect;
- *precbc = sym->value.label.bc;
- return 1;
-}
-
-unsigned long
-yasm_symrec_get_opt_flags(const yasm_symrec *sym)
-{
- return sym->opt_flags;
-}
-
-void
-yasm_symrec_set_opt_flags(yasm_symrec *sym, unsigned long opt_flags)
-{
- sym->opt_flags = opt_flags;
-}
-
-void *
-yasm_symrec_get_of_data(yasm_symrec *sym)
-{
- return sym->of_data;
-}
-
-void
-yasm_symrec_set_of_data(yasm_symrec *sym, yasm_objfmt *of, void *of_data)
-{
- if (sym->of_data && sym->of) {
- if (sym->of->symrec_data_delete)
- sym->of->symrec_data_delete(sym->of_data);
- else
- yasm_internal_error(
- N_("don't know how to delete objfmt-specific data"));
- }
- sym->of = of;
- sym->of_data = of_data;
-}
-
-static unsigned long firstundef_line;
static int
-symrec_parser_finalize_checksym(yasm_symrec *sym,
- /*@unused@*/ /*@null@*/ void *d)
+symtab_parser_finalize_checksym(yasm_symrec *sym, /*@null@*/ void *d)
{
+ unsigned long *firstundef_line = d;
/* error if a symbol is used but never defined or extern/common declared */
if ((sym->status & SYM_USED) && !(sym->status & SYM_DEFINED) &&
!(sym->visibility & (YASM_SYM_EXTERN | YASM_SYM_COMMON))) {
yasm__error(sym->line, N_("undefined symbol `%s' (first use)"),
sym->name);
- if (sym->line < firstundef_line)
- firstundef_line = sym->line;
+ if (sym->line < *firstundef_line)
+ *firstundef_line = sym->line;
}
return 1;
}
void
-yasm_symrec_parser_finalize(void)
+yasm_symtab_parser_finalize(yasm_symtab *symtab)
{
- firstundef_line = ULONG_MAX;
- yasm_symrec_traverse(NULL, symrec_parser_finalize_checksym);
+ unsigned long firstundef_line = ULONG_MAX;
+ yasm_symtab_traverse(symtab, &firstundef_line,
+ symtab_parser_finalize_checksym);
if (firstundef_line < ULONG_MAX)
yasm__error(firstundef_line,
N_(" (Each undefined symbol is reported only once.)"));
}
void
-yasm_symrec_cleanup(void)
+yasm_symtab_destroy(yasm_symtab *symtab)
{
- HAMT_delete(sym_table, symrec_delete_one);
+ HAMT_destroy(symtab->sym_table, symrec_destroy_one);
- while (!SLIST_EMPTY(non_table_syms)) {
- non_table_symrec *sym = SLIST_FIRST(non_table_syms);
- SLIST_REMOVE_HEAD(non_table_syms, link);
- symrec_delete_one(sym->rec);
+ while (!SLIST_EMPTY(&symtab->non_table_syms)) {
+ non_table_symrec *sym = SLIST_FIRST(&symtab->non_table_syms);
+ SLIST_REMOVE_HEAD(&symtab->non_table_syms, link);
+ symrec_destroy_one(sym->rec);
yasm_xfree(sym);
}
- yasm_xfree(non_table_syms);
+
+ yasm_xfree(symtab);
}
typedef struct symrec_print_data {
symrec_print_data *data = (symrec_print_data *)d;
assert(data != NULL);
fprintf(data->f, "%*sSymbol `%s'\n", data->indent_level, "", sym->name);
- yasm_symrec_print(data->f, data->indent_level+1, sym);
+ yasm_symrec_print(sym, data->f, data->indent_level+1);
return 1;
}
void
-yasm_symrec_print_all(FILE *f, int indent_level)
+yasm_symtab_print(yasm_symtab *symtab, FILE *f, int indent_level)
{
symrec_print_data data;
data.f = f;
data.indent_level = indent_level;
- yasm_symrec_traverse(&data, symrec_print_wrapper);
+ yasm_symtab_traverse(symtab, &data, symrec_print_wrapper);
}
/*@=voidabstract@*/
+const char *
+yasm_symrec_get_name(const yasm_symrec *sym)
+{
+ return sym->name;
+}
+
+yasm_sym_vis
+yasm_symrec_get_visibility(const yasm_symrec *sym)
+{
+ return sym->visibility;
+}
+
+const yasm_expr *
+yasm_symrec_get_equ(const yasm_symrec *sym)
+{
+ if (sym->type == SYM_EQU)
+ return sym->value.expn;
+ return (const yasm_expr *)NULL;
+}
+
+int
+yasm_symrec_get_label(const yasm_symrec *sym,
+ yasm_symrec_get_label_bytecodep *precbc)
+{
+ if (sym->type != SYM_LABEL) {
+ *precbc = (yasm_symrec_get_label_bytecodep)0xDEADBEEF;
+ return 0;
+ }
+ *precbc = sym->value.precbc;
+ return 1;
+}
+
+void *
+yasm_symrec_get_data(yasm_symrec *sym,
+ const yasm_assoc_data_callback *callback)
+{
+ return yasm__assoc_data_get(sym->assoc_data, callback);
+}
+
+void
+yasm_symrec_add_data(yasm_symrec *sym,
+ const yasm_assoc_data_callback *callback, void *data)
+{
+ sym->assoc_data = yasm__assoc_data_add(sym->assoc_data, callback, data);
+}
+
void
-yasm_symrec_print(FILE *f, int indent_level, const yasm_symrec *sym)
+yasm_symrec_print(const yasm_symrec *sym, FILE *f, int indent_level)
{
switch (sym->type) {
case SYM_UNKNOWN:
case SYM_EQU:
fprintf(f, "%*s_EQU_\n", indent_level, "");
fprintf(f, "%*sExpn=", indent_level, "");
- yasm_expr_print(f, sym->value.expn);
+ yasm_expr_print(sym->value.expn, f);
fprintf(f, "\n");
break;
case SYM_LABEL:
fprintf(f, "%*s_Label_\n%*sSection:\n", indent_level, "",
indent_level, "");
- yasm_section_print(f, indent_level+1, sym->value.label.sect, 0);
- if (!sym->value.label.bc)
- fprintf(f, "%*sFirst bytecode\n", indent_level, "");
- else {
- fprintf(f, "%*sPreceding bytecode:\n", indent_level, "");
- yasm_bc_print(f, indent_level+1, sym->value.label.bc);
- }
+ yasm_section_print(yasm_bc_get_section(sym->value.precbc), f,
+ indent_level+1, 0);
+ fprintf(f, "%*sPreceding bytecode:\n", indent_level, "");
+ yasm_bc_print(sym->value.precbc, f, indent_level+1);
break;
}
fprintf(f, "\n");
}
- if (sym->of_data && sym->of) {
- fprintf(f, "%*sObject format-specific data:\n", indent_level, "");
- if (sym->of->symrec_data_print)
- sym->of->symrec_data_print(f, indent_level+1, sym->of_data);
- else
- fprintf(f, "%*sUNKNOWN\n", indent_level+1, "");
+ if (sym->assoc_data) {
+ fprintf(f, "%*sAssociated data:\n", indent_level, "");
+ yasm__assoc_data_print(sym->assoc_data, f, indent_level+1);
}
fprintf(f, "%*sLine Index=%lu\n", indent_level, "", sym->line);
#ifndef YASM_SYMREC_H
#define YASM_SYMREC_H
-/** Initialize symbol table internal data structures. */
-void yasm_symrec_initialize(void);
+/** Create a new symbol table. */
+yasm_symtab *yasm_symtab_create(void);
-/** Clean up internal symbol table allocations. */
-void yasm_symrec_cleanup(void);
+/** Destroy a symbol table and all internal symbols.
+ * \param symtab symbol table
+ * \warning All yasm_symrec *'s into this symbol table become invalid after
+ * this is called!
+ */
+void yasm_symtab_destroy(/*@only@*/ yasm_symtab *symtab);
/** Get a reference to (use) a symbol. The symbol does not necessarily need to
* be defined before it is used.
+ * \param symtab symbol table
* \param name symbol name
- * \param lindex line index where referenced
+ * \param line virtual line where referenced
* \return Symbol (dependent pointer, do not free).
*/
-/*@dependent@*/ yasm_symrec *yasm_symrec_use(const char *name,
- unsigned long lindex);
+/*@dependent@*/ yasm_symrec *yasm_symtab_use
+ (yasm_symtab *symtab, const char *name, unsigned long line);
/** Define a symbol as an EQU value.
+ * \param symtab symbol table
* \param name symbol (EQU) name
* \param e EQU value (expression)
- * \param lindex line index of EQU
+ * \param line virtual line of EQU
* \return Symbol (dependent pointer, do not free).
*/
-/*@dependent@*/ yasm_symrec *yasm_symrec_define_equ
- (const char *name, /*@keep@*/ yasm_expr *e, unsigned long lindex);
+/*@dependent@*/ yasm_symrec *yasm_symtab_define_equ
+ (yasm_symtab *symtab, const char *name, /*@keep@*/ yasm_expr *e,
+ unsigned long line);
/** Define a symbol as a label.
+ * \param symtab symbol table
+ * \param name symbol (label) name
+ * \param precbc bytecode preceding label
+ * \param in_table nonzero if the label should be inserted into the symbol
+ * table (some specially-generated ones should not be)
+ * \param line virtual line of label
+ * \return Symbol (dependent pointer, do not free).
+ */
+/*@dependent@*/ yasm_symrec *yasm_symtab_define_label
+ (yasm_symtab *symtab, const char *name,
+ /*@dependent@*/ yasm_bytecode *precbc, int in_table, unsigned long line);
+
+/** Define a symbol as a label, shortcut (no need to find out symtab, it's
+ * determined from precbc).
* \param name symbol (label) name
- * \param sect section containing label
- * \param precbc bytecode preceding label (NULL if label is before first
- * bytecode in section)
+ * \param precbc bytecode preceding label
* \param in_table nonzero if the label should be inserted into the symbol
* table (some specially-generated ones should not be)
- * \param lindex line index of label
+ * \param line virtual line of label
* \return Symbol (dependent pointer, do not free).
*/
-/*@dependent@*/ yasm_symrec *yasm_symrec_define_label
- (const char *name, /*@dependent@*/ /*@null@*/ yasm_section *sect,
- /*@dependent@*/ /*@null@*/ yasm_bytecode *precbc, int in_table,
- unsigned long lindex);
+/*@dependent@*/ yasm_symrec *yasm_symtab_define_label2
+ (const char *name, /*@dependent@*/ yasm_bytecode *precbc, int in_table,
+ unsigned long line);
/** Declare external visibility of a symbol.
* \note Not all visibility combinations are allowed.
+ * \param symtab symbol table
* \param name symbol name
* \param vis visibility
- * \param lindex line index of visibility-setting
+ * \param line virtual line of visibility-setting
* \return Symbol (dependent pointer, do not free).
*/
-/*@dependent@*/ yasm_symrec *yasm_symrec_declare
- (const char *name, yasm_sym_vis vis, unsigned long lindex);
+/*@dependent@*/ yasm_symrec *yasm_symtab_declare
+ (yasm_symtab *symtab, const char *name, yasm_sym_vis vis,
+ unsigned long line);
+
+/** Callback function for yasm_symrec_traverse().
+ * \param sym symbol
+ * \param d data passed into yasm_symrec_traverse()
+ * \return Nonzero to stop symbol traversal.
+ */
+typedef int (*yasm_symtab_traverse_callback)
+ (yasm_symrec *sym, /*@null@*/ void *d);
+
+/** Traverse all symbols in the symbol table.
+ * \param symtab symbol table
+ * \param d data to pass to each call of callback function
+ * \param func callback function called on each symbol
+ * \return Nonzero value returned by callback function if it ever returned
+ * nonzero.
+ */
+int /*@alt void@*/ yasm_symtab_traverse
+ (yasm_symtab *symtab, /*@null@*/ void *d,
+ yasm_symtab_traverse_callback func);
+
+/** Finalize symbol table after parsing stage. Checks for symbols that are
+ * used but never defined or declared #YASM_SYM_EXTERN or #YASM_SYM_COMMON.
+ */
+void yasm_symtab_parser_finalize(yasm_symtab *symtab);
+
+/** Print the symbol table. For debugging purposes.
+ * \param symtab symbol table
+ * \param f file
+ * \param indent_level indentation level
+ */
+void yasm_symtab_print(yasm_symtab *symtab, FILE *f, int indent_level);
/** Get the name of a symbol.
* \param sym symbol
/*@observer@*/ /*@null@*/ const yasm_expr *yasm_symrec_get_equ
(const yasm_symrec *sym);
-/** Dependent pointer to a section. */
-typedef /*@dependent@*/ /*@null@*/ yasm_section *
- yasm_symrec_get_label_sectionp;
-
/** Dependent pointer to a bytecode. */
-typedef /*@dependent@*/ /*@null@*/ yasm_bytecode *
- yasm_symrec_get_label_bytecodep;
+typedef /*@dependent@*/ yasm_bytecode *yasm_symrec_get_label_bytecodep;
/** Get the label location of a symbol.
* \param sym symbol
- * \param sect section containing label (output)
- * \param precbc bytecode preceding label (output); NULL if no preceding
- * bytecode in section.
+ * \param precbc bytecode preceding label (output)
* \return 0 if not symbol is not a label or if the symbol's visibility is
* #YASM_SYM_EXTERN or #YASM_SYM_COMMON (not defined in the file).
*/
int yasm_symrec_get_label(const yasm_symrec *sym,
- /*@out@*/ yasm_symrec_get_label_sectionp *sect,
/*@out@*/ yasm_symrec_get_label_bytecodep *precbc);
-/** Get yasm_optimizer-specific flags. For yasm_optimizer use only.
- * \param sym symbol
- * \return Optimizer-specific flags.
- */
-unsigned long yasm_symrec_get_opt_flags(const yasm_symrec *sym);
-
-/** Set yasm_optimizer-specific flags. For yasm_optimizer use only.
- * \param sym symbol
- * \param opt_flags optimizer-specific flags.
- */
-void yasm_symrec_set_opt_flags(yasm_symrec *sym, unsigned long opt_flags);
-
-/** Get yasm_objfmt-specific data. For yasm_objfmt use only.
+/** Get associated data for a symbol and data callback.
* \param sym symbol
- * \return Object format-specific data.
+ * \param callback callback used when adding data
+ * \return Associated data (NULL if none).
*/
-/*@dependent@*/ /*@null@*/ void *yasm_symrec_get_of_data(yasm_symrec *sym);
+/*@dependent@*/ /*@null@*/ void *yasm_symrec_get_data
+ (yasm_symrec *sym, const yasm_assoc_data_callback *callback);
-/** Set yasm_objfmt-specific data. For yasm_objfmt use only.
- * \attention Deletes any existing of_data.
+/** Add associated data to a symbol.
+ * \attention Deletes any existing associated data for that data callback.
* \param sym symbol
- * \param of object format
- * \param of_data object format-specific data.
- */
-void yasm_symrec_set_of_data(yasm_symrec *sym, yasm_objfmt *of,
- /*@only@*/ /*@null@*/ void *of_data);
-
-/** Callback function for yasm_symrec_traverse().
- * \param sym symbol
- * \param d data passed into yasm_symrec_traverse()
- * \return Nonzero to stop symbol traversal.
- */
-typedef int (*yasm_symrec_traverse_callback)
- (yasm_symrec *sym, /*@null@*/ void *d);
-
-/** Traverse all symbols in the symbol table.
- * \param d data to pass to each call of callback function
- * \param func callback function called on each symbol
- * \return Nonzero value returned by callback function if it ever returned
- * nonzero.
- */
-int /*@alt void@*/ yasm_symrec_traverse
- (/*@null@*/ void *d, yasm_symrec_traverse_callback func);
-
-/** Finalize symbol table after parsing stage. Checks for symbols that are
- * used but never defined or declared #YASM_SYM_EXTERN or #YASM_SYM_COMMON.
- */
-void yasm_symrec_parser_finalize(void);
-
-/** Print the symbol table. For debugging purposes.
- * \param f file
- * \param indent_level indentation level
+ * \param callback callback
+ * \param data data to associate
*/
-void yasm_symrec_print_all(FILE *f, int indent_level);
+void yasm_symrec_add_data(yasm_symrec *sym,
+ const yasm_assoc_data_callback *callback,
+ /*@only@*/ /*@null@*/ void *data);
/** Print a symbol. For debugging purposes.
* \param f file
* \param indent_level indentation level
* \param sym symbol
*/
-void yasm_symrec_print(FILE *f, int indent_level, const yasm_symrec *sym);
+void yasm_symrec_print(const yasm_symrec *sym, FILE *f, int indent_level);
#endif
static void
new_setup(Init_Entry *vals, int i)
{
- flt = yasm_floatnum_new(vals[i].ascii);
+ flt = yasm_floatnum_create(vals[i].ascii);
strcpy(result_msg, vals[i].ascii);
strcat(result_msg, ": incorrect ");
}
for (i=0; i<num; i++) {
new_setup(vals, i);
fail_unless(new_check_flt(&vals[i]) == 0, result_msg);
- yasm_floatnum_delete(flt);
+ yasm_floatnum_destroy(flt);
}
}
END_TEST
for (i=0; i<num; i++) {
new_setup(vals, i);
fail_unless(new_check_flt(&vals[i]) == 0, result_msg);
- yasm_floatnum_delete(flt);
+ yasm_floatnum_destroy(flt);
}
}
END_TEST
*/
#define YASM_LIB_INTERNAL
#include "util.h"
-/*@unused@*/ RCSID("$IdPath: yasm/libyasm/valparam.c,v 1.13 2003/03/16 23:53:31 peter Exp $");
+/*@unused@*/ RCSID("$IdPath$");
#include "coretype.h"
#include "valparam.h"
yasm_valparam *
-yasm_vp_new(/*@keep@*/ char *v, /*@keep@*/ yasm_expr *p)
+yasm_vp_create(/*@keep@*/ char *v, /*@keep@*/ yasm_expr *p)
{
yasm_valparam *r = yasm_xmalloc(sizeof(yasm_valparam));
r->val = v;
if (cur->val)
yasm_xfree(cur->val);
if (cur->param)
- yasm_expr_delete(cur->param);
+ yasm_expr_destroy(cur->param);
yasm_xfree(cur);
cur = next;
}
}
void
-yasm_vps_print(FILE *f, const yasm_valparamhead *headp)
+yasm_vps_print(const yasm_valparamhead *headp, FILE *f)
{
const yasm_valparam *vp;
else
fprintf(f, "((nil),");
if (vp->param)
- yasm_expr_print(f, vp->param);
+ yasm_expr_print(vp->param, f);
else
fprintf(f, "(nil)");
fprintf(f, ")");
}
}
-/* Non-macro yasm_vps_initialize() for non-YASM_LIB_INTERNAL users. */
-#undef yasm_vps_initialize
+yasm_valparamhead *
+yasm_vps_create(void)
+{
+ yasm_valparamhead *headp = yasm_xmalloc(sizeof(yasm_valparamhead));
+ yasm_vps_initialize(headp);
+ return headp;
+}
+
void
-yasm_vps_initialize(/*@out@*/ yasm_valparamhead *headp)
+yasm_vps_destroy(yasm_valparamhead *headp)
{
- STAILQ_INIT(headp);
+ yasm_vps_delete(headp);
+ yasm_xfree(headp);
}
/* Non-macro yasm_vps_append() for non-YASM_LIB_INTERNAL users. */
* \param p parameter
* \return Newly allocated valparam.
*/
-yasm_valparam *yasm_vp_new(/*@keep@*/ char *v, /*@keep@*/ yasm_expr *p);
+yasm_valparam *yasm_vp_create(/*@keep@*/ char *v, /*@keep@*/ yasm_expr *p);
+/** Create a new linked list of valparams.
+ * \return Newly allocated valparam list.
+ */
+yasm_valparamhead *yasm_vps_create(void);
+
+/** Destroy a list of instruction operands (created with yasm_vps_create).
+ * \param headp list of instruction operands
+ */
+void yasm_vps_destroy(yasm_valparamhead *headp);
+
+#ifdef YASM_LIB_INTERNAL
/** Initialize linked list of valparams.
* \param headp linked list
*/
-void yasm_vps_initialize(/*@out@*/ yasm_valparamhead *headp);
-#ifdef YASM_LIB_INTERNAL
#define yasm_vps_initialize(headp) STAILQ_INIT(headp)
-#endif
-/** Destroy (free allocated memory for) linked list of valparams.
+/** Destroy (free allocated memory for) linked list of valparams (created with
+ * yasm_vps_initialize).
* \warning Deletes val/params.
* \param headp linked list
*/
void yasm_vps_delete(yasm_valparamhead *headp);
+#endif
/** Append valparam to tail of linked list.
* \param headp linked list
* \param f file
* \param headp linked list
*/
-void yasm_vps_print(FILE *f, /*@null@*/ const yasm_valparamhead *headp);
+void yasm_vps_print(/*@null@*/ const yasm_valparamhead *headp, FILE *f);
#endif
#include "lc3barch.h"
-static int
-lc3b_initialize(/*@unused@*/ const char *machine)
+yasm_arch_module yasm_lc3b_LTX_arch;
+
+
+static /*@only@*/ yasm_arch *
+lc3b_create(const char *machine)
{
+ yasm_arch *arch;
+
if (yasm__strcasecmp(machine, "lc3b") != 0)
- return 1;
- return 0;
+ return NULL;
+
+ arch = yasm_xmalloc(sizeof(yasm_arch));
+ arch->module = &yasm_lc3b_LTX_arch;
+ return arch;
}
static void
-lc3b_cleanup(void)
+lc3b_destroy(/*@only@*/ yasm_arch *arch)
{
+ yasm_xfree(arch);
}
-int
-yasm_lc3b__parse_directive(/*@unused@*/ const char *name,
- /*@unused@*/ yasm_valparamhead *valparams,
- /*@unused@*/ /*@null@*/
- yasm_valparamhead *objext_valparams,
- /*@unused@*/ yasm_sectionhead *headp,
- /*@unused@*/ unsigned long lindex)
+static const char *
+lc3b_get_machine(/*@unused@*/ const yasm_arch *arch)
+{
+ return "lc3b";
+}
+
+static int
+lc3b_set_var(yasm_arch *arch, const char *var, unsigned long val)
{
return 1;
}
-unsigned int
-yasm_lc3b__get_reg_size(unsigned long reg)
+static int
+lc3b_parse_directive(/*@unused@*/ yasm_arch *arch,
+ /*@unused@*/ const char *name,
+ /*@unused@*/ yasm_valparamhead *valparams,
+ /*@unused@*/ /*@null@*/
+ yasm_valparamhead *objext_valparams,
+ /*@unused@*/ yasm_object *object,
+ /*@unused@*/ unsigned long line)
+{
+ return 1;
+}
+
+static unsigned int
+lc3b_get_reg_size(/*@unused@*/ yasm_arch *arch, /*@unused@*/ unsigned long reg)
{
return 2;
}
-void
-yasm_lc3b__reg_print(FILE *f, unsigned long reg)
+static void
+lc3b_reg_print(/*@unused@*/ yasm_arch *arch, unsigned long reg, FILE *f)
{
fprintf(f, "r%u", (unsigned int)(reg&7));
}
static int
-yasm_lc3b__floatnum_tobytes(const yasm_floatnum *flt, unsigned char *buf,
- size_t destsize, size_t valsize, size_t shift,
- int warn, unsigned long lindex)
+lc3b_floatnum_tobytes(yasm_arch *arch, const yasm_floatnum *flt,
+ unsigned char *buf, size_t destsize, size_t valsize,
+ size_t shift, int warn, unsigned long line)
{
- yasm__error(lindex, N_("LC-3b does not support floating point"));
+ yasm__error(line, N_("LC-3b does not support floating point"));
return 1;
}
static yasm_effaddr *
-yasm_lc3b__ea_new_expr(yasm_expr *e)
+lc3b_ea_create_expr(yasm_arch *arch, yasm_expr *e)
{
- yasm_expr_delete(e);
+ yasm_expr_destroy(e);
return NULL;
}
};
/* Define arch structure -- see arch.h for details */
-yasm_arch yasm_lc3b_LTX_arch = {
+yasm_arch_module yasm_lc3b_LTX_arch = {
YASM_ARCH_VERSION,
"LC-3b",
"lc3b",
- lc3b_initialize,
- lc3b_cleanup,
+ lc3b_create,
+ lc3b_destroy,
+ lc3b_get_machine,
+ lc3b_set_var,
yasm_lc3b__parse_cpu,
yasm_lc3b__parse_check_id,
- yasm_lc3b__parse_directive,
+ lc3b_parse_directive,
yasm_lc3b__parse_insn,
NULL, /*yasm_lc3b__parse_prefix*/
NULL, /*yasm_lc3b__parse_seg_prefix*/
NULL, /*yasm_lc3b__parse_seg_override*/
- LC3B_BYTECODE_TYPE_MAX,
- yasm_lc3b__bc_delete,
- yasm_lc3b__bc_print,
- yasm_lc3b__bc_resolve,
- yasm_lc3b__bc_tobytes,
- yasm_lc3b__floatnum_tobytes,
+ lc3b_floatnum_tobytes,
yasm_lc3b__intnum_tobytes,
- yasm_lc3b__get_reg_size,
- yasm_lc3b__reg_print,
+ lc3b_get_reg_size,
+ lc3b_reg_print,
NULL, /*yasm_lc3b__segreg_print*/
- yasm_lc3b__ea_new_expr,
- NULL, /*yasm_lc3b__ea_data_delete*/
- NULL, /*yasm_lc3b__ea_data_print*/
+ lc3b_ea_create_expr,
lc3b_machines,
"lc3b",
2
#ifndef YASM_LC3BARCH_H
#define YASM_LC3BARCH_H
-typedef enum {
- LC3B_BC_INSN = YASM_BYTECODE_TYPE_BASE
-} lc3b_bytecode_type;
-#define LC3B_BYTECODE_TYPE_MAX LC3B_BC_INSN+1
-
/* Types of immediate. All immediates are stored in the LSBs of the insn. */
typedef enum lc3b_imm_type {
LC3B_IMM_NONE = 0, /* no immediate */
* (it doesn't make a copy).
*/
typedef struct lc3b_new_insn_data {
- unsigned long lindex;
+ unsigned long line;
/*@keep@*/ /*@null@*/ yasm_expr *imm;
lc3b_imm_type imm_type;
/*@null@*/ /*@dependent@*/ yasm_symrec *origin;
unsigned int opcode;
} lc3b_new_insn_data;
-yasm_bytecode *yasm_lc3b__bc_new_insn(lc3b_new_insn_data *d);
-
-void yasm_lc3b__bc_delete(yasm_bytecode *bc);
-void yasm_lc3b__bc_print(FILE *f, int indent_level, const yasm_bytecode *bc);
-yasm_bc_resolve_flags yasm_lc3b__bc_resolve
- (yasm_bytecode *bc, int save, const yasm_section *sect,
- yasm_calc_bc_dist_func calc_bc_dist);
-int yasm_lc3b__bc_tobytes(yasm_bytecode *bc, unsigned char **bufp,
- const yasm_section *sect, void *d,
- yasm_output_expr_func output_expr);
+yasm_bytecode *yasm_lc3b__bc_create_insn(lc3b_new_insn_data *d);
-void yasm_lc3b__parse_cpu(const char *cpuid, unsigned long lindex);
+void yasm_lc3b__parse_cpu(yasm_arch *arch, const char *cpuid,
+ unsigned long line);
yasm_arch_check_id_retval yasm_lc3b__parse_check_id
- (unsigned long data[2], const char *id, unsigned long lindex);
-
-int yasm_lc3b__parse_directive(const char *name, yasm_valparamhead *valparams,
- /*@null@*/ yasm_valparamhead *objext_valparams,
- yasm_sectionhead *headp, unsigned long lindex);
+ (yasm_arch *arch, unsigned long data[2], const char *id,
+ unsigned long line);
/*@null@*/ yasm_bytecode *yasm_lc3b__parse_insn
- (const unsigned long data[2], int num_operands,
- /*@null@*/ yasm_insn_operandhead *operands, yasm_section *cur_section,
- /*@null@*/ yasm_bytecode *prev_bc, unsigned long lindex);
-
-int yasm_lc3b__intnum_tobytes(const yasm_intnum *intn, unsigned char *buf,
- size_t destsize, size_t valsize, int shift,
- const yasm_bytecode *bc, int rel, int warn,
- unsigned long lindex);
-
-unsigned int yasm_lc3b__get_reg_size(unsigned long reg);
-
-void yasm_lc3b__reg_print(FILE *f, unsigned long reg);
+ (yasm_arch *arch, const unsigned long data[2], int num_operands,
+ /*@null@*/ yasm_insn_operandhead *operands, yasm_bytecode *prev_bc,
+ unsigned long line);
+int yasm_lc3b__intnum_tobytes
+ (yasm_arch *arch, const yasm_intnum *intn, unsigned char *buf,
+ size_t destsize, size_t valsize, int shift, const yasm_bytecode *bc,
+ int rel, int warn, unsigned long line);
#endif
#include "lc3barch.h"
+/* Bytecode types */
+
typedef struct lc3b_insn {
yasm_bytecode bc; /* base structure */
unsigned int opcode; /* opcode */
} lc3b_insn;
+/* Bytecode callback function prototypes */
+
+static void lc3b_bc_insn_destroy(yasm_bytecode *bc);
+static void lc3b_bc_insn_print(const yasm_bytecode *bc, FILE *f,
+ int indent_level);
+static yasm_bc_resolve_flags lc3b_bc_insn_resolve
+ (yasm_bytecode *bc, int save, yasm_calc_bc_dist_func calc_bc_dist);
+static int lc3b_bc_insn_tobytes(yasm_bytecode *bc, unsigned char **bufp,
+ void *d, yasm_output_expr_func output_expr,
+ /*@null@*/ yasm_output_reloc_func output_reloc);
+
+/* Bytecode callback structures */
+
+static const yasm_bytecode_callback lc3b_bc_callback_insn = {
+ lc3b_bc_insn_destroy,
+ lc3b_bc_insn_print,
+ lc3b_bc_insn_resolve,
+ lc3b_bc_insn_tobytes
+};
+
/*@-compmempass -mustfree@*/
yasm_bytecode *
-yasm_lc3b__bc_new_insn(lc3b_new_insn_data *d)
+yasm_lc3b__bc_create_insn(lc3b_new_insn_data *d)
{
lc3b_insn *insn;
- insn = (lc3b_insn *)yasm_bc_new_common((yasm_bytecode_type)LC3B_BC_INSN,
- sizeof(lc3b_insn), d->lindex);
+ insn = (lc3b_insn *)yasm_bc_create_common(&lc3b_bc_callback_insn,
+ sizeof(lc3b_insn), d->line);
insn->imm = d->imm;
if (d->imm)
}
/*@=compmempass =mustfree@*/
-void
-yasm_lc3b__bc_delete(yasm_bytecode *bc)
+static void
+lc3b_bc_insn_destroy(yasm_bytecode *bc)
{
- lc3b_insn *insn;
-
- if ((lc3b_bytecode_type)bc->type != LC3B_BC_INSN)
- return;
-
- insn = (lc3b_insn *)bc;
+ lc3b_insn *insn = (lc3b_insn *)bc;
if (insn->imm)
- yasm_expr_delete(insn->imm);
+ yasm_expr_destroy(insn->imm);
}
-void
-yasm_lc3b__bc_print(FILE *f, int indent_level, const yasm_bytecode *bc)
+static void
+lc3b_bc_insn_print(const yasm_bytecode *bc, FILE *f, int indent_level)
{
- const lc3b_insn *insn;
+ const lc3b_insn *insn = (const lc3b_insn *)bc;
- if ((lc3b_bytecode_type)bc->type != LC3B_BC_INSN)
- return;
-
- insn = (const lc3b_insn *)bc;
fprintf(f, "%*s_Instruction_\n", indent_level, "");
fprintf(f, "%*sImmediate Value:", indent_level, "");
if (!insn->imm)
else {
indent_level++;
fprintf(f, "\n%*sVal=", indent_level, "");
- yasm_expr_print(f, insn->imm);
+ yasm_expr_print(insn->imm, f);
fprintf(f, "\n%*sType=", indent_level, "");
switch (insn->imm_type) {
case LC3B_IMM_NONE:
fprintf(f, "\n%*sOrigin=", indent_level, "");
if (insn->origin) {
fprintf(f, "\n");
- yasm_symrec_print(f, indent_level+1, insn->origin);
+ yasm_symrec_print(insn->origin, f, indent_level+1);
} else
fprintf(f, "(nil)\n");
fprintf(f, "%*sOpcode: %04x\n", indent_level, "",
(unsigned int)insn->opcode);
}
-yasm_bc_resolve_flags
-yasm_lc3b__bc_resolve(yasm_bytecode *bc, int save, const yasm_section *sect,
- yasm_calc_bc_dist_func calc_bc_dist)
+static yasm_bc_resolve_flags
+lc3b_bc_insn_resolve(yasm_bytecode *bc, int save,
+ yasm_calc_bc_dist_func calc_bc_dist)
{
- lc3b_insn *insn;
+ lc3b_insn *insn = (lc3b_insn *)bc;
/*@null@*/ yasm_expr *temp;
/*@dependent@*/ /*@null@*/ const yasm_intnum *num;
long rel;
- if ((lc3b_bytecode_type)bc->type != LC3B_BC_INSN)
- yasm_internal_error(N_("Didn't handle bytecode type in lc3b arch"));
-
- insn = (lc3b_insn *)bc;
-
/* Fixed size instruction length */
bc->len = 2;
return YASM_BC_RESOLVE_MIN_LEN;
temp = yasm_expr_copy(insn->imm);
- temp = yasm_expr_new(YASM_EXPR_SUB, yasm_expr_expr(temp),
- yasm_expr_sym(insn->origin), bc->line);
+ temp = yasm_expr_create(YASM_EXPR_SUB, yasm_expr_expr(temp),
+ yasm_expr_sym(insn->origin), bc->line);
num = yasm_expr_get_intnum(&temp, calc_bc_dist);
if (!num) {
yasm__error(bc->line, N_("target external or out of segment"));
- yasm_expr_delete(temp);
+ yasm_expr_destroy(temp);
return YASM_BC_RESOLVE_ERROR | YASM_BC_RESOLVE_UNKNOWN_LEN;
}
rel = yasm_intnum_get_int(num);
rel -= 2;
- yasm_expr_delete(temp);
+ yasm_expr_destroy(temp);
/* 9-bit signed, word-multiple displacement */
if (rel < -512 || rel > 511) {
yasm__error(bc->line, N_("target out of range"));
return YASM_BC_RESOLVE_MIN_LEN;
}
-int
-yasm_lc3b__bc_tobytes(yasm_bytecode *bc, unsigned char **bufp,
- const yasm_section *sect, void *d,
- yasm_output_expr_func output_expr)
+static int
+lc3b_bc_insn_tobytes(yasm_bytecode *bc, unsigned char **bufp, void *d,
+ yasm_output_expr_func output_expr,
+ /*@unused@*/ yasm_output_reloc_func output_reloc)
{
- lc3b_insn *insn;
-
- if ((lc3b_bytecode_type)bc->type != LC3B_BC_INSN)
- return 0;
-
- insn = (lc3b_insn *)bc;
+ lc3b_insn *insn = (lc3b_insn *)bc;
/* Output opcode */
YASM_SAVE_16_L(*bufp, insn->opcode);
case LC3B_IMM_NONE:
break;
case LC3B_IMM_4:
- if (output_expr(&insn->imm, *bufp, 2, 4, 0, 0, sect, bc, 0, 1, d))
+ if (output_expr(&insn->imm, *bufp, 2, 4, 0, 0, bc, 0, 1, d))
return 1;
break;
case LC3B_IMM_5:
- if (output_expr(&insn->imm, *bufp, 2, 5, 0, 0, sect, bc, 0, 1, d))
+ if (output_expr(&insn->imm, *bufp, 2, 5, 0, 0, bc, 0, 1, d))
return 1;
break;
case LC3B_IMM_6_WORD:
- if (output_expr(&insn->imm, *bufp, 2, 6, -1, 0, sect, bc, 0, 1, d))
+ if (output_expr(&insn->imm, *bufp, 2, 6, -1, 0, bc, 0, 1, d))
return 1;
break;
case LC3B_IMM_6_BYTE:
- if (output_expr(&insn->imm, *bufp, 2, 6, 0, 0, sect, bc, 0, 1, d))
+ if (output_expr(&insn->imm, *bufp, 2, 6, 0, 0, bc, 0, 1, d))
return 1;
break;
case LC3B_IMM_8:
- if (output_expr(&insn->imm, *bufp, 2, 8, -1, 0, sect, bc, 0, 1, d))
+ if (output_expr(&insn->imm, *bufp, 2, 8, -1, 0, bc, 0, 1, d))
return 1;
break;
case LC3B_IMM_9_PC:
- insn->imm = yasm_expr_new(YASM_EXPR_SUB, yasm_expr_expr(insn->imm),
- yasm_expr_sym(insn->origin), bc->line);
- if (output_expr(&insn->imm, *bufp, 2, 9, -1, 0, sect, bc, 1, 1, d))
+ insn->imm = yasm_expr_create(YASM_EXPR_SUB,
+ yasm_expr_expr(insn->imm), yasm_expr_sym(insn->origin),
+ bc->line);
+ if (output_expr(&insn->imm, *bufp, 2, 9, -1, 0, bc, 1, 1, d))
return 1;
break;
case LC3B_IMM_9:
- if (output_expr(&insn->imm, *bufp, 2, 9, -1, 0, sect, bc, 0, 1, d))
+ if (output_expr(&insn->imm, *bufp, 2, 9, -1, 0, bc, 0, 1, d))
return 1;
break;
default:
}
int
-yasm_lc3b__intnum_tobytes(const yasm_intnum *intn, unsigned char *buf,
- size_t destsize, size_t valsize, int shift,
- const yasm_bytecode *bc, int rel, int warn,
- unsigned long lindex)
+yasm_lc3b__intnum_tobytes(yasm_arch *arch, const yasm_intnum *intn,
+ unsigned char *buf, size_t destsize, size_t valsize,
+ int shift, const yasm_bytecode *bc, int rel,
+ int warn, unsigned long line)
{
if (rel) {
yasm_intnum *relnum, *delta;
yasm_internal_error(
N_("tried to do PC-relative offset from invalid sized value"));
relnum = yasm_intnum_copy(intn);
- delta = yasm_intnum_new_uint(bc->len);
- yasm_intnum_calc(relnum, YASM_EXPR_SUB, delta, lindex);
- yasm_intnum_delete(delta);
+ delta = yasm_intnum_create_uint(bc->len);
+ yasm_intnum_calc(relnum, YASM_EXPR_SUB, delta, line);
+ yasm_intnum_destroy(delta);
yasm_intnum_get_sized(relnum, buf, destsize, valsize, shift, 0, warn,
- lindex);
- yasm_intnum_delete(relnum);
+ line);
+ yasm_intnum_destroy(relnum);
} else {
/* Write value out. */
yasm_intnum_get_sized(intn, buf, destsize, valsize, shift, 0, warn,
- lindex);
+ line);
}
return 0;
}
};
yasm_bytecode *
-yasm_lc3b__parse_insn(const unsigned long data[4], int num_operands,
- yasm_insn_operandhead *operands,
- yasm_section *cur_section,
- /*@null@*/ yasm_bytecode *prev_bc, unsigned long lindex)
+yasm_lc3b__parse_insn(yasm_arch *arch, const unsigned long data[4],
+ int num_operands, yasm_insn_operandhead *operands,
+ yasm_bytecode *prev_bc, unsigned long line)
{
lc3b_new_insn_data d;
int num_info = (int)(data[1]&0xFF);
/* Match each operand type and size */
for(i = 0, op = yasm_ops_first(operands); op && i<info->num_operands &&
- !mismatch; op = yasm_ops_next(op), i++) {
+ !mismatch; op = yasm_operand_next(op), i++) {
/* Check operand type */
switch ((int)(info->operands[i] & OPT_MASK)) {
case OPT_Imm:
if (!found) {
/* Didn't find a matching one */
- yasm__error(lindex, N_("invalid combination of opcode and operands"));
+ yasm__error(line, N_("invalid combination of opcode and operands"));
return NULL;
}
/* Copy what we can from info */
- d.lindex = lindex;
+ d.line = line;
d.imm = NULL;
d.imm_type = LC3B_IMM_NONE;
d.origin = NULL;
/* Go through operands and assign */
if (operands) {
for(i = 0, op = yasm_ops_first(operands); op && i<info->num_operands;
- op = yasm_ops_next(op), i++) {
+ op = yasm_operand_next(op), i++) {
switch ((int)(info->operands[i] & OPA_MASK)) {
case OPA_None:
/* Throw away the operand contents */
if (op->type == YASM_INSN__OPERAND_IMM)
- yasm_expr_delete(op->data.val);
+ yasm_expr_destroy(op->data.val);
break;
case OPA_DR:
if (op->type != YASM_INSN__OPERAND_REG)
d.imm = op->data.val;
break;
case YASM_INSN__OPERAND_REG:
- d.imm = yasm_expr_new_ident(yasm_expr_int(
- yasm_intnum_new_uint(op->data.reg & 0x7)),
- lindex);
+ d.imm = yasm_expr_create_ident(yasm_expr_int(
+ yasm_intnum_create_uint(op->data.reg & 0x7)),
+ line);
break;
default:
yasm_internal_error(N_("invalid operand conversion"));
d.imm_type = (info->operands[i] & OPI_MASK)>>3;
if (d.imm_type == LC3B_IMM_9_PC)
- d.origin = yasm_symrec_define_label("$", cur_section, prev_bc,
- 0, lindex);
+ d.origin = yasm_symtab_define_label2("$", prev_bc, 0, line);
}
}
/* Create the bytecode and return it */
- return yasm_lc3b__bc_new_insn(&d);
+ return yasm_lc3b__bc_create_insn(&d);
}
*/
void
-yasm_lc3b__parse_cpu(const char *id, unsigned long lindex)
+yasm_lc3b__parse_cpu(yasm_arch *arch, const char *id, unsigned long line)
{
}
yasm_arch_check_id_retval
-yasm_lc3b__parse_check_id(unsigned long data[4], const char *id,
- unsigned long lindex)
+yasm_lc3b__parse_check_id(yasm_arch *arch, unsigned long data[4],
+ const char *id, unsigned long line)
{
const char *oid = id;
/*const char *marker;*/
#include "x86arch.h"
-unsigned char yasm_x86_LTX_mode_bits = 0;
-unsigned long yasm_x86__cpu_enabled;
-unsigned int yasm_x86_amd64_machine;
+yasm_arch_module yasm_x86_LTX_arch;
-static int
-x86_initialize(const char *machine)
+
+static /*@only@*/ yasm_arch *
+x86_create(const char *machine)
{
+ yasm_arch_x86 *arch_x86;
+ unsigned int amd64_machine;
+
if (yasm__strcasecmp(machine, "x86") == 0)
- yasm_x86_amd64_machine = 0;
+ amd64_machine = 0;
else if (yasm__strcasecmp(machine, "amd64") == 0)
- yasm_x86_amd64_machine = 1;
+ amd64_machine = 1;
else
- return 1;
+ return NULL;
- yasm_x86__cpu_enabled = ~CPU_Any;
- return 0;
+ arch_x86 = yasm_xmalloc(sizeof(yasm_arch_x86));
+
+ arch_x86->arch.module = &yasm_x86_LTX_arch;
+
+ arch_x86->cpu_enabled = ~CPU_Any;
+ arch_x86->amd64_machine = amd64_machine;
+ arch_x86->mode_bits = 0;
+
+ return (yasm_arch *)arch_x86;
}
static void
-x86_cleanup(void)
+x86_destroy(/*@only@*/ yasm_arch *arch)
+{
+ yasm_xfree(arch);
+}
+
+static const char *
+x86_get_machine(const yasm_arch *arch)
{
+ const yasm_arch_x86 *arch_x86 = (const yasm_arch_x86 *)arch;
+ if (arch_x86->amd64_machine)
+ return "amd64";
+ else
+ return "x86";
}
-int
-yasm_x86__parse_directive(const char *name, yasm_valparamhead *valparams,
- /*@unused@*/ /*@null@*/
- yasm_valparamhead *objext_valparams,
- /*@unused@*/ yasm_sectionhead *headp,
- unsigned long lindex)
+static int
+x86_set_var(yasm_arch *arch, const char *var, unsigned long val)
{
+ yasm_arch_x86 *arch_x86 = (yasm_arch_x86 *)arch;
+ if (yasm__strcasecmp(var, "mode_bits") == 0)
+ arch_x86->mode_bits = val;
+ else
+ return 1;
+ return 0;
+}
+
+static int
+x86_parse_directive(yasm_arch *arch, const char *name,
+ yasm_valparamhead *valparams,
+ /*@unused@*/ /*@null@*/
+ yasm_valparamhead *objext_valparams,
+ /*@unused@*/ yasm_object *object, unsigned long line)
+{
+ yasm_arch_x86 *arch_x86 = (yasm_arch_x86 *)arch;
yasm_valparam *vp;
const yasm_intnum *intn;
long lval;
(intn = yasm_expr_get_intnum(&vp->param, NULL)) != NULL &&
(lval = yasm_intnum_get_int(intn)) &&
(lval == 16 || lval == 32 || lval == 64))
- yasm_x86_LTX_mode_bits = (unsigned char)lval;
+ arch_x86->mode_bits = (unsigned char)lval;
else
- yasm__error(lindex, N_("invalid argument to [%s]"), "BITS");
+ yasm__error(line, N_("invalid argument to [%s]"), "BITS");
return 0;
} else
return 1;
}
unsigned int
-yasm_x86__get_reg_size(unsigned long reg)
+yasm_x86__get_reg_size(yasm_arch *arch, unsigned long reg)
{
switch ((x86_expritem_reg_size)(reg & ~0xFUL)) {
case X86_REG8:
return 0;
}
-void
-yasm_x86__reg_print(FILE *f, unsigned long reg)
+static void
+x86_reg_print(yasm_arch *arch, unsigned long reg, FILE *f)
{
static const char *name8[] = {"al","cl","dl","bl","ah","ch","dh","bh"};
static const char *name8x[] = {
}
}
-void
-yasm_x86__segreg_print(FILE *f, unsigned long segreg)
+static void
+x86_segreg_print(yasm_arch *arch, unsigned long segreg, FILE *f)
{
static const char *name[] = {"es","cs","ss","ds","fs","gs"};
fprintf(f, "%s", name[segreg&7]);
}
-void
-yasm_x86__parse_prefix(yasm_bytecode *bc, const unsigned long data[4],
- unsigned long lindex)
+static void
+x86_parse_prefix(yasm_arch *arch, yasm_bytecode *bc,
+ const unsigned long data[4], unsigned long line)
{
switch((x86_parse_insn_prefix)data[0]) {
case X86_LOCKREP:
- yasm_x86__bc_insn_set_lockrep_prefix(bc, data[1] & 0xff,
- lindex);
+ yasm_x86__bc_insn_set_lockrep_prefix(bc, data[1] & 0xff, line);
break;
case X86_ADDRSIZE:
yasm_x86__bc_insn_addrsize_override(bc, data[1]);
}
}
-void
-yasm_x86__parse_seg_prefix(yasm_bytecode *bc, unsigned long segreg,
- unsigned long lindex)
+static void
+x86_parse_seg_prefix(yasm_arch *arch, yasm_bytecode *bc, unsigned long segreg,
+ unsigned long line)
{
yasm_x86__ea_set_segment(yasm_x86__bc_insn_get_ea(bc),
- (unsigned char)(segreg>>8), lindex);
+ (unsigned char)(segreg>>8), line);
}
-void
-yasm_x86__parse_seg_override(yasm_effaddr *ea, unsigned long segreg,
- unsigned long lindex)
+static void
+x86_parse_seg_override(yasm_arch *arch, yasm_effaddr *ea,
+ unsigned long segreg, unsigned long line)
{
- yasm_x86__ea_set_segment(ea, (unsigned char)(segreg>>8), lindex);
+ yasm_x86__ea_set_segment(ea, (unsigned char)(segreg>>8), line);
}
/* Define x86 machines -- see arch.h for details */
};
/* Define arch structure -- see arch.h for details */
-yasm_arch yasm_x86_LTX_arch = {
+yasm_arch_module yasm_x86_LTX_arch = {
YASM_ARCH_VERSION,
"x86 (IA-32 and derivatives), AMD64",
"x86",
- x86_initialize,
- x86_cleanup,
+ x86_create,
+ x86_destroy,
+ x86_get_machine,
+ x86_set_var,
yasm_x86__parse_cpu,
yasm_x86__parse_check_id,
- yasm_x86__parse_directive,
+ x86_parse_directive,
yasm_x86__parse_insn,
- yasm_x86__parse_prefix,
- yasm_x86__parse_seg_prefix,
- yasm_x86__parse_seg_override,
- X86_BYTECODE_TYPE_MAX,
- yasm_x86__bc_delete,
- yasm_x86__bc_print,
- yasm_x86__bc_resolve,
- yasm_x86__bc_tobytes,
+ x86_parse_prefix,
+ x86_parse_seg_prefix,
+ x86_parse_seg_override,
yasm_x86__floatnum_tobytes,
yasm_x86__intnum_tobytes,
yasm_x86__get_reg_size,
- yasm_x86__reg_print,
- yasm_x86__segreg_print,
- yasm_x86__ea_new_expr,
- NULL, /* x86_ea_data_delete */
- yasm_x86__ea_data_print,
+ x86_reg_print,
+ x86_segreg_print,
+ yasm_x86__ea_create_expr,
x86_machines,
"x86",
2
#define CPU_64 (1UL<<24) /* Only available in 64-bit mode */
#define CPU_Not64 (1UL<<25) /* Not available (invalid) in 64-bit mode */
-/* What instructions/features are enabled? */
-extern unsigned long yasm_x86__cpu_enabled;
+typedef struct yasm_arch_x86 {
+ yasm_arch arch; /* base structure */
-typedef enum {
- X86_BC_INSN = YASM_BYTECODE_TYPE_BASE,
- X86_BC_JMP
-} x86_bytecode_type;
-#define X86_BYTECODE_TYPE_MAX X86_BC_JMP+1
+ /* What instructions/features are enabled? */
+ unsigned long cpu_enabled;
+ unsigned int amd64_machine;
+ unsigned char mode_bits;
+} yasm_arch_x86;
/* 0-15 (low 4 bits) used for register number, stored in same data area.
* Note 8-15 are only valid for some registers, and only in 64-bit mode.
x86_rex_bit_pos rexbit);
void yasm_x86__ea_set_segment(/*@null@*/ yasm_effaddr *ea,
- unsigned int segment, unsigned long lindex);
+ unsigned int segment, unsigned long line);
void yasm_x86__ea_set_disponly(yasm_effaddr *ea);
-yasm_effaddr *yasm_x86__ea_new_reg(unsigned long reg, unsigned char *rex,
- unsigned int bits);
-yasm_effaddr *yasm_x86__ea_new_imm(/*@keep@*/ yasm_expr *imm,
- unsigned int im_len);
-yasm_effaddr *yasm_x86__ea_new_expr(/*@keep@*/ yasm_expr *e);
+yasm_effaddr *yasm_x86__ea_create_reg(unsigned long reg, unsigned char *rex,
+ unsigned int bits);
+yasm_effaddr *yasm_x86__ea_create_imm
+ (/*@keep@*/ yasm_expr *imm, unsigned int im_len);
+yasm_effaddr *yasm_x86__ea_create_expr(yasm_arch *arch,
+ /*@keep@*/ yasm_expr *e);
/*@observer@*/ /*@null@*/ yasm_effaddr *yasm_x86__bc_insn_get_ea
(/*@null@*/ yasm_bytecode *bc);
unsigned int addrsize);
void yasm_x86__bc_insn_set_lockrep_prefix(yasm_bytecode *bc,
unsigned int prefix,
- unsigned long lindex);
+ unsigned long line);
/* Structure with *all* inputs passed to x86_bytecode_new_insn().
* IMPORTANT: ea_ptr and im_ptr cannot be reused or freed after calling the
* function (it doesn't make a copy).
*/
typedef struct x86_new_insn_data {
- unsigned long lindex;
+ unsigned long line;
/*@keep@*/ /*@null@*/ yasm_effaddr *ea;
/*@null@*/ /*@dependent@*/ yasm_symrec *ea_origin;
/*@keep@*/ /*@null@*/ yasm_expr *imm;
unsigned char signext_imm8_op;
} x86_new_insn_data;
-yasm_bytecode *yasm_x86__bc_new_insn(x86_new_insn_data *d);
+yasm_bytecode *yasm_x86__bc_create_insn(yasm_arch *arch, x86_new_insn_data *d);
/* Structure with *all* inputs passed to x86_bytecode_new_jmp().
* Pass 0 for the opcode_len if that version of the opcode doesn't exist.
*/
typedef struct x86_new_jmp_data {
- unsigned long lindex;
+ unsigned long line;
/*@keep@*/ yasm_expr *target;
/*@dependent@*/ yasm_symrec *origin;
x86_jmp_opcode_sel op_sel;
unsigned char opersize;
} x86_new_jmp_data;
-yasm_bytecode *yasm_x86__bc_new_jmp(x86_new_jmp_data *d);
-
-extern unsigned char yasm_x86_LTX_mode_bits;
-
-void yasm_x86__bc_delete(yasm_bytecode *bc);
-void yasm_x86__bc_print(FILE *f, int indent_level, const yasm_bytecode *bc);
-yasm_bc_resolve_flags yasm_x86__bc_resolve
- (yasm_bytecode *bc, int save, const yasm_section *sect,
- yasm_calc_bc_dist_func calc_bc_dist);
-int yasm_x86__bc_tobytes(yasm_bytecode *bc, unsigned char **bufp,
- const yasm_section *sect, void *d,
- yasm_output_expr_func output_expr);
+yasm_bytecode *yasm_x86__bc_create_jmp(yasm_arch *arch, x86_new_jmp_data *d);
/* Check an effective address. Returns 0 if EA was successfully determined,
* 1 if invalid EA, or 2 if indeterminate EA.
unsigned char *v_sib, unsigned char *n_sib, unsigned char *pcrel,
unsigned char *rex, yasm_calc_bc_dist_func calc_bc_dist);
-void yasm_x86__parse_cpu(const char *cpuid, unsigned long lindex);
+void yasm_x86__parse_cpu(yasm_arch *arch, const char *cpuid,
+ unsigned long line);
yasm_arch_check_id_retval yasm_x86__parse_check_id
- (unsigned long data[2], const char *id, unsigned long lindex);
-
-int yasm_x86__parse_directive(const char *name, yasm_valparamhead *valparams,
- /*@null@*/ yasm_valparamhead *objext_valparams,
- yasm_sectionhead *headp, unsigned long lindex);
+ (yasm_arch *arch, unsigned long data[2], const char *id,
+ unsigned long line);
/*@null@*/ yasm_bytecode *yasm_x86__parse_insn
- (const unsigned long data[2], int num_operands,
- /*@null@*/ yasm_insn_operandhead *operands, yasm_section *cur_section,
- /*@null@*/ yasm_bytecode *prev_bc, unsigned long lindex);
-
-void yasm_x86__parse_prefix(yasm_bytecode *bc, const unsigned long data[4],
- unsigned long lindex);
-
-void yasm_x86__parse_seg_prefix(yasm_bytecode *bc, unsigned long segreg,
- unsigned long lindex);
-
-void yasm_x86__parse_seg_override(yasm_effaddr *ea, unsigned long segreg,
- unsigned long lindex);
-
-int yasm_x86__floatnum_tobytes(const yasm_floatnum *flt, unsigned char *buf,
- size_t destsize, size_t valsize, size_t shift,
- int warn, unsigned long lindex);
-int yasm_x86__intnum_tobytes(const yasm_intnum *intn, unsigned char *buf,
- size_t destsize, size_t valsize, int shift,
- const yasm_bytecode *bc, int rel, int warn,
- unsigned long lindex);
-
-unsigned int yasm_x86__get_reg_size(unsigned long reg);
-
-void yasm_x86__reg_print(FILE *f, unsigned long reg);
-
-void yasm_x86__segreg_print(FILE *f, unsigned long segreg);
-
-void yasm_x86__ea_data_print(FILE *f, int indent_level,
- const yasm_effaddr *ea);
-
+ (yasm_arch *arch, const unsigned long data[2], int num_operands,
+ /*@null@*/ yasm_insn_operandhead *operands, yasm_bytecode *prev_bc,
+ unsigned long line);
+
+int yasm_x86__floatnum_tobytes
+ (yasm_arch *arch, const yasm_floatnum *flt, unsigned char *buf,
+ size_t destsize, size_t valsize, size_t shift, int warn,
+ unsigned long line);
+int yasm_x86__intnum_tobytes
+ (yasm_arch *arch, const yasm_intnum *intn, unsigned char *buf,
+ size_t destsize, size_t valsize, int shift, const yasm_bytecode *bc,
+ int rel, int warn, unsigned long line);
+
+unsigned int yasm_x86__get_reg_size(yasm_arch *arch, unsigned long reg);
#endif
#include "x86arch.h"
+/* Effective address type */
+
typedef struct x86_effaddr {
yasm_effaddr ea; /* base structure */
/* How the spare (register) bits in Mod/RM are handled:
* Even if valid_modrm=0, the spare bits are still valid (don't overwrite!)
- * They're set in bytecode_new_insn().
+ * They're set in bytecode_create_insn().
*/
unsigned char modrm;
unsigned char valid_modrm; /* 1 if Mod/RM byte currently valid, 0 if not */
unsigned char pcrel; /* 1 if PC-relative transformation needed */
} x86_effaddr;
+/* Bytecode types */
+
typedef struct x86_insn {
yasm_bytecode bc; /* base structure */
unsigned char mode_bits;
} x86_jmp;
+/* Effective address callback function prototypes */
+
+static void x86_ea_destroy(yasm_effaddr *ea);
+static void x86_ea_print(const yasm_effaddr *ea, FILE *f, int indent_level);
+
+/* Bytecode callback function prototypes */
+
+static void x86_bc_insn_destroy(yasm_bytecode *bc);
+static void x86_bc_insn_print(const yasm_bytecode *bc, FILE *f,
+ int indent_level);
+static yasm_bc_resolve_flags x86_bc_insn_resolve
+ (yasm_bytecode *bc, int save, yasm_calc_bc_dist_func calc_bc_dist);
+static int x86_bc_insn_tobytes(yasm_bytecode *bc, unsigned char **bufp,
+ void *d, yasm_output_expr_func output_expr,
+ /*@null@*/ yasm_output_reloc_func output_reloc);
+
+static void x86_bc_jmp_destroy(yasm_bytecode *bc);
+static void x86_bc_jmp_print(const yasm_bytecode *bc, FILE *f,
+ int indent_level);
+static yasm_bc_resolve_flags x86_bc_jmp_resolve
+ (yasm_bytecode *bc, int save, yasm_calc_bc_dist_func calc_bc_dist);
+static int x86_bc_jmp_tobytes(yasm_bytecode *bc, unsigned char **bufp,
+ void *d, yasm_output_expr_func output_expr,
+ /*@null@*/ yasm_output_reloc_func output_reloc);
+
+/* Effective address callback structures */
+
+static const yasm_effaddr_callback x86_ea_callback = {
+ x86_ea_destroy,
+ x86_ea_print
+};
+
+/* Bytecode callback structures */
+
+static const yasm_bytecode_callback x86_bc_callback_insn = {
+ x86_bc_insn_destroy,
+ x86_bc_insn_print,
+ x86_bc_insn_resolve,
+ x86_bc_insn_tobytes
+};
+
+static const yasm_bytecode_callback x86_bc_callback_jmp = {
+ x86_bc_jmp_destroy,
+ x86_bc_jmp_print,
+ x86_bc_jmp_resolve,
+ x86_bc_jmp_tobytes
+};
int
yasm_x86__set_rex_from_reg(unsigned char *rex, unsigned char *low3,
/*@-compmempass -mustfree@*/
yasm_bytecode *
-yasm_x86__bc_new_insn(x86_new_insn_data *d)
+yasm_x86__bc_create_insn(yasm_arch *arch, x86_new_insn_data *d)
{
+ yasm_arch_x86 *arch_x86 = (yasm_arch_x86 *)arch;
x86_insn *insn;
- insn = (x86_insn *)yasm_bc_new_common((yasm_bytecode_type)X86_BC_INSN,
- sizeof(x86_insn), d->lindex);
+ insn = (x86_insn *)yasm_bc_create_common(&x86_bc_callback_insn,
+ sizeof(x86_insn), d->line);
insn->ea = (x86_effaddr *)d->ea;
if (d->ea) {
}
if (d->imm) {
- insn->imm = yasm_imm_new_expr(d->imm);
+ insn->imm = yasm_imm_create_expr(d->imm);
insn->imm->len = d->im_len;
insn->imm->sign = d->im_sign;
} else
insn->shift_op = d->shift_op;
insn->signext_imm8_op = d->signext_imm8_op;
- insn->mode_bits = yasm_x86_LTX_mode_bits;
+ insn->mode_bits = arch_x86->mode_bits;
return (yasm_bytecode *)insn;
}
/*@-compmempass -mustfree@*/
yasm_bytecode *
-yasm_x86__bc_new_jmp(x86_new_jmp_data *d)
+yasm_x86__bc_create_jmp(yasm_arch *arch, x86_new_jmp_data *d)
{
+ yasm_arch_x86 *arch_x86 = (yasm_arch_x86 *)arch;
x86_jmp *jmp;
- jmp = (x86_jmp *) yasm_bc_new_common((yasm_bytecode_type)X86_BC_JMP,
- sizeof(x86_jmp), d->lindex);
+ jmp = (x86_jmp *) yasm_bc_create_common(&x86_bc_callback_jmp,
+ sizeof(x86_jmp), d->line);
jmp->target = d->target;
jmp->origin = d->origin;
jmp->op_sel = d->op_sel;
if ((d->op_sel == JMP_SHORT_FORCED) && (d->near_op_len == 0))
- yasm__error(d->lindex,
+ yasm__error(d->line,
N_("no SHORT form of that jump instruction exists"));
if ((d->op_sel == JMP_NEAR_FORCED) && (d->short_op_len == 0))
- yasm__error(d->lindex,
+ yasm__error(d->line,
N_("no NEAR form of that jump instruction exists"));
jmp->shortop.opcode[0] = d->short_op[0];
jmp->opersize = d->opersize;
jmp->lockrep_pre = 0;
- jmp->mode_bits = yasm_x86_LTX_mode_bits;
+ jmp->mode_bits = arch_x86->mode_bits;
return (yasm_bytecode *)jmp;
}
void
yasm_x86__ea_set_segment(yasm_effaddr *ea, unsigned int segment,
- unsigned long lindex)
+ unsigned long line)
{
x86_effaddr *x86_ea = (x86_effaddr *)ea;
return;
if (segment != 0 && x86_ea->segment != 0)
- yasm__warning(YASM_WARN_GENERAL, lindex,
+ yasm__warning(YASM_WARN_GENERAL, line,
N_("multiple segment overrides, using leftmost"));
x86_ea->segment = (unsigned char)segment;
}
yasm_effaddr *
-yasm_x86__ea_new_reg(unsigned long reg, unsigned char *rex, unsigned int bits)
+yasm_x86__ea_create_reg(unsigned long reg, unsigned char *rex,
+ unsigned int bits)
{
x86_effaddr *x86_ea;
unsigned char rm;
x86_ea = yasm_xmalloc(sizeof(x86_effaddr));
+ x86_ea->ea.callback = &x86_ea_callback;
x86_ea->ea.disp = (yasm_expr *)NULL;
x86_ea->ea.len = 0;
x86_ea->ea.nosplit = 0;
}
yasm_effaddr *
-yasm_x86__ea_new_expr(yasm_expr *e)
+yasm_x86__ea_create_expr(yasm_arch *arch, yasm_expr *e)
{
x86_effaddr *x86_ea;
x86_ea = yasm_xmalloc(sizeof(x86_effaddr));
+ x86_ea->ea.callback = &x86_ea_callback;
x86_ea->ea.disp = e;
x86_ea->ea.len = 0;
x86_ea->ea.nosplit = 0;
/*@-compmempass@*/
yasm_effaddr *
-yasm_x86__ea_new_imm(yasm_expr *imm, unsigned int im_len)
+yasm_x86__ea_create_imm(yasm_expr *imm, unsigned int im_len)
{
x86_effaddr *x86_ea;
x86_ea = yasm_xmalloc(sizeof(x86_effaddr));
+ x86_ea->ea.callback = &x86_ea_callback;
x86_ea->ea.disp = imm;
x86_ea->ea.len = (unsigned char)im_len;
x86_ea->ea.nosplit = 0;
if (!bc)
return NULL;
- if ((x86_bytecode_type)bc->type != X86_BC_INSN)
+ if (bc->callback != &x86_bc_callback_insn)
yasm_internal_error(N_("Trying to get EA of non-instruction"));
return (yasm_effaddr *)(((x86_insn *)bc)->ea);
void
yasm_x86__bc_insn_opersize_override(yasm_bytecode *bc, unsigned int opersize)
{
- x86_insn *insn;
- x86_jmp *jmp;
-
if (!bc)
return;
- switch ((x86_bytecode_type)bc->type) {
- case X86_BC_INSN:
- insn = (x86_insn *)bc;
- insn->opersize = (unsigned char)opersize;
- break;
- case X86_BC_JMP:
- jmp = (x86_jmp *)bc;
- jmp->opersize = (unsigned char)opersize;
- break;
- default:
- yasm_internal_error(
- N_("OperSize override applied to non-instruction"));
- }
+ if (bc->callback == &x86_bc_callback_insn) {
+ x86_insn *insn = (x86_insn *)bc;
+ insn->opersize = (unsigned char)opersize;
+ } else if (bc->callback == &x86_bc_callback_jmp) {
+ x86_jmp *jmp = (x86_jmp *)bc;
+ jmp->opersize = (unsigned char)opersize;
+ } else
+ yasm_internal_error(N_("OperSize override applied to non-instruction"));
}
void
yasm_x86__bc_insn_addrsize_override(yasm_bytecode *bc, unsigned int addrsize)
{
- x86_insn *insn;
- x86_jmp *jmp;
-
if (!bc)
return;
- switch ((x86_bytecode_type)bc->type) {
- case X86_BC_INSN:
- insn = (x86_insn *)bc;
- insn->addrsize = (unsigned char)addrsize;
- break;
- case X86_BC_JMP:
- jmp = (x86_jmp *)bc;
- jmp->addrsize = (unsigned char)addrsize;
- break;
- default:
- yasm_internal_error(
- N_("AddrSize override applied to non-instruction"));
- }
+ if (bc->callback == &x86_bc_callback_insn) {
+ x86_insn *insn = (x86_insn *)bc;
+ insn->addrsize = (unsigned char)addrsize;
+ } else if (bc->callback == &x86_bc_callback_jmp) {
+ x86_jmp *jmp = (x86_jmp *)bc;
+ jmp->addrsize = (unsigned char)addrsize;
+ } else
+ yasm_internal_error(N_("AddrSize override applied to non-instruction"));
}
void
yasm_x86__bc_insn_set_lockrep_prefix(yasm_bytecode *bc, unsigned int prefix,
- unsigned long lindex)
+ unsigned long line)
{
- x86_insn *insn;
- x86_jmp *jmp;
unsigned char *lockrep_pre = (unsigned char *)NULL;
if (!bc)
return;
- switch ((x86_bytecode_type)bc->type) {
- case X86_BC_INSN:
- insn = (x86_insn *)bc;
- lockrep_pre = &insn->lockrep_pre;
- break;
- case X86_BC_JMP:
- jmp = (x86_jmp *)bc;
- lockrep_pre = &jmp->lockrep_pre;
- break;
- default:
- yasm_internal_error(
- N_("LockRep prefix applied to non-instruction"));
- }
+ if (bc->callback == &x86_bc_callback_insn) {
+ x86_insn *insn = (x86_insn *)bc;
+ lockrep_pre = &insn->lockrep_pre;
+ } else if (bc->callback == &x86_bc_callback_jmp) {
+ x86_jmp *jmp = (x86_jmp *)bc;
+ lockrep_pre = &jmp->lockrep_pre;
+ } else
+ yasm_internal_error(N_("LockRep prefix applied to non-instruction"));
if (*lockrep_pre != 0)
- yasm__warning(YASM_WARN_GENERAL, lindex,
+ yasm__warning(YASM_WARN_GENERAL, line,
N_("multiple LOCK or REP prefixes, using leftmost"));
*lockrep_pre = (unsigned char)prefix;
}
-void
-yasm_x86__bc_delete(yasm_bytecode *bc)
+static void
+x86_bc_insn_destroy(yasm_bytecode *bc)
{
- x86_insn *insn;
- x86_jmp *jmp;
-
- switch ((x86_bytecode_type)bc->type) {
- case X86_BC_INSN:
- insn = (x86_insn *)bc;
- if (insn->ea)
- yasm_ea_delete((yasm_effaddr *)insn->ea);
- if (insn->imm) {
- yasm_expr_delete(insn->imm->val);
- yasm_xfree(insn->imm);
- }
- break;
- case X86_BC_JMP:
- jmp = (x86_jmp *)bc;
- yasm_expr_delete(jmp->target);
- break;
+ x86_insn *insn = (x86_insn *)bc;
+ if (insn->ea)
+ yasm_ea_destroy((yasm_effaddr *)insn->ea);
+ if (insn->imm) {
+ yasm_expr_destroy(insn->imm->val);
+ yasm_xfree(insn->imm);
}
}
-void
-yasm_x86__ea_data_print(FILE *f, int indent_level, const yasm_effaddr *ea)
+static void
+x86_bc_jmp_destroy(yasm_bytecode *bc)
+{
+ x86_jmp *jmp = (x86_jmp *)bc;
+ yasm_expr_destroy(jmp->target);
+}
+
+static void
+x86_ea_destroy(yasm_effaddr *ea)
+{
+}
+
+static void
+x86_ea_print(const yasm_effaddr *ea, FILE *f, int indent_level)
{
const x86_effaddr *x86_ea = (const x86_effaddr *)ea;
fprintf(f, "%*sSegmentOv=%02x PCRel=%u\n", indent_level, "",
(unsigned int)x86_ea->need_sib);
}
-void
-yasm_x86__bc_print(FILE *f, int indent_level, const yasm_bytecode *bc)
+static void
+x86_bc_insn_print(const yasm_bytecode *bc, FILE *f, int indent_level)
{
- const x86_insn *insn;
- const x86_jmp *jmp;
-
- switch ((x86_bytecode_type)bc->type) {
- case X86_BC_INSN:
- insn = (const x86_insn *)bc;
- fprintf(f, "%*s_Instruction_\n", indent_level, "");
- fprintf(f, "%*sEffective Address:", indent_level, "");
- if (insn->ea) {
- fprintf(f, "\n");
- yasm_ea_print(f, indent_level+1, (yasm_effaddr *)insn->ea);
- } else
- fprintf(f, " (nil)\n");
- fprintf(f, "%*sImmediate Value:", indent_level, "");
- if (!insn->imm)
- fprintf(f, " (nil)\n");
- else {
- indent_level++;
- fprintf(f, "\n%*sVal=", indent_level, "");
- if (insn->imm->val)
- yasm_expr_print(f, insn->imm->val);
- else
- fprintf(f, "(nil-SHOULDN'T HAPPEN)");
- fprintf(f, "\n");
- fprintf(f, "%*sLen=%u, Sign=%u\n", indent_level, "",
- (unsigned int)insn->imm->len,
- (unsigned int)insn->imm->sign);
- indent_level--;
- }
- fprintf(f, "%*sOpcode: %02x %02x %02x OpLen=%u\n", indent_level,
- "", (unsigned int)insn->opcode[0],
- (unsigned int)insn->opcode[1],
- (unsigned int)insn->opcode[2],
- (unsigned int)insn->opcode_len);
- fprintf(f,
- "%*sAddrSize=%u OperSize=%u LockRepPre=%02x REX=%03o\n",
- indent_level, "",
- (unsigned int)insn->addrsize,
- (unsigned int)insn->opersize,
- (unsigned int)insn->lockrep_pre,
- (unsigned int)insn->rex);
- fprintf(f, "%*sShiftOp=%u BITS=%u\n", indent_level, "",
- (unsigned int)insn->shift_op,
- (unsigned int)insn->mode_bits);
+ const x86_insn *insn = (const x86_insn *)bc;
+
+ fprintf(f, "%*s_Instruction_\n", indent_level, "");
+ fprintf(f, "%*sEffective Address:", indent_level, "");
+ if (insn->ea) {
+ fprintf(f, "\n");
+ yasm_ea_print((yasm_effaddr *)insn->ea, f, indent_level+1);
+ } else
+ fprintf(f, " (nil)\n");
+ fprintf(f, "%*sImmediate Value:", indent_level, "");
+ if (!insn->imm)
+ fprintf(f, " (nil)\n");
+ else {
+ indent_level++;
+ fprintf(f, "\n%*sVal=", indent_level, "");
+ if (insn->imm->val)
+ yasm_expr_print(insn->imm->val, f);
+ else
+ fprintf(f, "(nil-SHOULDN'T HAPPEN)");
+ fprintf(f, "\n");
+ fprintf(f, "%*sLen=%u, Sign=%u\n", indent_level, "",
+ (unsigned int)insn->imm->len,
+ (unsigned int)insn->imm->sign);
+ indent_level--;
+ }
+ fprintf(f, "%*sOpcode: %02x %02x %02x OpLen=%u\n", indent_level,
+ "", (unsigned int)insn->opcode[0],
+ (unsigned int)insn->opcode[1],
+ (unsigned int)insn->opcode[2],
+ (unsigned int)insn->opcode_len);
+ fprintf(f,
+ "%*sAddrSize=%u OperSize=%u LockRepPre=%02x REX=%03o\n",
+ indent_level, "",
+ (unsigned int)insn->addrsize,
+ (unsigned int)insn->opersize,
+ (unsigned int)insn->lockrep_pre,
+ (unsigned int)insn->rex);
+ fprintf(f, "%*sShiftOp=%u BITS=%u\n", indent_level, "",
+ (unsigned int)insn->shift_op,
+ (unsigned int)insn->mode_bits);
+}
+
+static void
+x86_bc_jmp_print(const yasm_bytecode *bc, FILE *f, int indent_level)
+{
+ const x86_jmp *jmp = (const x86_jmp *)bc;
+
+ fprintf(f, "%*s_Jump_\n", indent_level, "");
+ fprintf(f, "%*sTarget=", indent_level, "");
+ yasm_expr_print(jmp->target, f);
+ fprintf(f, "%*sOrigin=\n", indent_level, "");
+ yasm_symrec_print(jmp->origin, f, indent_level+1);
+ fprintf(f, "\n%*sShort Form:\n", indent_level, "");
+ if (jmp->shortop.opcode_len == 0)
+ fprintf(f, "%*sNone\n", indent_level+1, "");
+ else
+ fprintf(f, "%*sOpcode: %02x %02x %02x OpLen=%u\n",
+ indent_level+1, "",
+ (unsigned int)jmp->shortop.opcode[0],
+ (unsigned int)jmp->shortop.opcode[1],
+ (unsigned int)jmp->shortop.opcode[2],
+ (unsigned int)jmp->shortop.opcode_len);
+ fprintf(f, "%*sNear Form:\n", indent_level, "");
+ if (jmp->nearop.opcode_len == 0)
+ fprintf(f, "%*sNone\n", indent_level+1, "");
+ else
+ fprintf(f, "%*sOpcode: %02x %02x %02x OpLen=%u\n",
+ indent_level+1, "",
+ (unsigned int)jmp->nearop.opcode[0],
+ (unsigned int)jmp->nearop.opcode[1],
+ (unsigned int)jmp->nearop.opcode[2],
+ (unsigned int)jmp->nearop.opcode_len);
+ fprintf(f, "%*sFar Form:\n", indent_level, "");
+ if (jmp->farop.opcode_len == 0)
+ fprintf(f, "%*sNone\n", indent_level+1, "");
+ else
+ fprintf(f, "%*sOpcode: %02x %02x %02x OpLen=%u\n",
+ indent_level+1, "",
+ (unsigned int)jmp->farop.opcode[0],
+ (unsigned int)jmp->farop.opcode[1],
+ (unsigned int)jmp->farop.opcode[2],
+ (unsigned int)jmp->farop.opcode_len);
+ fprintf(f, "%*sOpSel=", indent_level, "");
+ switch (jmp->op_sel) {
+ case JMP_NONE:
+ fprintf(f, "None");
break;
- case X86_BC_JMP:
- jmp = (const x86_jmp *)bc;
- fprintf(f, "%*s_Jump_\n", indent_level, "");
- fprintf(f, "%*sTarget=", indent_level, "");
- yasm_expr_print(f, jmp->target);
- fprintf(f, "%*sOrigin=\n", indent_level, "");
- yasm_symrec_print(f, indent_level+1, jmp->origin);
- fprintf(f, "\n%*sShort Form:\n", indent_level, "");
- if (jmp->shortop.opcode_len == 0)
- fprintf(f, "%*sNone\n", indent_level+1, "");
- else
- fprintf(f, "%*sOpcode: %02x %02x %02x OpLen=%u\n",
- indent_level+1, "",
- (unsigned int)jmp->shortop.opcode[0],
- (unsigned int)jmp->shortop.opcode[1],
- (unsigned int)jmp->shortop.opcode[2],
- (unsigned int)jmp->shortop.opcode_len);
- fprintf(f, "%*sNear Form:\n", indent_level, "");
- if (jmp->nearop.opcode_len == 0)
- fprintf(f, "%*sNone\n", indent_level+1, "");
- else
- fprintf(f, "%*sOpcode: %02x %02x %02x OpLen=%u\n",
- indent_level+1, "",
- (unsigned int)jmp->nearop.opcode[0],
- (unsigned int)jmp->nearop.opcode[1],
- (unsigned int)jmp->nearop.opcode[2],
- (unsigned int)jmp->nearop.opcode_len);
- fprintf(f, "%*sFar Form:\n", indent_level, "");
- if (jmp->farop.opcode_len == 0)
- fprintf(f, "%*sNone\n", indent_level+1, "");
- else
- fprintf(f, "%*sOpcode: %02x %02x %02x OpLen=%u\n",
- indent_level+1, "",
- (unsigned int)jmp->farop.opcode[0],
- (unsigned int)jmp->farop.opcode[1],
- (unsigned int)jmp->farop.opcode[2],
- (unsigned int)jmp->farop.opcode_len);
- fprintf(f, "%*sOpSel=", indent_level, "");
- switch (jmp->op_sel) {
- case JMP_NONE:
- fprintf(f, "None");
- break;
- case JMP_SHORT:
- fprintf(f, "Short");
- break;
- case JMP_NEAR:
- fprintf(f, "Near");
- break;
- case JMP_SHORT_FORCED:
- fprintf(f, "Forced Short");
- break;
- case JMP_NEAR_FORCED:
- fprintf(f, "Forced Near");
- break;
- case JMP_FAR:
- fprintf(f, "Far");
- break;
- default:
- fprintf(f, "UNKNOWN!!");
- break;
- }
- fprintf(f, "\n%*sAddrSize=%u OperSize=%u LockRepPre=%02x\n",
- indent_level, "",
- (unsigned int)jmp->addrsize,
- (unsigned int)jmp->opersize,
- (unsigned int)jmp->lockrep_pre);
- fprintf(f, "%*sBITS=%u\n", indent_level, "",
- (unsigned int)jmp->mode_bits);
+ case JMP_SHORT:
+ fprintf(f, "Short");
+ break;
+ case JMP_NEAR:
+ fprintf(f, "Near");
+ break;
+ case JMP_SHORT_FORCED:
+ fprintf(f, "Forced Short");
+ break;
+ case JMP_NEAR_FORCED:
+ fprintf(f, "Forced Near");
+ break;
+ case JMP_FAR:
+ fprintf(f, "Far");
+ break;
+ default:
+ fprintf(f, "UNKNOWN!!");
break;
}
+ fprintf(f, "\n%*sAddrSize=%u OperSize=%u LockRepPre=%02x\n",
+ indent_level, "",
+ (unsigned int)jmp->addrsize,
+ (unsigned int)jmp->opersize,
+ (unsigned int)jmp->lockrep_pre);
+ fprintf(f, "%*sBITS=%u\n", indent_level, "",
+ (unsigned int)jmp->mode_bits);
}
static yasm_bc_resolve_flags
-x86_bc_resolve_insn(x86_insn *insn, unsigned long *len, int save,
- const yasm_section *sect,
+x86_bc_insn_resolve(yasm_bytecode *bc, int save,
yasm_calc_bc_dist_func calc_bc_dist)
{
+ x86_insn *insn = (x86_insn *)bc;
/*@null@*/ yasm_expr *temp;
x86_effaddr *x86_ea = insn->ea;
yasm_effaddr *ea = &x86_ea->ea;
&eat.valid_sib, &eat.need_sib, &eat.pcrel, &insn->rex,
calc_bc_dist)) {
case 1:
- yasm_expr_delete(temp);
+ yasm_expr_destroy(temp);
/* failed, don't bother checking rest of insn */
return YASM_BC_RESOLVE_UNKNOWN_LEN|YASM_BC_RESOLVE_ERROR;
case 2:
- yasm_expr_delete(temp);
+ yasm_expr_destroy(temp);
/* failed, don't bother checking rest of insn */
return YASM_BC_RESOLVE_UNKNOWN_LEN;
default:
- yasm_expr_delete(temp);
+ yasm_expr_destroy(temp);
/* okay */
break;
}
*x86_ea = eat; /* structure copy */
ea->len = displen;
if (displen == 0 && ea->disp) {
- yasm_expr_delete(ea->disp);
+ yasm_expr_destroy(ea->disp);
ea->disp = NULL;
}
}
}
/* Compute length of ea and add to total */
- *len += eat.need_modrm + (eat.need_sib ? 1:0) + displen;
- *len += (eat.segment != 0) ? 1 : 0;
+ bc->len += eat.need_modrm + (eat.need_sib ? 1:0) + displen;
+ bc->len += (eat.segment != 0) ? 1 : 0;
}
if (imm) {
/* We can use the ,1 form: subtract out the imm len
* (as we add it back in below).
*/
- *len -= imm->len;
+ bc->len -= imm->len;
if (save) {
/* Make the ,1 form permanent. */
insn->opcode[0] = insn->opcode[1];
/* Delete imm, as it's not needed. */
- yasm_expr_delete(imm->val);
+ yasm_expr_destroy(imm->val);
yasm_xfree(imm);
insn->imm = (yasm_immval *)NULL;
}
insn->shift_op = 0;
}
- yasm_expr_delete(temp);
+ yasm_expr_destroy(temp);
}
- *len += immlen;
+ bc->len += immlen;
}
- *len += insn->opcode_len;
- *len += (insn->addrsize != 0 && insn->addrsize != insn->mode_bits) ? 1:0;
+ bc->len += insn->opcode_len;
+ bc->len += (insn->addrsize != 0 && insn->addrsize != insn->mode_bits) ? 1:0;
if (insn->opersize != 0 &&
((insn->mode_bits != 64 && insn->opersize != insn->mode_bits) ||
(insn->mode_bits == 64 && insn->opersize == 16)))
- (*len)++;
- *len += (insn->lockrep_pre != 0) ? 1:0;
+ bc->len++;
+ bc->len += (insn->lockrep_pre != 0) ? 1:0;
if (insn->rex != 0xff &&
(insn->rex != 0 ||
(insn->mode_bits == 64 && insn->opersize == 64 &&
insn->def_opersize_64 != 64)))
- (*len)++;
+ bc->len++;
return retval;
}
static yasm_bc_resolve_flags
-x86_bc_resolve_jmp(x86_jmp *jmp, unsigned long *len, int save,
- const yasm_bytecode *bc, const yasm_section *sect,
+x86_bc_jmp_resolve(yasm_bytecode *bc, int save,
yasm_calc_bc_dist_func calc_bc_dist)
{
+ x86_jmp *jmp = (x86_jmp *)bc;
yasm_bc_resolve_flags retval = YASM_BC_RESOLVE_MIN_LEN;
/*@null@*/ yasm_expr *temp;
/*@dependent@*/ /*@null@*/ const yasm_intnum *num;
jrtype = JMP_SHORT;
if (save) {
temp = yasm_expr_copy(jmp->target);
- temp = yasm_expr_new(YASM_EXPR_SUB, yasm_expr_expr(temp),
- yasm_expr_sym(jmp->origin), bc->line);
+ temp = yasm_expr_create(YASM_EXPR_SUB, yasm_expr_expr(temp),
+ yasm_expr_sym(jmp->origin), bc->line);
num = yasm_expr_get_intnum(&temp, calc_bc_dist);
if (!num) {
yasm__error(bc->line,
N_("short jump target external or out of segment"));
- yasm_expr_delete(temp);
+ yasm_expr_destroy(temp);
return YASM_BC_RESOLVE_ERROR | YASM_BC_RESOLVE_UNKNOWN_LEN;
} else {
rel = yasm_intnum_get_int(num);
rel -= jmp->shortop.opcode_len+1;
- yasm_expr_delete(temp);
+ yasm_expr_destroy(temp);
/* does a short form exist? */
if (jmp->shortop.opcode_len == 0) {
yasm__error(bc->line, N_("short jump does not exist"));
* requires offset to be set BEFORE calling calc_len in order for
* this test to be valid.
*/
- temp = yasm_expr_new(YASM_EXPR_SUB, yasm_expr_expr(temp),
- yasm_expr_sym(jmp->origin), bc->line);
+ temp = yasm_expr_create(YASM_EXPR_SUB, yasm_expr_expr(temp),
+ yasm_expr_sym(jmp->origin), bc->line);
num = yasm_expr_get_intnum(&temp, calc_bc_dist);
if (num) {
rel = yasm_intnum_get_int(num);
jrtype = JMP_SHORT;
}
}
- yasm_expr_delete(temp);
+ yasm_expr_destroy(temp);
break;
}
if (jmp->shortop.opcode_len == 0)
return YASM_BC_RESOLVE_UNKNOWN_LEN; /* size not available */
- *len += jmp->shortop.opcode_len + 1;
+ bc->len += jmp->shortop.opcode_len + 1;
break;
case JMP_NEAR:
if (save)
if (jmp->nearop.opcode_len == 0)
return YASM_BC_RESOLVE_UNKNOWN_LEN; /* size not available */
- *len += jmp->nearop.opcode_len;
- *len += (opersize == 16) ? 2 : 4;
+ bc->len += jmp->nearop.opcode_len;
+ bc->len += (opersize == 16) ? 2 : 4;
break;
case JMP_FAR:
if (save)
if (jmp->farop.opcode_len == 0)
return YASM_BC_RESOLVE_UNKNOWN_LEN; /* size not available */
- *len += jmp->farop.opcode_len;
- *len += 2; /* segment */
- *len += (opersize == 16) ? 2 : 4;
+ bc->len += jmp->farop.opcode_len;
+ bc->len += 2; /* segment */
+ bc->len += (opersize == 16) ? 2 : 4;
break;
default:
yasm_internal_error(N_("unknown jump type"));
}
- *len += (jmp->addrsize != 0 && jmp->addrsize != jmp->mode_bits) ? 1:0;
- *len += (jmp->opersize != 0 && jmp->opersize != jmp->mode_bits) ? 1:0;
- *len += (jmp->lockrep_pre != 0) ? 1:0;
+ bc->len += (jmp->addrsize != 0 && jmp->addrsize != jmp->mode_bits) ? 1:0;
+ bc->len += (jmp->opersize != 0 && jmp->opersize != jmp->mode_bits) ? 1:0;
+ bc->len += (jmp->lockrep_pre != 0) ? 1:0;
return retval;
}
-yasm_bc_resolve_flags
-yasm_x86__bc_resolve(yasm_bytecode *bc, int save, const yasm_section *sect,
- yasm_calc_bc_dist_func calc_bc_dist)
-{
- switch ((x86_bytecode_type)bc->type) {
- case X86_BC_INSN:
- return x86_bc_resolve_insn((x86_insn *)bc, &bc->len, save, sect,
- calc_bc_dist);
- case X86_BC_JMP:
- return x86_bc_resolve_jmp((x86_jmp *)bc, &bc->len, save, bc, sect,
- calc_bc_dist);
- default:
- break;
- }
- yasm_internal_error(N_("Didn't handle bytecode type in x86 arch"));
- /*@notreached@*/
- return YASM_BC_RESOLVE_UNKNOWN_LEN;
-}
-
static int
-x86_bc_tobytes_insn(x86_insn *insn, unsigned char **bufp,
- const yasm_section *sect, yasm_bytecode *bc, void *d,
- yasm_output_expr_func output_expr)
+x86_bc_insn_tobytes(yasm_bytecode *bc, unsigned char **bufp, void *d,
+ yasm_output_expr_func output_expr,
+ /*@unused@*/ yasm_output_reloc_func output_reloc)
{
+ x86_insn *insn = (x86_insn *)bc;
/*@null@*/ x86_effaddr *x86_ea = insn->ea;
/*@null@*/ yasm_effaddr *ea = &x86_ea->ea;
yasm_immval *imm = insn->imm;
if (ea->disp) {
if (eat.pcrel) {
ea->disp =
- yasm_expr_new(YASM_EXPR_SUB, yasm_expr_expr(ea->disp),
- yasm_expr_sym(eat.origin), bc->line);
+ yasm_expr_create(YASM_EXPR_SUB,
+ yasm_expr_expr(ea->disp),
+ yasm_expr_sym(eat.origin), bc->line);
if (output_expr(&ea->disp, *bufp, ea->len,
(size_t)(ea->len*8), 0,
- (unsigned long)(*bufp-bufp_orig), sect, bc,
- 1, 1, d))
+ (unsigned long)(*bufp-bufp_orig), bc, 1, 1,
+ d))
return 1;
} else {
if (output_expr(&ea->disp, *bufp, ea->len,
(size_t)(ea->len*8), 0,
- (unsigned long)(*bufp-bufp_orig), sect, bc,
- 0, 1, d))
+ (unsigned long)(*bufp-bufp_orig), bc, 0, 1,
+ d))
return 1;
}
*bufp += ea->len;
/* Immediate (if required) */
if (imm && imm->val) {
if (output_expr(&imm->val, *bufp, imm->len, (size_t)(imm->len*8), 0,
- (unsigned long)(*bufp-bufp_orig), sect, bc, 0, 1, d))
+ (unsigned long)(*bufp-bufp_orig), bc, 0, 1, d))
return 1;
*bufp += imm->len;
}
}
static int
-x86_bc_tobytes_jmp(x86_jmp *jmp, unsigned char **bufp,
- const yasm_section *sect, yasm_bytecode *bc,
- void *d, yasm_output_expr_func output_expr)
+x86_bc_jmp_tobytes(yasm_bytecode *bc, unsigned char **bufp, void *d,
+ yasm_output_expr_func output_expr,
+ /*@unused@*/ yasm_output_reloc_func output_reloc)
{
+ x86_jmp *jmp = (x86_jmp *)bc;
unsigned char opersize;
unsigned int i;
unsigned char *bufp_orig = *bufp;
/* Relative displacement */
jmp->target =
- yasm_expr_new(YASM_EXPR_SUB, yasm_expr_expr(jmp->target),
- yasm_expr_sym(jmp->origin), bc->line);
+ yasm_expr_create(YASM_EXPR_SUB, yasm_expr_expr(jmp->target),
+ yasm_expr_sym(jmp->origin), bc->line);
if (output_expr(&jmp->target, *bufp, 1, 8, 0,
- (unsigned long)(*bufp-bufp_orig), sect, bc, 1, 1,
- d))
+ (unsigned long)(*bufp-bufp_orig), bc, 1, 1, d))
return 1;
*bufp += 1;
break;
/* Relative displacement */
jmp->target =
- yasm_expr_new(YASM_EXPR_SUB, yasm_expr_expr(jmp->target),
- yasm_expr_sym(jmp->origin), bc->line);
+ yasm_expr_create(YASM_EXPR_SUB, yasm_expr_expr(jmp->target),
+ yasm_expr_sym(jmp->origin), bc->line);
i = (opersize == 16) ? 2 : 4;
if (output_expr(&jmp->target, *bufp, i, i*8, 0,
- (unsigned long)(*bufp-bufp_orig), sect, bc, 1, 1,
- d))
+ (unsigned long)(*bufp-bufp_orig), bc, 1, 1, d))
return 1;
*bufp += i;
break;
yasm_internal_error(N_("could not extract segment for far jump"));
i = (opersize == 16) ? 2 : 4;
if (output_expr(&jmp->target, *bufp, i, i*8, 0,
- (unsigned long)(*bufp-bufp_orig), sect, bc, 0, 1,
- d))
+ (unsigned long)(*bufp-bufp_orig), bc, 0, 1, d))
return 1;
*bufp += i;
if (output_expr(&targetseg, *bufp, 2, 2*8, 0,
- (unsigned long)(*bufp-bufp_orig), sect, bc, 0, 1,
- d))
+ (unsigned long)(*bufp-bufp_orig), bc, 0, 1, d))
return 1;
*bufp += 2;
}
int
-yasm_x86__bc_tobytes(yasm_bytecode *bc, unsigned char **bufp,
- const yasm_section *sect, void *d,
- yasm_output_expr_func output_expr)
-{
- switch ((x86_bytecode_type)bc->type) {
- case X86_BC_INSN:
- return x86_bc_tobytes_insn((x86_insn *)bc, bufp, sect, bc, d,
- output_expr);
- case X86_BC_JMP:
- return x86_bc_tobytes_jmp((x86_jmp *)bc, bufp, sect, bc, d,
- output_expr);
- default:
- break;
- }
- return 0;
-}
-
-int
-yasm_x86__intnum_tobytes(const yasm_intnum *intn, unsigned char *buf,
- size_t destsize, size_t valsize, int shift,
- const yasm_bytecode *bc, int rel, int warn,
- unsigned long lindex)
+yasm_x86__intnum_tobytes(yasm_arch *arch, const yasm_intnum *intn,
+ unsigned char *buf, size_t destsize, size_t valsize,
+ int shift, const yasm_bytecode *bc, int rel, int warn,
+ unsigned long line)
{
if (rel) {
yasm_intnum *relnum, *delta;
yasm_internal_error(
N_("tried to do PC-relative offset from invalid sized value"));
relnum = yasm_intnum_copy(intn);
- delta = yasm_intnum_new_uint(bc->len);
- yasm_intnum_calc(relnum, YASM_EXPR_SUB, delta, lindex);
- yasm_intnum_delete(delta);
+ delta = yasm_intnum_create_uint(bc->len);
+ yasm_intnum_calc(relnum, YASM_EXPR_SUB, delta, line);
+ yasm_intnum_destroy(delta);
yasm_intnum_get_sized(relnum, buf, destsize, valsize, shift, 0, warn,
- lindex);
- yasm_intnum_delete(relnum);
+ line);
+ yasm_intnum_destroy(relnum);
} else {
/* Write value out. */
yasm_intnum_get_sized(intn, buf, destsize, valsize, shift, 0, warn,
- lindex);
+ line);
}
return 0;
}
/* overwrite with 0 to eliminate register from displacement expr */
ei->type = YASM_EXPR_INT;
- ei->data.intn = yasm_intnum_new_uint(0);
+ ei->data.intn = yasm_intnum_create_uint(0);
/* we're okay */
return &data->regs[*regnum];
/* overwrite with 0 to eliminate register from displacement expr */
ei->type = YASM_EXPR_INT;
- ei->data.intn = yasm_intnum_new_uint(0);
+ ei->data.intn = yasm_intnum_create_uint(0);
/* we're okay */
return reg16[*regnum];
/* Replace e with expanded reg expn */
ne = e->terms[havereg_expr].data.expn;
e->terms[havereg_expr].type = YASM_EXPR_NONE; /* don't delete it! */
- yasm_expr_delete(e); /* but everything else */
+ yasm_expr_destroy(e); /* but everything else */
e = ne;
/*@-onlytrans@*/
*ep = ne;
e->op = YASM_EXPR_IDENT;
e->numterms = 1;
/* Delete the intnum created by get_reg(). */
- yasm_intnum_delete(e->terms[1].data.intn);
+ yasm_intnum_destroy(e->terms[1].data.intn);
}
break;
case YASM_EXPR_ADD:
* Don't do this if we came from dispreq check above, so
* check *displen.
*/
- yasm_expr_delete(e);
+ yasm_expr_destroy(e);
*ep = (yasm_expr *)NULL;
} else if (dispval >= -128 && dispval <= 127) {
/* It fits into a signed byte */
}
int
-yasm_x86__floatnum_tobytes(const yasm_floatnum *flt, unsigned char *buf,
- size_t destsize, size_t valsize, size_t shift,
- int warn, unsigned long lindex)
+yasm_x86__floatnum_tobytes(yasm_arch *arch, const yasm_floatnum *flt,
+ unsigned char *buf, size_t destsize, size_t valsize,
+ size_t shift, int warn, unsigned long line)
{
if (!yasm_floatnum_check_size(flt, valsize)) {
- yasm__error(lindex, N_("invalid floating point constant size"));
+ yasm__error(line, N_("invalid floating point constant size"));
return 1;
}
- yasm_floatnum_get_sized(flt, buf, destsize, valsize, shift, 0, warn,
- lindex);
+ yasm_floatnum_get_sized(flt, buf, destsize, valsize, shift, 0, warn, line);
return 0;
}
static yasm_bytecode *
-x86_new_jmp(const unsigned long data[4], int num_operands,
+x86_new_jmp(yasm_arch *arch, const unsigned long data[4], int num_operands,
yasm_insn_operandhead *operands, x86_insn_info *jinfo,
- yasm_section *cur_section, /*@null@*/ yasm_bytecode *prev_bc,
- unsigned long lindex)
+ yasm_bytecode *prev_bc, unsigned long line)
{
+ yasm_arch_x86 *arch_x86 = (yasm_arch_x86 *)arch;
x86_new_jmp_data d;
int num_info = (int)(data[1]&0xFF);
x86_insn_info *info = (x86_insn_info *)data[0];
yasm_insn_operand *op;
static const unsigned char size_lookup[] = {0, 8, 16, 32, 64, 80, 128, 0};
- d.lindex = lindex;
+ d.line = line;
/* We know the target is in operand 0, but sanity check for Imm. */
op = yasm_ops_first(operands);
/* Far target needs to become "seg imm:imm". */
if ((jinfo->operands[0] & OPTM_MASK) == OPTM_Far)
- d.target = yasm_expr_new_tree(
- yasm_expr_new_branch(YASM_EXPR_SEG, op->data.val, lindex),
- YASM_EXPR_SEGOFF, yasm_expr_copy(op->data.val), lindex);
+ d.target = yasm_expr_create_tree(
+ yasm_expr_create_branch(YASM_EXPR_SEG, op->data.val, line),
+ YASM_EXPR_SEGOFF, yasm_expr_copy(op->data.val), line);
else
d.target = op->data.val;
/* Need to save jump origin for relative jumps. */
- d.origin = yasm_symrec_define_label("$", cur_section, prev_bc, 0, lindex);
+ d.origin = yasm_symtab_define_label2("$", prev_bc, 0, line);
/* Initially assume no far opcode is available. */
d.far_op_len = 0;
num_info--, info++) {
unsigned long cpu = info->cpu | data[2];
- if ((cpu & CPU_64) && yasm_x86_LTX_mode_bits != 64)
+ if ((cpu & CPU_64) && arch_x86->mode_bits != 64)
continue;
- if ((cpu & CPU_Not64) && yasm_x86_LTX_mode_bits == 64)
+ if ((cpu & CPU_Not64) && arch_x86->mode_bits == 64)
continue;
cpu &= ~(CPU_64 | CPU_Not64);
- if ((yasm_x86__cpu_enabled & cpu) != cpu)
+ if ((arch_x86->cpu_enabled & cpu) != cpu)
continue;
if (info->num_operands == 0)
}
}
- return yasm_x86__bc_new_jmp(&d);
+ return yasm_x86__bc_create_jmp(arch, &d);
}
yasm_bytecode *
-yasm_x86__parse_insn(const unsigned long data[4], int num_operands,
- yasm_insn_operandhead *operands,
- yasm_section *cur_section,
- /*@null@*/ yasm_bytecode *prev_bc, unsigned long lindex)
+yasm_x86__parse_insn(yasm_arch *arch, const unsigned long data[4],
+ int num_operands, yasm_insn_operandhead *operands,
+ yasm_bytecode *prev_bc, unsigned long line)
{
+ yasm_arch_x86 *arch_x86 = (yasm_arch_x86 *)arch;
x86_new_insn_data d;
int num_info = (int)(data[1]&0xFF);
x86_insn_info *info = (x86_insn_info *)data[0];
/* Match CPU */
cpu = info->cpu | data[2];
- if ((cpu & CPU_64) && yasm_x86_LTX_mode_bits != 64)
+ if ((cpu & CPU_64) && arch_x86->mode_bits != 64)
continue;
- if ((cpu & CPU_Not64) && yasm_x86_LTX_mode_bits == 64)
+ if ((cpu & CPU_Not64) && arch_x86->mode_bits == 64)
continue;
cpu &= ~(CPU_64 | CPU_Not64);
- if ((yasm_x86__cpu_enabled & cpu) != cpu)
+ if ((arch_x86->cpu_enabled & cpu) != cpu)
continue;
/* Match # of operands */
/* Match each operand type and size */
for(i = 0, op = yasm_ops_first(operands); op && i<info->num_operands &&
- !mismatch; op = yasm_ops_next(op), i++) {
+ !mismatch; op = yasm_operand_next(op), i++) {
/* Check operand type */
switch ((int)(info->operands[i] & OPT_MASK)) {
case OPT_Imm:
size = size_lookup[(info->operands[i] & OPS_MASK)>>OPS_SHIFT];
if (op->type == YASM_INSN__OPERAND_REG && op->size == 0) {
/* Register size must exactly match */
- if (yasm_x86__get_reg_size(op->data.reg) != size)
+ if (yasm_x86__get_reg_size(arch, op->data.reg) != size)
mismatch = 1;
} else {
if ((info->operands[i] & OPS_RMASK) == OPS_Relaxed) {
if (!found) {
/* Didn't find a matching one */
- yasm__error(lindex, N_("invalid combination of opcode and operands"));
+ yasm__error(line, N_("invalid combination of opcode and operands"));
return NULL;
}
switch ((int)((info->modifiers & MOD_ExtIndex_MASK)
>> MOD_ExtIndex_SHIFT)) {
case 0:
- yasm__error(lindex, N_("mismatch in operand sizes"));
+ yasm__error(line, N_("mismatch in operand sizes"));
break;
case 1:
- yasm__error(lindex, N_("operand size not specified"));
+ yasm__error(line, N_("operand size not specified"));
break;
default:
yasm_internal_error(N_("unrecognized x86 ext mod index"));
/* Shortcut to JmpRel */
if (operands && (info->operands[0] & OPA_MASK) == OPA_JmpRel)
- return x86_new_jmp(data, num_operands, operands, info, cur_section,
- prev_bc, lindex);
+ return x86_new_jmp(arch, data, num_operands, operands, info, prev_bc,
+ line);
/* Copy what we can from info */
- d.lindex = lindex;
+ d.line = line;
d.ea = NULL;
d.ea_origin = NULL;
d.imm = NULL;
mod_data >>= 8;
}
if (info->modifiers & MOD_Imm8) {
- d.imm = yasm_expr_new_ident(yasm_expr_int(
- yasm_intnum_new_uint(mod_data & 0xFF)), lindex);
+ d.imm = yasm_expr_create_ident(yasm_expr_int(
+ yasm_intnum_create_uint(mod_data & 0xFF)), line);
d.im_len = 1;
mod_data >>= 8;
}
/* Go through operands and assign */
if (operands) {
for(i = 0, op = yasm_ops_first(operands); op && i<info->num_operands;
- op = yasm_ops_next(op), i++) {
+ op = yasm_operand_next(op), i++) {
switch ((int)(info->operands[i] & OPA_MASK)) {
case OPA_None:
/* Throw away the operand contents */
case YASM_INSN__OPERAND_SEGREG:
break;
case YASM_INSN__OPERAND_MEMORY:
- yasm_ea_delete(op->data.ea);
+ yasm_ea_destroy(op->data.ea);
break;
case YASM_INSN__OPERAND_IMM:
- yasm_expr_delete(op->data.val);
+ yasm_expr_destroy(op->data.val);
break;
}
break;
switch (op->type) {
case YASM_INSN__OPERAND_REG:
d.ea =
- yasm_x86__ea_new_reg(op->data.reg, &d.rex,
- yasm_x86_LTX_mode_bits);
+ yasm_x86__ea_create_reg(op->data.reg, &d.rex,
+ arch_x86->mode_bits);
break;
case YASM_INSN__OPERAND_SEGREG:
yasm_internal_error(
if ((info->operands[i] & OPT_MASK) == OPT_MemOffs)
/* Special-case for MOV MemOffs instruction */
yasm_x86__ea_set_disponly(d.ea);
- else if (yasm_x86_LTX_mode_bits == 64)
+ else if (arch_x86->mode_bits == 64)
/* Save origin for possible RIP-relative */
- d.ea_origin = yasm_symrec_define_label("$",
- cur_section, prev_bc, 0, lindex);
+ d.ea_origin = yasm_symtab_define_label2("$",
+ prev_bc, 0, line);
break;
case YASM_INSN__OPERAND_IMM:
- d.ea = yasm_x86__ea_new_imm(op->data.val,
+ d.ea = yasm_x86__ea_create_imm(op->data.val,
size_lookup[(info->operands[i] &
OPS_MASK)>>OPS_SHIFT]);
break;
d.spare = (unsigned char)(op->data.reg&7);
else if (op->type == YASM_INSN__OPERAND_REG) {
if (yasm_x86__set_rex_from_reg(&d.rex, &d.spare,
- op->data.reg, yasm_x86_LTX_mode_bits,
+ op->data.reg, arch_x86->mode_bits,
X86_REX_R)) {
- yasm__error(lindex,
+ yasm__error(line,
N_("invalid combination of opcode and operands"));
return NULL;
}
if (op->type == YASM_INSN__OPERAND_REG) {
unsigned char opadd;
if (yasm_x86__set_rex_from_reg(&d.rex, &opadd,
- op->data.reg, yasm_x86_LTX_mode_bits,
+ op->data.reg, arch_x86->mode_bits,
X86_REX_B)) {
- yasm__error(lindex,
+ yasm__error(line,
N_("invalid combination of opcode and operands"));
return NULL;
}
break;
case OPA_SpareEA:
if (op->type == YASM_INSN__OPERAND_REG) {
- d.ea = yasm_x86__ea_new_reg(op->data.reg, &d.rex,
- yasm_x86_LTX_mode_bits);
+ d.ea = yasm_x86__ea_create_reg(op->data.reg, &d.rex,
+ arch_x86->mode_bits);
if (!d.ea ||
yasm_x86__set_rex_from_reg(&d.rex, &d.spare,
- op->data.reg, yasm_x86_LTX_mode_bits,
+ op->data.reg, arch_x86->mode_bits,
X86_REX_R)) {
- yasm__error(lindex,
+ yasm__error(line,
N_("invalid combination of opcode and operands"));
if (d.ea)
yasm_xfree(d.ea);
}
/* Create the bytecode and return it */
- return yasm_x86__bc_new_insn(&d);
+ return yasm_x86__bc_create_insn(arch, &d);
}
*/
void
-yasm_x86__parse_cpu(const char *id, unsigned long lindex)
+yasm_x86__parse_cpu(yasm_arch *arch, const char *id, unsigned long line)
{
+ yasm_arch_x86 *arch_x86 = (yasm_arch_x86 *)arch;
/*const char *marker;*/
/*!re2c
/* The standard CPU names /set/ cpu_enabled. */
"8086" {
- yasm_x86__cpu_enabled = CPU_Priv;
+ arch_x86->cpu_enabled = CPU_Priv;
return;
}
("80" | I)? "186" {
- yasm_x86__cpu_enabled = CPU_186|CPU_Priv;
+ arch_x86->cpu_enabled = CPU_186|CPU_Priv;
return;
}
("80" | I)? "286" {
- yasm_x86__cpu_enabled = CPU_186|CPU_286|CPU_Priv;
+ arch_x86->cpu_enabled = CPU_186|CPU_286|CPU_Priv;
return;
}
("80" | I)? "386" {
- yasm_x86__cpu_enabled =
+ arch_x86->cpu_enabled =
CPU_186|CPU_286|CPU_386|CPU_SMM|CPU_Prot|CPU_Priv;
return;
}
("80" | I)? "486" {
- yasm_x86__cpu_enabled =
+ arch_x86->cpu_enabled =
CPU_186|CPU_286|CPU_386|CPU_486|CPU_FPU|CPU_SMM|CPU_Prot|
CPU_Priv;
return;
}
(I? "586") | (P E N T I U M) | (P "5") {
- yasm_x86__cpu_enabled =
+ arch_x86->cpu_enabled =
CPU_186|CPU_286|CPU_386|CPU_486|CPU_586|CPU_FPU|CPU_SMM|
CPU_Prot|CPU_Priv;
return;
}
(I? "686") | (P "6") | (P P R O) | (P E N T I U M P R O) {
- yasm_x86__cpu_enabled =
+ arch_x86->cpu_enabled =
CPU_186|CPU_286|CPU_386|CPU_486|CPU_586|CPU_686|CPU_FPU|
CPU_SMM|CPU_Prot|CPU_Priv;
return;
}
(P "2") | (P E N T I U M "-"? ("2" | (I I))) {
- yasm_x86__cpu_enabled =
+ arch_x86->cpu_enabled =
CPU_186|CPU_286|CPU_386|CPU_486|CPU_586|CPU_686|CPU_FPU|
CPU_MMX|CPU_SMM|CPU_Prot|CPU_Priv;
return;
}
(P "3") | (P E N T I U M "-"? ("3" | (I I I))) | (K A T M A I) {
- yasm_x86__cpu_enabled =
+ arch_x86->cpu_enabled =
CPU_186|CPU_286|CPU_386|CPU_486|CPU_586|CPU_686|CPU_P3|CPU_FPU|
CPU_MMX|CPU_SSE|CPU_SMM|CPU_Prot|CPU_Priv;
return;
}
(P "4") | (P E N T I U M "-"? ("4" | (I V))) | (W I L L I A M E T T E) {
- yasm_x86__cpu_enabled =
+ arch_x86->cpu_enabled =
CPU_186|CPU_286|CPU_386|CPU_486|CPU_586|CPU_686|CPU_P3|CPU_P4|
CPU_FPU|CPU_MMX|CPU_SSE|CPU_SSE2|CPU_SMM|CPU_Prot|CPU_Priv;
return;
}
(I A "-"? "64") | (I T A N I U M) {
- yasm_x86__cpu_enabled =
+ arch_x86->cpu_enabled =
CPU_186|CPU_286|CPU_386|CPU_486|CPU_586|CPU_686|CPU_P3|CPU_P4|
CPU_IA64|CPU_FPU|CPU_MMX|CPU_SSE|CPU_SSE2|CPU_SMM|CPU_Prot|
CPU_Priv;
return;
}
K "6" {
- yasm_x86__cpu_enabled =
+ arch_x86->cpu_enabled =
CPU_186|CPU_286|CPU_386|CPU_486|CPU_586|CPU_686|CPU_K6|CPU_FPU|
CPU_MMX|CPU_3DNow|CPU_SMM|CPU_Prot|CPU_Priv;
return;
}
(A T H L O N) | (K "7") {
- yasm_x86__cpu_enabled =
+ arch_x86->cpu_enabled =
CPU_186|CPU_286|CPU_386|CPU_486|CPU_586|CPU_686|CPU_K6|
CPU_Athlon|CPU_FPU|CPU_MMX|CPU_SSE|CPU_3DNow|CPU_SMM|CPU_Prot|
CPU_Priv;
}
((S L E D G E)? (H A M M E R)) | (O P T E R O N) |
(A T H L O N "-"? "64") {
- yasm_x86__cpu_enabled =
+ arch_x86->cpu_enabled =
CPU_186|CPU_286|CPU_386|CPU_486|CPU_586|CPU_686|CPU_K6|
CPU_Athlon|CPU_Hammer|CPU_FPU|CPU_MMX|CPU_SSE|CPU_3DNow|
CPU_SMM|CPU_Prot|CPU_Priv;
/* Features have "no" versions to disable them, and only set/reset the
* specific feature being changed. All other bits are left alone.
*/
- F P U { yasm_x86__cpu_enabled |= CPU_FPU; return; }
- N O F P U { yasm_x86__cpu_enabled &= ~CPU_FPU; return; }
- M M X { yasm_x86__cpu_enabled |= CPU_MMX; return; }
- N O M M X { yasm_x86__cpu_enabled &= ~CPU_MMX; return; }
- S S E { yasm_x86__cpu_enabled |= CPU_SSE; return; }
- N O S S E { yasm_x86__cpu_enabled &= ~CPU_SSE; return; }
- S S E "2" { yasm_x86__cpu_enabled |= CPU_SSE2; return; }
- N O S S E "2" { yasm_x86__cpu_enabled &= ~CPU_SSE2; return; }
- "3" D N O W { yasm_x86__cpu_enabled |= CPU_3DNow; return; }
- N O "3" D N O W { yasm_x86__cpu_enabled &= ~CPU_3DNow; return; }
- C Y R I X { yasm_x86__cpu_enabled |= CPU_Cyrix; return; }
- N O C Y R I X { yasm_x86__cpu_enabled &= ~CPU_Cyrix; return; }
- A M D { yasm_x86__cpu_enabled |= CPU_AMD; return; }
- N O A M D { yasm_x86__cpu_enabled &= ~CPU_AMD; return; }
- S M M { yasm_x86__cpu_enabled |= CPU_SMM; return; }
- N O S M M { yasm_x86__cpu_enabled &= ~CPU_SMM; return; }
- P R O T { yasm_x86__cpu_enabled |= CPU_Prot; return; }
- N O P R O T { yasm_x86__cpu_enabled &= ~CPU_Prot; return; }
- U N D O C { yasm_x86__cpu_enabled |= CPU_Undoc; return; }
- N O U N D O C { yasm_x86__cpu_enabled &= ~CPU_Undoc; return; }
- O B S { yasm_x86__cpu_enabled |= CPU_Obs; return; }
- N O O B S { yasm_x86__cpu_enabled &= ~CPU_Obs; return; }
- P R I V { yasm_x86__cpu_enabled |= CPU_Priv; return; }
- N O P R I V { yasm_x86__cpu_enabled &= ~CPU_Priv; return; }
+ F P U { arch_x86->cpu_enabled |= CPU_FPU; return; }
+ N O F P U { arch_x86->cpu_enabled &= ~CPU_FPU; return; }
+ M M X { arch_x86->cpu_enabled |= CPU_MMX; return; }
+ N O M M X { arch_x86->cpu_enabled &= ~CPU_MMX; return; }
+ S S E { arch_x86->cpu_enabled |= CPU_SSE; return; }
+ N O S S E { arch_x86->cpu_enabled &= ~CPU_SSE; return; }
+ S S E "2" { arch_x86->cpu_enabled |= CPU_SSE2; return; }
+ N O S S E "2" { arch_x86->cpu_enabled &= ~CPU_SSE2; return; }
+ "3" D N O W { arch_x86->cpu_enabled |= CPU_3DNow; return; }
+ N O "3" D N O W { arch_x86->cpu_enabled &= ~CPU_3DNow; return; }
+ C Y R I X { arch_x86->cpu_enabled |= CPU_Cyrix; return; }
+ N O C Y R I X { arch_x86->cpu_enabled &= ~CPU_Cyrix; return; }
+ A M D { arch_x86->cpu_enabled |= CPU_AMD; return; }
+ N O A M D { arch_x86->cpu_enabled &= ~CPU_AMD; return; }
+ S M M { arch_x86->cpu_enabled |= CPU_SMM; return; }
+ N O S M M { arch_x86->cpu_enabled &= ~CPU_SMM; return; }
+ P R O T { arch_x86->cpu_enabled |= CPU_Prot; return; }
+ N O P R O T { arch_x86->cpu_enabled &= ~CPU_Prot; return; }
+ U N D O C { arch_x86->cpu_enabled |= CPU_Undoc; return; }
+ N O U N D O C { arch_x86->cpu_enabled &= ~CPU_Undoc; return; }
+ O B S { arch_x86->cpu_enabled |= CPU_Obs; return; }
+ N O O B S { arch_x86->cpu_enabled &= ~CPU_Obs; return; }
+ P R I V { arch_x86->cpu_enabled |= CPU_Priv; return; }
+ N O P R I V { arch_x86->cpu_enabled &= ~CPU_Priv; return; }
/* catchalls */
[\001-\377]+ {
- yasm__warning(YASM_WARN_GENERAL, lindex,
+ yasm__warning(YASM_WARN_GENERAL, line,
N_("unrecognized CPU identifier `%s'"), id);
return;
}
[\000] {
- yasm__warning(YASM_WARN_GENERAL, lindex,
+ yasm__warning(YASM_WARN_GENERAL, line,
N_("unrecognized CPU identifier `%s'"), id);
return;
}
}
yasm_arch_check_id_retval
-yasm_x86__parse_check_id(unsigned long data[4], const char *id,
- unsigned long lindex)
+yasm_x86__parse_check_id(yasm_arch *arch, unsigned long data[4],
+ const char *id, unsigned long line)
{
+ yasm_arch_x86 *arch_x86 = (yasm_arch_x86 *)arch;
const char *oid = id;
/*const char *marker;*/
/*!re2c
return YASM_ARCH_CHECK_ID_PREFIX;
}
O "64" {
- if (yasm_x86_LTX_mode_bits != 64) {
- yasm__warning(YASM_WARN_GENERAL, lindex,
+ if (arch_x86->mode_bits != 64) {
+ yasm__warning(YASM_WARN_GENERAL, line,
N_("`%s' is a prefix in 64-bit mode"), oid);
return YASM_ARCH_CHECK_ID_NONE;
}
}
/* address size overrides */
A "16" {
- if (yasm_x86_LTX_mode_bits == 64) {
- yasm__error(lindex,
+ if (arch_x86->mode_bits == 64) {
+ yasm__error(line,
N_("Cannot override address size to 16 bits in 64-bit mode"));
return YASM_ARCH_CHECK_ID_NONE;
}
return YASM_ARCH_CHECK_ID_PREFIX;
}
A "64" {
- if (yasm_x86_LTX_mode_bits != 64) {
- yasm__warning(YASM_WARN_GENERAL, lindex,
+ if (arch_x86->mode_bits != 64) {
+ yasm__warning(YASM_WARN_GENERAL, line,
N_("`%s' is a prefix in 64-bit mode"), oid);
return YASM_ARCH_CHECK_ID_NONE;
}
/* control, debug, and test registers */
C R [02-48] {
- if (yasm_x86_LTX_mode_bits != 64 && oid[2] == '8') {
- yasm__warning(YASM_WARN_GENERAL, lindex,
+ if (arch_x86->mode_bits != 64 && oid[2] == '8') {
+ yasm__warning(YASM_WARN_GENERAL, line,
N_("`%s' is a register in 64-bit mode"), oid);
return YASM_ARCH_CHECK_ID_NONE;
}
return YASM_ARCH_CHECK_ID_REG;
}
X M M [0-9] {
- if (yasm_x86_LTX_mode_bits != 64 &&
+ if (arch_x86->mode_bits != 64 &&
(oid[3] == '8' || oid[3] == '9')) {
- yasm__warning(YASM_WARN_GENERAL, lindex,
+ yasm__warning(YASM_WARN_GENERAL, line,
N_("`%s' is a register in 64-bit mode"), oid);
return YASM_ARCH_CHECK_ID_NONE;
}
return YASM_ARCH_CHECK_ID_REG;
}
X M M "1" [0-5] {
- if (yasm_x86_LTX_mode_bits != 64) {
- yasm__warning(YASM_WARN_GENERAL, lindex,
+ if (arch_x86->mode_bits != 64) {
+ yasm__warning(YASM_WARN_GENERAL, line,
N_("`%s' is a register in 64-bit mode"), oid);
return YASM_ARCH_CHECK_ID_NONE;
}
/* integer registers */
R A X {
- if (yasm_x86_LTX_mode_bits != 64) {
- yasm__warning(YASM_WARN_GENERAL, lindex,
+ if (arch_x86->mode_bits != 64) {
+ yasm__warning(YASM_WARN_GENERAL, line,
N_("`%s' is a register in 64-bit mode"), oid);
return YASM_ARCH_CHECK_ID_NONE;
}
return YASM_ARCH_CHECK_ID_REG;
}
R C X {
- if (yasm_x86_LTX_mode_bits != 64) {
- yasm__warning(YASM_WARN_GENERAL, lindex,
+ if (arch_x86->mode_bits != 64) {
+ yasm__warning(YASM_WARN_GENERAL, line,
N_("`%s' is a register in 64-bit mode"), oid);
return YASM_ARCH_CHECK_ID_NONE;
}
return YASM_ARCH_CHECK_ID_REG;
}
R D X {
- if (yasm_x86_LTX_mode_bits != 64) {
- yasm__warning(YASM_WARN_GENERAL, lindex,
+ if (arch_x86->mode_bits != 64) {
+ yasm__warning(YASM_WARN_GENERAL, line,
N_("`%s' is a register in 64-bit mode"), oid);
return YASM_ARCH_CHECK_ID_NONE;
}
return YASM_ARCH_CHECK_ID_REG;
}
R B X {
- if (yasm_x86_LTX_mode_bits != 64) {
- yasm__warning(YASM_WARN_GENERAL, lindex,
+ if (arch_x86->mode_bits != 64) {
+ yasm__warning(YASM_WARN_GENERAL, line,
N_("`%s' is a register in 64-bit mode"), oid);
return YASM_ARCH_CHECK_ID_NONE;
}
return YASM_ARCH_CHECK_ID_REG;
}
R S P {
- if (yasm_x86_LTX_mode_bits != 64) {
- yasm__warning(YASM_WARN_GENERAL, lindex,
+ if (arch_x86->mode_bits != 64) {
+ yasm__warning(YASM_WARN_GENERAL, line,
N_("`%s' is a register in 64-bit mode"), oid);
return YASM_ARCH_CHECK_ID_NONE;
}
return YASM_ARCH_CHECK_ID_REG;
}
R B P {
- if (yasm_x86_LTX_mode_bits != 64) {
- yasm__warning(YASM_WARN_GENERAL, lindex,
+ if (arch_x86->mode_bits != 64) {
+ yasm__warning(YASM_WARN_GENERAL, line,
N_("`%s' is a register in 64-bit mode"), oid);
return YASM_ARCH_CHECK_ID_NONE;
}
return YASM_ARCH_CHECK_ID_REG;
}
R S I {
- if (yasm_x86_LTX_mode_bits != 64) {
- yasm__warning(YASM_WARN_GENERAL, lindex,
+ if (arch_x86->mode_bits != 64) {
+ yasm__warning(YASM_WARN_GENERAL, line,
N_("`%s' is a register in 64-bit mode"), oid);
return YASM_ARCH_CHECK_ID_NONE;
}
return YASM_ARCH_CHECK_ID_REG;
}
R D I {
- if (yasm_x86_LTX_mode_bits != 64) {
- yasm__warning(YASM_WARN_GENERAL, lindex,
+ if (arch_x86->mode_bits != 64) {
+ yasm__warning(YASM_WARN_GENERAL, line,
N_("`%s' is a register in 64-bit mode"), oid);
return YASM_ARCH_CHECK_ID_NONE;
}
return YASM_ARCH_CHECK_ID_REG;
}
R [8-9] {
- if (yasm_x86_LTX_mode_bits != 64) {
- yasm__warning(YASM_WARN_GENERAL, lindex,
+ if (arch_x86->mode_bits != 64) {
+ yasm__warning(YASM_WARN_GENERAL, line,
N_("`%s' is a register in 64-bit mode"), oid);
return YASM_ARCH_CHECK_ID_NONE;
}
return YASM_ARCH_CHECK_ID_REG;
}
R "1" [0-5] {
- if (yasm_x86_LTX_mode_bits != 64) {
- yasm__warning(YASM_WARN_GENERAL, lindex,
+ if (arch_x86->mode_bits != 64) {
+ yasm__warning(YASM_WARN_GENERAL, line,
N_("`%s' is a register in 64-bit mode"), oid);
return YASM_ARCH_CHECK_ID_NONE;
}
E S I { data[0] = X86_REG32 | 6; return YASM_ARCH_CHECK_ID_REG; }
E D I { data[0] = X86_REG32 | 7; return YASM_ARCH_CHECK_ID_REG; }
R [8-9] D {
- if (yasm_x86_LTX_mode_bits != 64) {
- yasm__warning(YASM_WARN_GENERAL, lindex,
+ if (arch_x86->mode_bits != 64) {
+ yasm__warning(YASM_WARN_GENERAL, line,
N_("`%s' is a register in 64-bit mode"), oid);
return YASM_ARCH_CHECK_ID_NONE;
}
return YASM_ARCH_CHECK_ID_REG;
}
R "1" [0-5] D {
- if (yasm_x86_LTX_mode_bits != 64) {
- yasm__warning(YASM_WARN_GENERAL, lindex,
+ if (arch_x86->mode_bits != 64) {
+ yasm__warning(YASM_WARN_GENERAL, line,
N_("`%s' is a register in 64-bit mode"), oid);
return YASM_ARCH_CHECK_ID_NONE;
}
S I { data[0] = X86_REG16 | 6; return YASM_ARCH_CHECK_ID_REG; }
D I { data[0] = X86_REG16 | 7; return YASM_ARCH_CHECK_ID_REG; }
R [8-9] W {
- if (yasm_x86_LTX_mode_bits != 64) {
- yasm__warning(YASM_WARN_GENERAL, lindex,
+ if (arch_x86->mode_bits != 64) {
+ yasm__warning(YASM_WARN_GENERAL, line,
N_("`%s' is a register in 64-bit mode"), oid);
return YASM_ARCH_CHECK_ID_NONE;
}
return YASM_ARCH_CHECK_ID_REG;
}
R "1" [0-5] W {
- if (yasm_x86_LTX_mode_bits != 64) {
- yasm__warning(YASM_WARN_GENERAL, lindex,
+ if (arch_x86->mode_bits != 64) {
+ yasm__warning(YASM_WARN_GENERAL, line,
N_("`%s' is a register in 64-bit mode"), oid);
return YASM_ARCH_CHECK_ID_NONE;
}
D H { data[0] = X86_REG8 | 6; return YASM_ARCH_CHECK_ID_REG; }
B H { data[0] = X86_REG8 | 7; return YASM_ARCH_CHECK_ID_REG; }
S P L {
- if (yasm_x86_LTX_mode_bits != 64) {
- yasm__warning(YASM_WARN_GENERAL, lindex,
+ if (arch_x86->mode_bits != 64) {
+ yasm__warning(YASM_WARN_GENERAL, line,
N_("`%s' is a register in 64-bit mode"), oid);
return YASM_ARCH_CHECK_ID_NONE;
}
return YASM_ARCH_CHECK_ID_REG;
}
B P L {
- if (yasm_x86_LTX_mode_bits != 64) {
- yasm__warning(YASM_WARN_GENERAL, lindex,
+ if (arch_x86->mode_bits != 64) {
+ yasm__warning(YASM_WARN_GENERAL, line,
N_("`%s' is a register in 64-bit mode"), oid);
return YASM_ARCH_CHECK_ID_NONE;
}
return YASM_ARCH_CHECK_ID_REG;
}
S I L {
- if (yasm_x86_LTX_mode_bits != 64) {
- yasm__warning(YASM_WARN_GENERAL, lindex,
+ if (arch_x86->mode_bits != 64) {
+ yasm__warning(YASM_WARN_GENERAL, line,
N_("`%s' is a register in 64-bit mode"), oid);
return YASM_ARCH_CHECK_ID_NONE;
}
return YASM_ARCH_CHECK_ID_REG;
}
D I L {
- if (yasm_x86_LTX_mode_bits != 64) {
- yasm__warning(YASM_WARN_GENERAL, lindex,
+ if (arch_x86->mode_bits != 64) {
+ yasm__warning(YASM_WARN_GENERAL, line,
N_("`%s' is a register in 64-bit mode"), oid);
return YASM_ARCH_CHECK_ID_NONE;
}
return YASM_ARCH_CHECK_ID_REG;
}
R [8-9] B {
- if (yasm_x86_LTX_mode_bits != 64) {
- yasm__warning(YASM_WARN_GENERAL, lindex,
+ if (arch_x86->mode_bits != 64) {
+ yasm__warning(YASM_WARN_GENERAL, line,
N_("`%s' is a register in 64-bit mode"), oid);
return YASM_ARCH_CHECK_ID_NONE;
}
return YASM_ARCH_CHECK_ID_REG;
}
R "1" [0-5] B {
- if (yasm_x86_LTX_mode_bits != 64) {
- yasm__warning(YASM_WARN_GENERAL, lindex,
+ if (arch_x86->mode_bits != 64) {
+ yasm__warning(YASM_WARN_GENERAL, line,
N_("`%s' is a register in 64-bit mode"), oid);
return YASM_ARCH_CHECK_ID_NONE;
}
/* segment registers */
E S {
- if (yasm_x86_LTX_mode_bits == 64)
- yasm__warning(YASM_WARN_GENERAL, lindex,
+ if (arch_x86->mode_bits == 64)
+ yasm__warning(YASM_WARN_GENERAL, line,
N_("`%s' segment register ignored in 64-bit mode"), oid);
data[0] = 0x2600;
return YASM_ARCH_CHECK_ID_SEGREG;
}
C S { data[0] = 0x2e01; return YASM_ARCH_CHECK_ID_SEGREG; }
S S {
- if (yasm_x86_LTX_mode_bits == 64)
- yasm__warning(YASM_WARN_GENERAL, lindex,
+ if (arch_x86->mode_bits == 64)
+ yasm__warning(YASM_WARN_GENERAL, line,
N_("`%s' segment register ignored in 64-bit mode"), oid);
data[0] = 0x3602;
return YASM_ARCH_CHECK_ID_SEGREG;
}
D S {
- if (yasm_x86_LTX_mode_bits == 64)
- yasm__warning(YASM_WARN_GENERAL, lindex,
+ if (arch_x86->mode_bits == 64)
+ yasm__warning(YASM_WARN_GENERAL, line,
N_("`%s' segment register ignored in 64-bit mode"), oid);
data[0] = 0x3e03;
return YASM_ARCH_CHECK_ID_SEGREG;
/* RIP for 64-bit mode IP-relative offsets */
R I P {
- if (yasm_x86_LTX_mode_bits != 64) {
- yasm__warning(YASM_WARN_GENERAL, lindex,
+ if (arch_x86->mode_bits != 64) {
+ yasm__warning(YASM_WARN_GENERAL, line,
N_("`%s' is a register in 64-bit mode"), oid);
return YASM_ARCH_CHECK_ID_NONE;
}
/* Move with sign/zero extend */
M O V S X { RET_INSN(movszx, 0xBE, CPU_386); }
M O V S X D {
- if (yasm_x86_LTX_mode_bits != 64) {
- yasm__warning(YASM_WARN_GENERAL, lindex,
+ if (arch_x86->mode_bits != 64) {
+ yasm__warning(YASM_WARN_GENERAL, line,
N_("`%s' is an instruction in 64-bit mode"),
oid);
return YASM_ARCH_CHECK_ID_NONE;
/* Push instructions */
P U S H { RET_INSN(push, 0, CPU_Any); }
P U S H A {
- if (yasm_x86_LTX_mode_bits == 64) {
- yasm__error(lindex, N_("`%s' invalid in 64-bit mode"), oid);
+ if (arch_x86->mode_bits == 64) {
+ yasm__error(line, N_("`%s' invalid in 64-bit mode"), oid);
RET_INSN(not64, 0, CPU_Not64);
}
RET_INSN(onebyte, 0x0060, CPU_186);
}
P U S H A D {
- if (yasm_x86_LTX_mode_bits == 64) {
- yasm__error(lindex, N_("`%s' invalid in 64-bit mode"), oid);
+ if (arch_x86->mode_bits == 64) {
+ yasm__error(line, N_("`%s' invalid in 64-bit mode"), oid);
RET_INSN(not64, 0, CPU_Not64);
}
RET_INSN(onebyte, 0x2060, CPU_386);
}
P U S H A W {
- if (yasm_x86_LTX_mode_bits == 64) {
- yasm__error(lindex, N_("`%s' invalid in 64-bit mode"), oid);
+ if (arch_x86->mode_bits == 64) {
+ yasm__error(line, N_("`%s' invalid in 64-bit mode"), oid);
RET_INSN(not64, 0, CPU_Not64);
}
RET_INSN(onebyte, 0x1060, CPU_186);
/* Pop instructions */
P O P { RET_INSN(pop, 0, CPU_Any); }
P O P A {
- if (yasm_x86_LTX_mode_bits == 64) {
- yasm__error(lindex, N_("`%s' invalid in 64-bit mode"), oid);
+ if (arch_x86->mode_bits == 64) {
+ yasm__error(line, N_("`%s' invalid in 64-bit mode"), oid);
RET_INSN(not64, 0, CPU_Not64);
}
RET_INSN(onebyte, 0x0061, CPU_186);
}
P O P A D {
- if (yasm_x86_LTX_mode_bits == 64) {
- yasm__error(lindex, N_("`%s' invalid in 64-bit mode"), oid);
+ if (arch_x86->mode_bits == 64) {
+ yasm__error(line, N_("`%s' invalid in 64-bit mode"), oid);
RET_INSN(not64, 0, CPU_Not64);
}
RET_INSN(onebyte, 0x2061, CPU_386);
}
P O P A W {
- if (yasm_x86_LTX_mode_bits == 64) {
- yasm__error(lindex, N_("`%s' invalid in 64-bit mode"), oid);
+ if (arch_x86->mode_bits == 64) {
+ yasm__error(line, N_("`%s' invalid in 64-bit mode"), oid);
RET_INSN(not64, 0, CPU_Not64);
}
RET_INSN(onebyte, 0x1061, CPU_186);
L E A { RET_INSN(lea, 0, CPU_Any); }
/* Load segment registers from memory */
L D S {
- if (yasm_x86_LTX_mode_bits == 64) {
- yasm__error(lindex, N_("`%s' invalid in 64-bit mode"), oid);
+ if (arch_x86->mode_bits == 64) {
+ yasm__error(line, N_("`%s' invalid in 64-bit mode"), oid);
RET_INSN(not64, 0, CPU_Not64);
}
RET_INSN(ldes, 0xC5, CPU_Any);
}
L E S {
- if (yasm_x86_LTX_mode_bits == 64) {
- yasm__error(lindex, N_("`%s' invalid in 64-bit mode"), oid);
+ if (arch_x86->mode_bits == 64) {
+ yasm__error(line, N_("`%s' invalid in 64-bit mode"), oid);
RET_INSN(not64, 0, CPU_Not64);
}
RET_INSN(ldes, 0xC4, CPU_Any);
C L T S { RET_INSN(twobyte, 0x0F06, CPU_286|CPU_Priv); }
C M C { RET_INSN(onebyte, 0x00F5, CPU_Any); }
L A H F {
- if (yasm_x86_LTX_mode_bits == 64) {
- yasm__error(lindex, N_("`%s' invalid in 64-bit mode"), oid);
+ if (arch_x86->mode_bits == 64) {
+ yasm__error(line, N_("`%s' invalid in 64-bit mode"), oid);
RET_INSN(not64, 0, CPU_Not64);
}
RET_INSN(onebyte, 0x009F, CPU_Any);
}
S A H F {
- if (yasm_x86_LTX_mode_bits == 64) {
- yasm__error(lindex, N_("`%s' invalid in 64-bit mode"), oid);
+ if (arch_x86->mode_bits == 64) {
+ yasm__error(line, N_("`%s' invalid in 64-bit mode"), oid);
RET_INSN(not64, 0, CPU_Not64);
}
RET_INSN(onebyte, 0x009E, CPU_Any);
P U S H F D { RET_INSN(onebyte, 0x209C, CPU_386); }
P U S H F W { RET_INSN(onebyte, 0x109C, CPU_Any); }
P U S H F Q {
- if (yasm_x86_LTX_mode_bits != 64) {
- yasm__warning(YASM_WARN_GENERAL, lindex,
+ if (arch_x86->mode_bits != 64) {
+ yasm__warning(YASM_WARN_GENERAL, line,
N_("`%s' is an instruction in 64-bit mode"),
oid);
return YASM_ARCH_CHECK_ID_NONE;
}
P O P F { RET_INSN(onebyte, 0x40009D, CPU_Any); }
P O P F D {
- if (yasm_x86_LTX_mode_bits == 64) {
- yasm__error(lindex, N_("`%s' invalid in 64-bit mode"), oid);
+ if (arch_x86->mode_bits == 64) {
+ yasm__error(line, N_("`%s' invalid in 64-bit mode"), oid);
RET_INSN(not64, 0, CPU_Not64);
}
RET_INSN(onebyte, 0x00209D, CPU_386);
}
P O P F W { RET_INSN(onebyte, 0x40109D, CPU_Any); }
P O P F Q {
- if (yasm_x86_LTX_mode_bits != 64) {
- yasm__warning(YASM_WARN_GENERAL, lindex,
+ if (arch_x86->mode_bits != 64) {
+ yasm__warning(YASM_WARN_GENERAL, line,
N_("`%s' is an instruction in 64-bit mode"),
oid);
return YASM_ARCH_CHECK_ID_NONE;
N E G { RET_INSN(f6, 0x03, CPU_Any); }
N O T { RET_INSN(f6, 0x02, CPU_Any); }
A A A {
- if (yasm_x86_LTX_mode_bits == 64) {
- yasm__error(lindex, N_("`%s' invalid in 64-bit mode"), oid);
+ if (arch_x86->mode_bits == 64) {
+ yasm__error(line, N_("`%s' invalid in 64-bit mode"), oid);
RET_INSN(not64, 0, CPU_Not64);
}
RET_INSN(onebyte, 0x0037, CPU_Any);
}
A A S {
- if (yasm_x86_LTX_mode_bits == 64) {
- yasm__error(lindex, N_("`%s' invalid in 64-bit mode"), oid);
+ if (arch_x86->mode_bits == 64) {
+ yasm__error(line, N_("`%s' invalid in 64-bit mode"), oid);
RET_INSN(not64, 0, CPU_Not64);
}
RET_INSN(onebyte, 0x003F, CPU_Any);
}
D A A {
- if (yasm_x86_LTX_mode_bits == 64) {
- yasm__error(lindex, N_("`%s' invalid in 64-bit mode"), oid);
+ if (arch_x86->mode_bits == 64) {
+ yasm__error(line, N_("`%s' invalid in 64-bit mode"), oid);
RET_INSN(not64, 0, CPU_Not64);
}
RET_INSN(onebyte, 0x0027, CPU_Any);
}
D A S {
- if (yasm_x86_LTX_mode_bits == 64) {
- yasm__error(lindex, N_("`%s' invalid in 64-bit mode"), oid);
+ if (arch_x86->mode_bits == 64) {
+ yasm__error(line, N_("`%s' invalid in 64-bit mode"), oid);
RET_INSN(not64, 0, CPU_Not64);
}
RET_INSN(onebyte, 0x002F, CPU_Any);
}
A A D {
- if (yasm_x86_LTX_mode_bits == 64) {
- yasm__error(lindex, N_("`%s' invalid in 64-bit mode"), oid);
+ if (arch_x86->mode_bits == 64) {
+ yasm__error(line, N_("`%s' invalid in 64-bit mode"), oid);
RET_INSN(not64, 0, CPU_Not64);
}
RET_INSN(aadm, 0x01, CPU_Any);
}
A A M {
- if (yasm_x86_LTX_mode_bits == 64) {
- yasm__error(lindex, N_("`%s' invalid in 64-bit mode"), oid);
+ if (arch_x86->mode_bits == 64) {
+ yasm__error(line, N_("`%s' invalid in 64-bit mode"), oid);
RET_INSN(not64, 0, CPU_Not64);
}
RET_INSN(aadm, 0x00, CPU_Any);
C B W { RET_INSN(onebyte, 0x1098, CPU_Any); }
C W D E { RET_INSN(onebyte, 0x2098, CPU_386); }
C D Q E {
- if (yasm_x86_LTX_mode_bits != 64) {
- yasm__warning(YASM_WARN_GENERAL, lindex,
+ if (arch_x86->mode_bits != 64) {
+ yasm__warning(YASM_WARN_GENERAL, line,
N_("`%s' is an instruction in 64-bit mode"),
oid);
return YASM_ARCH_CHECK_ID_NONE;
C W D { RET_INSN(onebyte, 0x1099, CPU_Any); }
C D Q { RET_INSN(onebyte, 0x2099, CPU_386); }
C D O {
- if (yasm_x86_LTX_mode_bits != 64) {
- yasm__warning(YASM_WARN_GENERAL, lindex,
+ if (arch_x86->mode_bits != 64) {
+ yasm__warning(YASM_WARN_GENERAL, line,
N_("`%s' is an instruction in 64-bit mode"),
oid);
return YASM_ARCH_CHECK_ID_NONE;
J C X Z { RET_INSN(jcxz, 16, CPU_Any); }
J E C X Z { RET_INSN(jcxz, 32, CPU_386); }
J R C X Z {
- if (yasm_x86_LTX_mode_bits != 64) {
- yasm__warning(YASM_WARN_GENERAL, lindex,
+ if (arch_x86->mode_bits != 64) {
+ yasm__warning(YASM_WARN_GENERAL, line,
N_("`%s' is an instruction in 64-bit mode"),
oid);
return YASM_ARCH_CHECK_ID_NONE;
C M P S W { RET_INSN(onebyte, 0x10A7, CPU_Any); }
C M P S D { RET_INSN(cmpsd, 0, CPU_Any); }
C M P S Q {
- if (yasm_x86_LTX_mode_bits != 64) {
- yasm__warning(YASM_WARN_GENERAL, lindex,
+ if (arch_x86->mode_bits != 64) {
+ yasm__warning(YASM_WARN_GENERAL, line,
N_("`%s' is an instruction in 64-bit mode"),
oid);
return YASM_ARCH_CHECK_ID_NONE;
L O D S W { RET_INSN(onebyte, 0x10AD, CPU_Any); }
L O D S D { RET_INSN(onebyte, 0x20AD, CPU_386); }
L O D S Q {
- if (yasm_x86_LTX_mode_bits != 64) {
- yasm__warning(YASM_WARN_GENERAL, lindex,
+ if (arch_x86->mode_bits != 64) {
+ yasm__warning(YASM_WARN_GENERAL, line,
N_("`%s' is an instruction in 64-bit mode"),
oid);
return YASM_ARCH_CHECK_ID_NONE;
M O V S W { RET_INSN(onebyte, 0x10A5, CPU_Any); }
M O V S D { RET_INSN(movsd, 0, CPU_Any); }
M O V S Q {
- if (yasm_x86_LTX_mode_bits != 64) {
- yasm__warning(YASM_WARN_GENERAL, lindex,
+ if (arch_x86->mode_bits != 64) {
+ yasm__warning(YASM_WARN_GENERAL, line,
N_("`%s' is an instruction in 64-bit mode"),
oid);
return YASM_ARCH_CHECK_ID_NONE;
S C A S W { RET_INSN(onebyte, 0x10AF, CPU_Any); }
S C A S D { RET_INSN(onebyte, 0x20AF, CPU_386); }
S C A S Q {
- if (yasm_x86_LTX_mode_bits != 64) {
- yasm__warning(YASM_WARN_GENERAL, lindex,
+ if (arch_x86->mode_bits != 64) {
+ yasm__warning(YASM_WARN_GENERAL, line,
N_("`%s' is an instruction in 64-bit mode"),
oid);
return YASM_ARCH_CHECK_ID_NONE;
S T O S W { RET_INSN(onebyte, 0x10AB, CPU_Any); }
S T O S D { RET_INSN(onebyte, 0x20AB, CPU_386); }
S T O S Q {
- if (yasm_x86_LTX_mode_bits != 64) {
- yasm__warning(YASM_WARN_GENERAL, lindex,
+ if (arch_x86->mode_bits != 64) {
+ yasm__warning(YASM_WARN_GENERAL, line,
N_("`%s' is an instruction in 64-bit mode"),
oid);
return YASM_ARCH_CHECK_ID_NONE;
I N T "3" { RET_INSN(onebyte, 0x00CC, CPU_Any); }
I N T "03" { RET_INSN(onebyte, 0x00CC, CPU_Any); }
I N T O {
- if (yasm_x86_LTX_mode_bits == 64) {
- yasm__error(lindex, N_("`%s' invalid in 64-bit mode"), oid);
+ if (arch_x86->mode_bits == 64) {
+ yasm__error(line, N_("`%s' invalid in 64-bit mode"), oid);
RET_INSN(not64, 0, CPU_Not64);
}
RET_INSN(onebyte, 0x00CE, CPU_Any);
I R E T W { RET_INSN(onebyte, 0x10CF, CPU_Any); }
I R E T D { RET_INSN(onebyte, 0x20CF, CPU_386); }
I R E T Q {
- if (yasm_x86_LTX_mode_bits != 64) {
- yasm__warning(YASM_WARN_GENERAL, lindex,
+ if (arch_x86->mode_bits != 64) {
+ yasm__warning(YASM_WARN_GENERAL, line,
N_("`%s' is an instruction in 64-bit mode"),
oid);
return YASM_ARCH_CHECK_ID_NONE;
}
R S M { RET_INSN(twobyte, 0x0FAA, CPU_586|CPU_SMM); }
B O U N D {
- if (yasm_x86_LTX_mode_bits == 64) {
- yasm__error(lindex, N_("`%s' invalid in 64-bit mode"), oid);
+ if (arch_x86->mode_bits == 64) {
+ yasm__error(line, N_("`%s' invalid in 64-bit mode"), oid);
RET_INSN(not64, 0, CPU_Not64);
}
RET_INSN(bound, 0, CPU_186);
N O P { RET_INSN(onebyte, 0x0090, CPU_Any); }
/* Protection control */
A R P L {
- if (yasm_x86_LTX_mode_bits == 64) {
- yasm__error(lindex, N_("`%s' invalid in 64-bit mode"), oid);
+ if (arch_x86->mode_bits == 64) {
+ yasm__error(line, N_("`%s' invalid in 64-bit mode"), oid);
RET_INSN(not64, 0, CPU_Not64);
}
RET_INSN(arpl, 0, CPU_286|CPU_Prot);
C M P X C H G "8" B { RET_INSN(cmpxchg8b, 0, CPU_586); }
/* Pentium II/Pentium Pro extensions */
S Y S E N T E R {
- if (yasm_x86_LTX_mode_bits == 64) {
- yasm__error(lindex, N_("`%s' invalid in 64-bit mode"), oid);
+ if (arch_x86->mode_bits == 64) {
+ yasm__error(line, N_("`%s' invalid in 64-bit mode"), oid);
RET_INSN(not64, 0, CPU_Not64);
}
RET_INSN(twobyte, 0x0F34, CPU_686);
}
S Y S E X I T {
- if (yasm_x86_LTX_mode_bits == 64) {
- yasm__error(lindex, N_("`%s' invalid in 64-bit mode"), oid);
+ if (arch_x86->mode_bits == 64) {
+ yasm__error(line, N_("`%s' invalid in 64-bit mode"), oid);
RET_INSN(not64, 0, CPU_Not64);
}
RET_INSN(twobyte, 0x0F35, CPU_686|CPU_Priv);
S Y S R E T { RET_INSN(twobyte, 0x0F07, CPU_686|CPU_AMD|CPU_Priv); }
/* AMD x86-64 extensions */
S W A P G S {
- if (yasm_x86_LTX_mode_bits != 64) {
- yasm__warning(YASM_WARN_GENERAL, lindex,
+ if (arch_x86->mode_bits != 64) {
+ yasm__warning(YASM_WARN_GENERAL, line,
N_("`%s' is an instruction in 64-bit mode"),
oid);
return YASM_ARCH_CHECK_ID_NONE;
L O A D A L L { RET_INSN(twobyte, 0x0F07, CPU_386|CPU_Undoc); }
L O A D A L L "286" { RET_INSN(twobyte, 0x0F05, CPU_286|CPU_Undoc); }
S A L C {
- if (yasm_x86_LTX_mode_bits == 64) {
- yasm__error(lindex, N_("`%s' invalid in 64-bit mode"), oid);
+ if (arch_x86->mode_bits == 64) {
+ yasm__error(line, N_("`%s' invalid in 64-bit mode"), oid);
RET_INSN(not64, 0, CPU_Not64);
}
RET_INSN(onebyte, 0x00D6, CPU_Undoc);
NULL, /*null_dbgfmt_initialize*/
NULL, /*null_dbgfmt_cleanup*/
NULL, /*null_dbgfmt_directive*/
- NULL, /*null_dbgfmt_generate*/
- NULL, /*null_dbgfmt_bc_data_output*/
- NULL, /*null_dbgfmt_bc_data_delete*/
- NULL /*null_dbgfmt_bc_data_print*/
+ NULL /*null_dbgfmt_generate*/
};
N_NBLCS = 0xf8 /* Gould non-base registers */
} stabs_stab_type;
-#define STABS_DEBUG_DATA 1
-#define STABS_DEBUG_STR 2
-
typedef struct {
unsigned long lastline; /* track line and file of bytecodes */
unsigned long curline;
yasm_section *sect;
} stabs_symsect;
-yasm_dbgfmt yasm_stabs_LTX_dbgfmt;
+/* Bytecode types */
+
+typedef struct {
+ yasm_bytecode bc; /* base structure */
+ /*@only@*/ char *str;
+} stabs_bc_str;
+
+typedef struct {
+ yasm_bytecode bc; /* base structure */
+ stabs_stab *stab;
+} stabs_bc_stab;
+
+/* Bytecode callback function prototypes */
+
+static void stabs_bc_str_destroy(yasm_bytecode *bc);
+static void stabs_bc_str_print(const yasm_bytecode *bc, FILE *f, int
+ indent_level);
+static yasm_bc_resolve_flags stabs_bc_str_resolve
+ (yasm_bytecode *bc, int save, yasm_calc_bc_dist_func calc_bc_dist);
+static int stabs_bc_str_tobytes
+ (yasm_bytecode *bc, unsigned char **bufp, void *d,
+ yasm_output_expr_func output_expr,
+ /*@null@*/ yasm_output_reloc_func output_reloc);
+
+static void stabs_bc_stab_destroy(yasm_bytecode *bc);
+static void stabs_bc_stab_print(const yasm_bytecode *bc, FILE *f, int
+ indent_level);
+static yasm_bc_resolve_flags stabs_bc_stab_resolve
+ (yasm_bytecode *bc, int save, yasm_calc_bc_dist_func calc_bc_dist);
+static int stabs_bc_stab_tobytes
+ (yasm_bytecode *bc, unsigned char **bufp, void *d,
+ yasm_output_expr_func output_expr,
+ /*@null@*/ yasm_output_reloc_func output_reloc);
+
+/* Bytecode callback structures */
+
+static const yasm_bytecode_callback stabs_bc_str_callback = {
+ stabs_bc_str_destroy,
+ stabs_bc_str_print,
+ stabs_bc_str_resolve,
+ stabs_bc_str_tobytes
+};
+
+static const yasm_bytecode_callback stabs_bc_stab_callback = {
+ stabs_bc_stab_destroy,
+ stabs_bc_stab_print,
+ stabs_bc_stab_resolve,
+ stabs_bc_stab_tobytes
+};
+static yasm_symtab *symtab = NULL;
static yasm_objfmt *cur_objfmt = NULL;
static const char *filename = NULL;
-static yasm_linemgr *linemgr = NULL;
+static yasm_linemap *linemap = NULL;
static yasm_arch *cur_arch = NULL;
-static const char *cur_machine = NULL;
static size_t stabs_relocsize_bits = 0;
static size_t stabs_relocsize_bytes = 0;
static int
stabs_dbgfmt_initialize(const char *in_filename, const char *obj_filename,
- yasm_linemgr *lm, yasm_objfmt *of, yasm_arch *a,
- const char *machine)
+ yasm_object *object, yasm_objfmt *of, yasm_arch *a)
{
cur_objfmt = of;
filename = in_filename;
- linemgr = lm;
+ symtab = yasm_object_get_symtab(object);
+ linemap = yasm_object_get_linemap(object);
cur_arch = a;
- cur_machine = machine;
return 0;
}
static yasm_bytecode *
stabs_dbgfmt_append_bcstr(yasm_section *sect, const char *str)
{
- yasm_bytecode *bc = yasm_bc_new_dbgfmt_data(
- STABS_DEBUG_STR, strlen(str)+1,
- &yasm_stabs_LTX_dbgfmt,
- (void *)yasm__xstrdup(str), 0);
- yasm_bytecodehead *bcs = yasm_section_get_bytecodes(sect);
- yasm_bytecode *precbc = yasm_bcs_last(bcs);
+ yasm_bytecode *bc, *precbc;
+ stabs_bc_str *bc_str;
+
+ precbc = yasm_section_bcs_last(sect);
+ bc = yasm_bc_create_common(&stabs_bc_str_callback, sizeof(stabs_bc_str),
+ 0);
+ bc_str = (stabs_bc_str *)bc;
+
+ bc_str->str = yasm__xstrdup(str);
+
+ bc->len = strlen(str)+1;
bc->offset = precbc ? precbc->offset + precbc->len : 0;
- yasm_bcs_append(bcs, bc);
+
+ yasm_section_bcs_append(sect, bc);
return bc;
}
/*@null@*/ yasm_bytecode *bcvalue, unsigned long value)
{
yasm_bytecode *bc, *precbc;
- yasm_bytecodehead *bcs;
+ stabs_bc_stab *bc_stab;
stabs_stab *stab = yasm_xmalloc(sizeof(stabs_stab));
+
stab->other = 0;
stab->bcstr = bcstr;
stab->type = type;
stab->bcvalue = bcvalue;
stab->value = value;
- bc = yasm_bc_new_dbgfmt_data(STABS_DEBUG_DATA, info->stablen,
- &yasm_stabs_LTX_dbgfmt, (void *)stab,
- bcvalue ? bcvalue->line : 0);
- bcs = yasm_section_get_bytecodes(sect);
- precbc = yasm_bcs_last(bcs);
+ precbc = yasm_section_bcs_last(sect);
+ bc = yasm_bc_create_common(&stabs_bc_stab_callback, sizeof(stabs_bc_stab),
+ bcvalue ? bcvalue->line : 0);
+ bc_stab = (stabs_bc_stab *)bc;
+
+ bc_stab->stab = stab;
+
+ bc->len = info->stablen;
bc->offset = precbc ? precbc->offset + precbc->len : 0;
- yasm_bcs_append(bcs, bc);
+
+ yasm_section_bcs_append(sect, bc);
+
info->stabcount++;
return stab;
}
stabs_dbgfmt_first_sym_traversal(yasm_symrec *sym, void *d)
{
stabs_symsect *symsect = (stabs_symsect *)d;
- yasm_section *sect;
yasm_bytecode *precbc;
- if (!yasm_symrec_get_label(sym, §, &precbc))
+ if (!yasm_symrec_get_label(sym, &precbc))
return 1;
- if (precbc == NULL)
- precbc = yasm_bcs_first(yasm_section_get_bytecodes(sect));
- if ((sect == symsect->sect)
+ if ((precbc->section == symsect->sect)
&& ((symsect->sym == NULL)
|| precbc->offset < symsect->precbc->offset))
{
}
symsect.sect = sect;
- yasm_symrec_traverse((void *)&symsect, stabs_dbgfmt_first_sym_traversal);
+ yasm_symtab_traverse(symtab, (void *)&symsect,
+ stabs_dbgfmt_first_sym_traversal);
info->firstsym = symsect.sym;
info->firstbc = symsect.precbc;
}
stabs_dbgfmt_generate_bcs(yasm_bytecode *bc, void *d)
{
stabs_info *info = (stabs_info *)d;
- linemgr->lookup(bc->line, &info->curfile, &info->curline);
+ yasm_linemap_lookup(linemap, bc->line, &info->curfile, &info->curline);
if (info->lastfile != info->curfile) {
info->lastline = 0; /* new file, so line changes */
N_FUN, 0, info->firstsym, info->firstbc, 0);
yasm_xfree(str);
}
- yasm_bcs_traverse(yasm_section_get_bytecodes(sect), d,
- stabs_dbgfmt_generate_bcs);
+ yasm_section_bcs_traverse(sect, d, stabs_dbgfmt_generate_bcs);
return 1;
}
static void
-stabs_dbgfmt_generate(yasm_sectionhead *sections)
+stabs_dbgfmt_generate(yasm_object *object)
{
stabs_info info;
int new;
yasm_bytecode *dbgbc;
- yasm_bytecodehead *bcs;
+ stabs_bc_stab *dbgbc_stab;
stabs_stab *stab;
yasm_bytecode *filebc, *nullbc, *laststr;
yasm_section *stext;
+ const char *machine = cur_arch->module->get_machine(cur_arch);
/* Stablen is determined by arch/machine */
- if (yasm__strcasecmp(cur_arch->keyword, "x86") == 0) {
- if (yasm__strcasecmp(cur_machine, "x86") == 0) {
+ if (yasm__strcasecmp(cur_arch->module->keyword, "x86") == 0) {
+ if (yasm__strcasecmp(machine, "x86") == 0) {
info.stablen = 12;
}
- else if (yasm__strcasecmp(cur_machine, "amd64") == 0) {
+ else if (yasm__strcasecmp(machine, "amd64") == 0) {
info.stablen = 16;
}
else
info.lastline = 0;
info.stabcount = 0;
- info.stab = yasm_sections_switch_general(sections, ".stab", 0, 0, &new, 0);
+ info.stab = yasm_object_get_general(object, ".stab", 0, 0, &new, 0);
if (!new) {
- yasm_bytecode *last = yasm_bcs_last(
- yasm_section_get_bytecodes(info.stab));
+ yasm_bytecode *last = yasm_section_bcs_last(info.stab);
if (last == NULL)
- yasm__error(
- yasm_bcs_first(yasm_section_get_bytecodes(info.stab))->line,
+ yasm__error(yasm_section_bcs_first(info.stab)->line,
N_("stabs debugging conflicts with user-defined section .stab"));
else
yasm__warning(YASM_WARN_GENERAL, 0,
N_("stabs debugging overrides empty section .stab"));
}
- info.stabstr = yasm_sections_switch_general(sections, ".stabstr", 0, 0,
- &new, 0);
+ info.stabstr = yasm_object_get_general(object, ".stabstr", 0, 0, &new, 0);
if (!new) {
- yasm_bytecode *last = yasm_bcs_last(
- yasm_section_get_bytecodes(info.stabstr));
+ yasm_bytecode *last = yasm_section_bcs_last(info.stabstr);
if (last == NULL)
- yasm__error(
- yasm_bcs_first(yasm_section_get_bytecodes(info.stabstr))->line,
+ yasm__error(yasm_section_bcs_first(info.stabstr)->line,
N_("stabs debugging conflicts with user-defined section .stabstr"));
else
yasm__warning(YASM_WARN_GENERAL, 0,
/* initial pseudo-stab */
stab = yasm_xmalloc(sizeof(stabs_stab));
- dbgbc = yasm_bc_new_dbgfmt_data(STABS_DEBUG_DATA, info.stablen,
- &yasm_stabs_LTX_dbgfmt, (void *)stab, 0);
- bcs = yasm_section_get_bytecodes(info.stab);
- yasm_bcs_append(bcs, dbgbc);
+ dbgbc = yasm_bc_create_common(&stabs_bc_stab_callback,
+ sizeof(stabs_bc_stab), 0);
+ dbgbc_stab = (stabs_bc_stab *)dbgbc;
+
+ dbgbc->len = info.stablen;
+ dbgbc_stab->stab = stab;
+
+ yasm_section_bcs_append(info.stab, dbgbc);
/* initial strtab bytecodes */
nullbc = stabs_dbgfmt_append_bcstr(info.stabstr, "");
filebc = stabs_dbgfmt_append_bcstr(info.stabstr, filename);
- stext = yasm_sections_find_general(sections, ".text");
- info.firstsym = yasm_symrec_use(".text", 0);
- info.firstbc = yasm_bcs_first(yasm_section_get_bytecodes(stext));
+ stext = yasm_object_find_general(object, ".text");
+ info.firstsym = yasm_symtab_use(yasm_object_get_symtab(object), ".text", 0);
+ info.firstbc = yasm_section_bcs_first(stext);
/* N_SO file stab */
stabs_dbgfmt_append_stab(&info, info.stab, filebc, N_SO, 0,
info.firstsym, info.firstbc, 0);
- yasm_sections_traverse(sections, (void *)&info,
- stabs_dbgfmt_generate_sections);
+ yasm_object_sections_traverse(object, (void *)&info,
+ stabs_dbgfmt_generate_sections);
/* fill initial pseudo-stab's fields */
- laststr = yasm_bcs_last(yasm_section_get_bytecodes(info.stabstr));
+ laststr = yasm_section_bcs_last(info.stabstr);
if (laststr == NULL)
yasm_internal_error(".stabstr has no entries");
}
static int
-stabs_dbgfmt_bc_data_output(yasm_bytecode *bc, unsigned int type,
- const void *data, unsigned char **buf,
- const yasm_section *sect,
- yasm_output_reloc_func output_reloc, void *objfmt_d)
+stabs_bc_stab_tobytes(yasm_bytecode *bc, unsigned char **bufp, void *d,
+ yasm_output_expr_func output_expr,
+ yasm_output_reloc_func output_reloc)
{
- unsigned char *bufp = *buf;
- if (type == STABS_DEBUG_DATA) {
- const stabs_stab *stab = data;
-
- YASM_WRITE_32_L(bufp, stab->bcstr ? stab->bcstr->offset : 0);
- YASM_WRITE_8(bufp, stab->type);
- YASM_WRITE_8(bufp, stab->other);
- YASM_WRITE_16_L(bufp, stab->desc);
-
- if (stab->symvalue != NULL) {
- printf("DBG: ");
- bc->offset += 8;
- output_reloc(stab->symvalue, bc, bufp, stabs_relocsize_bytes,
- stabs_relocsize_bits, 0, 0, sect, objfmt_d);
- bc->offset -= 8;
- bufp += stabs_relocsize_bytes;
- }
- else if (stab->bcvalue != NULL) {
- YASM_WRITE_32_L(bufp, stab->bcvalue->offset);
- }
- else {
- YASM_WRITE_32_L(bufp, stab->value);
- }
+ stabs_bc_stab *bc_stab = (stabs_bc_stab *)bc;
+ unsigned char *buf = *bufp;
+ const stabs_stab *stab = bc_stab->stab;
+
+ YASM_WRITE_32_L(buf, stab->bcstr ? stab->bcstr->offset : 0);
+ YASM_WRITE_8(buf, stab->type);
+ YASM_WRITE_8(buf, stab->other);
+ YASM_WRITE_16_L(buf, stab->desc);
+
+ if (stab->symvalue != NULL) {
+ printf("DBG: ");
+ bc->offset += 8;
+ output_reloc(stab->symvalue, bc, buf, stabs_relocsize_bytes,
+ stabs_relocsize_bits, 0, 0, d);
+ bc->offset -= 8;
+ buf += stabs_relocsize_bytes;
}
- else if (type == STABS_DEBUG_STR) {
- const char *str = data;
- strcpy((char *)bufp, str);
- bufp += strlen(str)+1;
+ else if (stab->bcvalue != NULL) {
+ YASM_WRITE_32_L(buf, stab->bcvalue->offset);
}
+ else {
+ YASM_WRITE_32_L(buf, stab->value);
+ }
+
+ *bufp = buf;
+ return 0;
+}
+
+static int
+stabs_bc_str_tobytes(yasm_bytecode *bc, unsigned char **bufp, void *d,
+ yasm_output_expr_func output_expr,
+ yasm_output_reloc_func output_reloc)
+{
+ stabs_bc_str *bc_str = (stabs_bc_str *)bc;
+ unsigned char *buf = *bufp;
+ const char *str = bc_str->str;
+
+ strcpy((char *)buf, str);
+ buf += strlen(str)+1;
- *buf = bufp;
+ *bufp = buf;
return 0;
}
static void
-stabs_dbgfmt_bc_data_delete(unsigned int type, void *data)
+stabs_bc_stab_destroy(yasm_bytecode *bc)
{
- /* both stabs and strs are allocated at the top level pointer */
- yasm_xfree(data);
+ stabs_bc_stab *bc_stab = (stabs_bc_stab *)bc;
+ yasm_xfree(bc_stab->stab);
}
static void
-stabs_dbgfmt_bc_data_print(FILE *f, int indent_level, unsigned int type,
- const void *data)
+stabs_bc_str_destroy(yasm_bytecode *bc)
{
- if (type == STABS_DEBUG_DATA) {
- const stabs_stab *stab = data;
- const char *str = "";
- fprintf(f, "%*s.stabs \"%s\", 0x%x, 0x%x, 0x%x, 0x%lx\n",
- indent_level, "", str, stab->type, stab->other, stab->desc,
- stab->bcvalue ? stab->bcvalue->offset : stab->value);
- }
- else if (type == STABS_DEBUG_STR)
- fprintf(f, "%*s\"%s\"\n", indent_level, "", (const char *)data);
+ stabs_bc_str *bc_str = (stabs_bc_str *)bc;
+ yasm_xfree(bc_str->str);
+}
+
+static void
+stabs_bc_stab_print(const yasm_bytecode *bc, FILE *f, int indent_level)
+{
+ const stabs_bc_stab *bc_stab = (const stabs_bc_stab *)bc;
+ const stabs_stab *stab = bc_stab->stab;
+ const char *str = "";
+ fprintf(f, "%*s.stabs \"%s\", 0x%x, 0x%x, 0x%x, 0x%lx\n",
+ indent_level, "", str, stab->type, stab->other, stab->desc,
+ stab->bcvalue ? stab->bcvalue->offset : stab->value);
+}
+
+static void
+stabs_bc_str_print(const yasm_bytecode *bc, FILE *f, int indent_level)
+{
+ const stabs_bc_str *bc_str = (const stabs_bc_str *)bc;
+ fprintf(f, "%*s\"%s\"\n", indent_level, "", bc_str->str);
+}
+
+static yasm_bc_resolve_flags
+stabs_bc_stab_resolve(yasm_bytecode *bc, int save,
+ yasm_calc_bc_dist_func calc_bc_dist)
+{
+ yasm_internal_error(N_("tried to resolve a stabs stab bytecode"));
+ /*@notreached@*/
+ return YASM_BC_RESOLVE_MIN_LEN;
+}
+
+static yasm_bc_resolve_flags
+stabs_bc_str_resolve(yasm_bytecode *bc, int save,
+ yasm_calc_bc_dist_func calc_bc_dist)
+{
+ yasm_internal_error(N_("tried to resolve a stabs str bytecode"));
+ /*@notreached@*/
+ return YASM_BC_RESOLVE_MIN_LEN;
}
/* Define dbgfmt structure -- see dbgfmt.h for details */
stabs_dbgfmt_initialize,
stabs_dbgfmt_cleanup,
NULL /*stabs_dbgfmt_directive*/,
- stabs_dbgfmt_generate,
- stabs_dbgfmt_bc_data_output,
- stabs_dbgfmt_bc_data_delete,
- stabs_dbgfmt_bc_data_print
+ stabs_dbgfmt_generate
};
#define REGULAR_OUTBUF_SIZE 1024
-yasm_objfmt yasm_bin_LTX_objfmt;
+static void bin_section_data_destroy(/*@only@*/ void *d);
+static void bin_section_data_print(void *data, FILE *f, int indent_level);
+
+static const yasm_assoc_data_callback bin_section_data_callback = {
+ bin_section_data_destroy,
+ bin_section_data_print
+};
static /*@dependent@*/ yasm_arch *cur_arch;
static int
bin_objfmt_initialize(/*@unused@*/ const char *in_filename,
/*@unused@*/ const char *obj_filename,
- /*@unused@*/ yasm_dbgfmt *df, yasm_arch *a,
- /*@unused@*/ const char *machine)
+ /*@unused@*/ yasm_object *object,
+ /*@unused@*/ yasm_dbgfmt *df, yasm_arch *a)
{
cur_arch = a;
return 0;
/* Figure out the size of .text by looking at the last bytecode's offset
* plus its length. Add the start and size together to get the new start.
*/
- last = yasm_bcs_last(yasm_section_get_bytecodes(prevsect));
+ last = yasm_section_bcs_last(prevsect);
if (last)
*prevsectlen = last->offset + last->len;
else
* indicate padded size. Because aignment is always a power of two, we
* can use some bit trickery to do this easily.
*/
- alignptr = yasm_section_get_of_data(sect);
+ alignptr = yasm_section_get_data(sect, &bin_section_data_callback);
if (alignptr)
align = *alignptr;
else
* start expr + intnum(dist).
*/
if (e->terms[i].type == YASM_EXPR_SYM &&
- yasm_symrec_get_label(e->terms[i].data.sym, §, &precbc) &&
- (dist = yasm_common_calc_bc_dist(sect, NULL, precbc))) {
+ yasm_symrec_get_label(e->terms[i].data.sym, &precbc) &&
+ (sect = yasm_bc_get_section(precbc)) &&
+ (dist = yasm_common_calc_bc_dist(yasm_section_bcs_first(sect),
+ precbc))) {
const yasm_expr *start = yasm_section_get_start(sect);
e->terms[i].type = YASM_EXPR_EXPR;
e->terms[i].data.expn =
- yasm_expr_new(YASM_EXPR_ADD,
- yasm_expr_expr(yasm_expr_copy(start)),
- yasm_expr_int(dist), e->line);
+ yasm_expr_create(YASM_EXPR_ADD,
+ yasm_expr_expr(yasm_expr_copy(start)),
+ yasm_expr_int(dist), e->line);
}
}
static int
bin_objfmt_output_expr(yasm_expr **ep, unsigned char *buf, size_t destsize,
size_t valsize, int shift,
- /*@unused@*/ unsigned long offset,
- /*@observer@*/ const yasm_section *sect,
- yasm_bytecode *bc, int rel, int warn,
- /*@unused@*/ /*@null@*/ void *d)
+ /*@unused@*/ unsigned long offset, yasm_bytecode *bc,
+ int rel, int warn, /*@unused@*/ /*@null@*/ void *d)
{
/*@dependent@*/ /*@null@*/ const yasm_intnum *intn;
/*@dependent@*/ /*@null@*/ const yasm_floatnum *flt;
- assert(info != NULL);
-
/* For binary output, this is trivial: any expression that doesn't simplify
* to an integer is an error (references something external).
* Other object formats need to generate their relocation list from here!
if (flt) {
if (shift < 0)
yasm_internal_error(N_("attempting to negative shift a float"));
- return cur_arch->floatnum_tobytes(flt, buf, destsize, valsize,
- (unsigned int)shift, warn, bc->line);
+ return cur_arch->module->floatnum_tobytes(cur_arch, flt, buf, destsize,
+ valsize, (unsigned int)shift,
+ warn, bc->line);
}
/* Handle integer expressions */
intn = yasm_expr_get_intnum(ep, NULL);
if (intn)
- return cur_arch->intnum_tobytes(intn, buf, destsize, valsize, shift,
- bc, rel, warn, bc->line);
+ return cur_arch->module->intnum_tobytes(cur_arch, intn, buf, destsize,
+ valsize, shift, bc, rel, warn,
+ bc->line);
/* Check for complex float expressions */
if (yasm_expr__contains(*ep, YASM_EXPR_FLOAT)) {
assert(info != NULL);
- bigbuf = yasm_bc_tobytes(bc, info->buf, &size, &multiple, &gap, info->sect,
- info, bin_objfmt_output_expr, NULL, NULL);
+ bigbuf = yasm_bc_tobytes(bc, info->buf, &size, &multiple, &gap, info,
+ bin_objfmt_output_expr, NULL);
/* Don't bother doing anything else if size ended up being 0. */
if (size == 0) {
}
static void
-bin_objfmt_output(FILE *f, yasm_sectionhead *sections,
- /*@unused@*/ int all_syms)
+bin_objfmt_output(FILE *f, yasm_object *object, /*@unused@*/ int all_syms)
{
/*@observer@*/ /*@null@*/ yasm_section *text, *data, *bss, *prevsect;
/*@null@*/ yasm_expr *startexpr;
info.f = f;
info.buf = yasm_xmalloc(REGULAR_OUTBUF_SIZE);
- text = yasm_sections_find_general(sections, ".text");
- data = yasm_sections_find_general(sections, ".data");
- bss = yasm_sections_find_general(sections, ".bss");
+ text = yasm_object_find_general(object, ".text");
+ data = yasm_object_find_general(object, ".data");
+ bss = yasm_object_find_general(object, ".bss");
if (!text)
yasm_internal_error(N_("No `.text' section in bin objfmt output"));
return;
}
start = yasm_intnum_get_uint(startnum);
- yasm_expr_delete(startexpr);
+ yasm_expr_destroy(startexpr);
textstart = start;
/* Align .data and .bss (if present) by adjusting their starts. */
if (data) {
start = bin_objfmt_align_section(data, prevsect, start, 4,
prevsectlenptr, prevsectpadptr);
- yasm_section_set_start(data,
- yasm_expr_new_ident(yasm_expr_int(yasm_intnum_new_uint(start)), 0),
- 0);
+ yasm_section_set_start(data, yasm_expr_create_ident(
+ yasm_expr_int(yasm_intnum_create_uint(start)), 0), 0);
datastart = start;
prevsect = data;
prevsectlenptr = &datalen;
if (bss) {
start = bin_objfmt_align_section(bss, prevsect, start, 4,
prevsectlenptr, prevsectpadptr);
- yasm_section_set_start(bss,
- yasm_expr_new_ident(yasm_expr_int(yasm_intnum_new_uint(start)), 0),
- 0);
+ yasm_section_set_start(bss, yasm_expr_create_ident(
+ yasm_expr_int(yasm_intnum_create_uint(start)), 0), 0);
}
/* Output .text first. */
info.sect = text;
info.start = textstart;
- yasm_bcs_traverse(yasm_section_get_bytecodes(text), &info,
- bin_objfmt_output_bytecode);
+ yasm_section_bcs_traverse(text, &info, bin_objfmt_output_bytecode);
/* If .data is present, output it */
if (data) {
/* Output .data bytecodes */
info.sect = data;
info.start = datastart;
- yasm_bcs_traverse(yasm_section_get_bytecodes(data), &info,
- bin_objfmt_output_bytecode);
+ yasm_section_bcs_traverse(data, &info, bin_objfmt_output_bytecode);
}
/* If .bss is present, check it for non-reserve bytecodes */
}
static /*@observer@*/ /*@null@*/ yasm_section *
-bin_objfmt_sections_switch(yasm_sectionhead *headp,
- yasm_valparamhead *valparams,
- /*@unused@*/ /*@null@*/
- yasm_valparamhead *objext_valparams,
- unsigned long lindex)
+bin_objfmt_section_switch(yasm_object *object, yasm_valparamhead *valparams,
+ /*@unused@*/ /*@null@*/
+ yasm_valparamhead *objext_valparams,
+ unsigned long line)
{
yasm_valparam *vp;
yasm_section *retval;
resonly = 1;
} else {
/* other section names not recognized. */
- yasm__error(lindex, N_("segment name `%s' not recognized"),
+ yasm__error(line, N_("segment name `%s' not recognized"),
sectname);
return NULL;
}
unsigned long bitcnt;
if (strcmp(sectname, ".text") == 0) {
- yasm__error(lindex,
+ yasm__error(line,
N_("cannot specify an alignment to the `%s' section"),
sectname);
return NULL;
align = yasm_expr_get_intnum(&vp->param, NULL);
if (!align) {
- yasm__error(lindex,
+ yasm__error(line,
N_("argument to `%s' is not a power of two"),
vp->val);
return NULL;
*/
BitCount(bitcnt, alignval);
if (bitcnt > 1) {
- yasm__error(lindex,
+ yasm__error(line,
N_("argument to `%s' is not a power of two"),
vp->val);
return NULL;
}
}
- retval = yasm_sections_switch_general(headp, sectname,
- yasm_expr_new_ident(yasm_expr_int(yasm_intnum_new_uint(start)),
- lindex), resonly, &isnew, lindex);
+ retval = yasm_object_get_general(object, sectname,
+ yasm_expr_create_ident(
+ yasm_expr_int(yasm_intnum_create_uint(start)), line), resonly,
+ &isnew, line);
if (isnew) {
if (have_alignval) {
unsigned long *data = yasm_xmalloc(sizeof(unsigned long));
*data = alignval;
- yasm_section_set_of_data(retval, &yasm_bin_LTX_objfmt, data);
+ yasm_section_add_data(retval, &bin_section_data_callback,
+ data);
}
- yasm_symrec_define_label(sectname, retval, (yasm_bytecode *)NULL,
- 1, lindex);
+ yasm_symtab_define_label(yasm_object_get_symtab(object), sectname,
+ yasm_section_bcs_first(retval), 1, line);
} else if (have_alignval)
- yasm__warning(YASM_WARN_GENERAL, lindex,
+ yasm__warning(YASM_WARN_GENERAL, line,
N_("alignment value ignored on section redeclaration"));
return retval;
}
static void
-bin_objfmt_section_data_delete(/*@only@*/ void *d)
+bin_section_data_destroy(/*@only@*/ void *d)
{
yasm_xfree(d);
}
bin_objfmt_common_declare(/*@unused@*/ yasm_symrec *sym,
/*@only@*/ yasm_expr *size, /*@unused@*/ /*@null@*/
yasm_valparamhead *objext_valparams,
- unsigned long lindex)
+ unsigned long line)
{
- yasm_expr_delete(size);
- yasm__error(lindex,
+ yasm_expr_destroy(size);
+ yasm__error(line,
N_("binary object format does not support common variables"));
}
bin_objfmt_directive(const char *name, yasm_valparamhead *valparams,
/*@unused@*/ /*@null@*/
yasm_valparamhead *objext_valparams,
- yasm_sectionhead *headp, unsigned long lindex)
+ yasm_object *object, unsigned long line)
{
yasm_section *sect;
yasm_valparam *vp;
/* ORG takes just a simple integer as param */
vp = yasm_vps_first(valparams);
if (vp->val)
- start = yasm_expr_new_ident(yasm_expr_sym(
- yasm_symrec_use(vp->val, lindex)), lindex);
+ start = yasm_expr_create_ident(yasm_expr_sym(yasm_symtab_use(
+ yasm_object_get_symtab(object), vp->val, line)), line);
else if (vp->param) {
start = vp->param;
vp->param = NULL; /* Don't let valparams delete it */
}
if (!start) {
- yasm__error(lindex, N_("argument to ORG must be expression"));
+ yasm__error(line, N_("argument to ORG must be expression"));
return 0;
}
/* ORG changes the start of the .text section */
- sect = yasm_sections_find_general(headp, ".text");
+ sect = yasm_object_find_general(object, ".text");
if (!sect)
yasm_internal_error(
N_("bin objfmt: .text section does not exist before ORG is called?"));
- yasm_section_set_start(sect, start, lindex);
+ yasm_section_set_start(sect, start, line);
return 0; /* directive recognized */
} else
}
static void
-bin_objfmt_section_data_print(FILE *f, int indent_level, void *data)
+bin_section_data_print(void *data, FILE *f, int indent_level)
{
fprintf(f, "%*salign=%ld\n", indent_level, "", *((unsigned long *)data));
}
bin_objfmt_initialize,
bin_objfmt_output,
bin_objfmt_cleanup,
- bin_objfmt_sections_switch,
- bin_objfmt_section_data_delete,
- bin_objfmt_section_data_print,
+ bin_objfmt_section_switch,
NULL /*bin_objfmt_extern_declare*/,
NULL /*bin_objfmt_global_declare*/,
bin_objfmt_common_declare,
- NULL /*bin_objfmt_symrec_data_delete*/,
- NULL /*bin_objfmt_symrec_data_print*/,
- bin_objfmt_directive,
- NULL /*bin_objfmt_bc_objfmt_data_delete*/,
- NULL /*bin_objfmt_bc_objfmt_data_print*/
+ bin_objfmt_directive
};
unsigned long addr; /* start of next section */
} coff_objfmt_output_info;
+static void coff_section_data_destroy(/*@only@*/ void *d);
+static void coff_section_data_print(void *data, FILE *f, int indent_level);
+
+static const yasm_assoc_data_callback coff_section_data_cb = {
+ coff_section_data_destroy,
+ coff_section_data_print
+};
+
+static void coff_symrec_data_destroy(/*@only@*/ void *d);
+static void coff_symrec_data_print(void *data, FILE *f, int indent_level);
+
+static const yasm_assoc_data_callback coff_symrec_data_cb = {
+ coff_symrec_data_destroy,
+ coff_symrec_data_print
+};
+
static unsigned int coff_objfmt_parse_scnum; /* sect numbering in parser */
static coff_symtab_head coff_symtab; /* symbol table of indexed syms */
-yasm_objfmt yasm_coff_LTX_objfmt;
static /*@dependent@*/ yasm_arch *cur_arch;
/* Set nonzero for win32 output. */
if (STAILQ_EMPTY(&coff_symtab))
yasm_internal_error(N_("empty COFF symbol table"));
entry = STAILQ_LAST(&coff_symtab, coff_symtab_entry, link);
- sym_data_prev = yasm_symrec_get_of_data(entry->sym);
+ sym_data_prev = yasm_symrec_get_data(entry->sym, &coff_symrec_data_cb);
assert(sym_data_prev != NULL);
sym_data = yasm_xmalloc(sizeof(coff_symrec_data));
sym_data->index = sym_data_prev->index + entry->numaux + 1;
sym_data->sclass = sclass;
sym_data->size = size;
- yasm_symrec_set_of_data(sym, &yasm_coff_LTX_objfmt, sym_data);
+ yasm_symrec_add_data(sym, &coff_symrec_data_cb, sym_data);
entry = yasm_xmalloc(sizeof(coff_symtab_entry) +
(numaux-1)*sizeof(coff_symtab_auxent));
static int
coff_objfmt_append_local_sym(yasm_symrec *sym, /*@unused@*/ /*@null@*/ void *d)
{
- if (!yasm_symrec_get_of_data(sym))
+ if (!yasm_symrec_get_data(sym, &coff_symrec_data_cb))
coff_objfmt_symtab_append(sym, COFF_SCL_STAT, NULL, 0,
COFF_SYMTAB_AUX_NONE);
return 1;
static int
coff_common_initialize(const char *in_filename,
/*@unused@*/ const char *obj_filename,
- /*@unused@*/ yasm_dbgfmt *df, yasm_arch *a,
- const char *machine)
+ yasm_object *object, /*@unused@*/ yasm_dbgfmt *df,
+ yasm_arch *a)
{
yasm_symrec *filesym;
coff_symrec_data *data;
cur_arch = a;
/* Only support x86 arch, x86 machine */
- if (yasm__strcasecmp(cur_arch->keyword, "x86") != 0 ||
- yasm__strcasecmp(machine, "x86") != 0)
+ if (yasm__strcasecmp(cur_arch->module->keyword, "x86") != 0 ||
+ yasm__strcasecmp(cur_arch->module->get_machine(cur_arch), "x86") != 0)
return 1;
coff_objfmt_parse_scnum = 1; /* section numbering starts at 1 */
data->index = 0;
data->sclass = COFF_SCL_FILE;
data->size = NULL;
- filesym = yasm_symrec_define_label(".file", NULL, NULL, 0, 0);
- yasm_symrec_set_of_data(filesym, &yasm_coff_LTX_objfmt, data);
+ /* FIXME: misuse of NULL bytecode here; it works, but only barely. */
+ filesym = yasm_symtab_define_label(yasm_object_get_symtab(object), ".file",
+ NULL, 0, 0);
+ yasm_symrec_add_data(filesym, &coff_symrec_data_cb, data);
entry = yasm_xmalloc(sizeof(coff_symtab_entry));
entry->sym = filesym;
static int
coff_objfmt_initialize(const char *in_filename, const char *obj_filename,
- yasm_dbgfmt *df, yasm_arch *a, const char *machine)
+ yasm_object *object, yasm_dbgfmt *df, yasm_arch *a)
{
win32 = 0;
- return coff_common_initialize(in_filename, obj_filename, df, a, machine);
+ return coff_common_initialize(in_filename, obj_filename, object, df, a);
}
static int
win32_objfmt_initialize(const char *in_filename, const char *obj_filename,
- yasm_dbgfmt *df, yasm_arch *a, const char *machine)
+ yasm_object *object, yasm_dbgfmt *df, yasm_arch *a)
{
win32 = 1;
- return coff_common_initialize(in_filename, obj_filename, df, a, machine);
+ return coff_common_initialize(in_filename, obj_filename, object, df, a);
}
static int
return 0;
assert(info != NULL);
- csd = yasm_section_get_of_data(sect);
+ csd = yasm_section_get_data(sect, &coff_section_data_cb);
assert(csd != NULL);
csd->addr = info->addr;
- last = yasm_bcs_last(yasm_section_get_bytecodes(sect));
+ last = yasm_section_bcs_last(sect);
if (last)
info->addr += last->offset + last->len;
static int
coff_objfmt_output_expr(yasm_expr **ep, unsigned char *buf, size_t destsize,
size_t valsize, int shift, unsigned long offset,
- /*@observer@*/ const yasm_section *sect,
yasm_bytecode *bc, int rel, int warn,
/*@null@*/ void *d)
{
if (flt) {
if (shift < 0)
yasm_internal_error(N_("attempting to negative shift a float"));
- return cur_arch->floatnum_tobytes(flt, buf, destsize, valsize,
- (unsigned int)shift, warn, bc->line);
+ return cur_arch->module->floatnum_tobytes(cur_arch, flt, buf, destsize,
+ valsize, (unsigned int)shift,
+ warn, bc->line);
}
/* Handle integer expressions, with relocation if necessary */
if (!win32) {
/*@dependent@*/ /*@null@*/ coff_symrec_data *csymd;
- csymd = yasm_symrec_get_of_data(sym);
+ csymd = yasm_symrec_get_data(sym, &coff_symrec_data_cb);
assert(csymd != NULL);
- *ep = yasm_expr_new(YASM_EXPR_ADD, yasm_expr_expr(*ep),
- yasm_expr_expr(yasm_expr_copy(csymd->size)),
- csymd->size->line);
+ *ep = yasm_expr_create(YASM_EXPR_ADD, yasm_expr_expr(*ep),
+ yasm_expr_expr(yasm_expr_copy(csymd->size)),
+ csymd->size->line);
*ep = yasm_expr_simplify(*ep, yasm_common_calc_bc_dist);
}
} else if (!(vis & YASM_SYM_EXTERN)) {
/* Local symbols need relocation to their section's start */
- if (yasm_symrec_get_label(sym, &label_sect, &label_precbc)) {
+ if (yasm_symrec_get_label(sym, &label_precbc)) {
/*@null@*/ coff_section_data *label_csd;
- label_csd = yasm_section_get_of_data(label_sect);
+ label_sect = yasm_bc_get_section(label_precbc);
+ label_csd = yasm_section_get_data(label_sect,
+ &coff_section_data_cb);
assert(label_csd != NULL);
reloc->sym = label_csd->sym;
if (COFF_SET_VMA)
- *ep = yasm_expr_new(YASM_EXPR_ADD, yasm_expr_expr(*ep),
- yasm_expr_int(yasm_intnum_new_uint(label_csd->addr)),
+ *ep = yasm_expr_create(YASM_EXPR_ADD, yasm_expr_expr(*ep),
+ yasm_expr_int(yasm_intnum_create_uint(label_csd->addr)),
(*ep)->line);
}
}
* (really $+$.len) in.
*/
if (win32)
- *ep = yasm_expr_new(YASM_EXPR_ADD, yasm_expr_expr(*ep),
- yasm_expr_sym(yasm_symrec_define_label("$", info->sect, bc,
- 0, (*ep)->line)),
+ *ep = yasm_expr_create(YASM_EXPR_ADD, yasm_expr_expr(*ep),
+ yasm_expr_sym(yasm_symtab_define_label2("$", bc,
+ 0, (*ep)->line)),
(*ep)->line);
else
- *ep = yasm_expr_new(YASM_EXPR_ADD, yasm_expr_expr(*ep),
- yasm_expr_sym(yasm_symrec_define_label("$$", info->sect,
- NULL, 0,
- (*ep)->line)),
+ *ep = yasm_expr_create(YASM_EXPR_ADD, yasm_expr_expr(*ep),
+ yasm_expr_sym(yasm_symtab_define_label2("$$",
+ yasm_section_bcs_first(info->sect), 0, (*ep)->line)),
(*ep)->line);
*ep = yasm_expr_simplify(*ep, yasm_common_calc_bc_dist);
} else
}
intn = yasm_expr_get_intnum(ep, NULL);
if (intn)
- return cur_arch->intnum_tobytes(intn, buf, destsize, valsize, shift,
- bc, rel, warn, bc->line);
+ return cur_arch->module->intnum_tobytes(cur_arch, intn, buf, destsize,
+ valsize, shift, bc, rel, warn,
+ bc->line);
/* Check for complex float expressions */
if (yasm_expr__contains(*ep, YASM_EXPR_FLOAT)) {
assert(info != NULL);
- bigbuf = yasm_bc_tobytes(bc, info->buf, &size, &multiple, &gap, info->sect,
- info, coff_objfmt_output_expr, NULL, NULL);
+ bigbuf = yasm_bc_tobytes(bc, info->buf, &size, &multiple, &gap, info,
+ coff_objfmt_output_expr, NULL);
/* Don't bother doing anything else if size ended up being 0. */
if (size == 0) {
return 0;
assert(info != NULL);
- csd = yasm_section_get_of_data(sect);
+ csd = yasm_section_get_data(sect, &coff_section_data_cb);
assert(csd != NULL);
csd->addr = info->addr;
if ((csd->flags & COFF_STYP_STD_MASK) == COFF_STYP_BSS) {
- /*@null@*/ yasm_bytecode *last =
- yasm_bcs_last(yasm_section_get_bytecodes(sect));
+ yasm_bytecode *last = yasm_section_bcs_last(sect);
/* Don't output BSS sections.
* TODO: Check for non-reserve bytecodes?
*/
pos = 0; /* position = 0 because it's not in the file */
- if (last)
- csd->size = last->offset + last->len;
+ csd->size = last->offset + last->len;
} else {
- /*@null@*/ yasm_bytecode *last =
- yasm_bcs_last(yasm_section_get_bytecodes(sect));
+ yasm_bytecode *last = yasm_section_bcs_last(sect);
pos = ftell(info->f);
if (pos == -1) {
info->sect = sect;
info->csd = csd;
- yasm_bcs_traverse(yasm_section_get_bytecodes(sect), info,
- coff_objfmt_output_bytecode);
+ yasm_section_bcs_traverse(sect, info, coff_objfmt_output_bytecode);
/* Sanity check final section size */
if (csd->size != (last->offset + last->len))
unsigned char *localbuf = info->buf;
/*@null@*/ coff_symrec_data *csymd;
- csymd = yasm_symrec_get_of_data(reloc->sym);
+ csymd = yasm_symrec_get_data(reloc->sym, &coff_symrec_data_cb);
if (!csymd)
yasm_internal_error(
N_("coff: no symbol data for relocated symbol"));
return 0;
assert(info != NULL);
- csd = yasm_section_get_of_data(sect);
+ csd = yasm_section_get_data(sect, &coff_section_data_cb);
assert(csd != NULL);
localbuf = info->buf;
}
static void
-coff_objfmt_output(FILE *f, yasm_sectionhead *sections, int all_syms)
+coff_objfmt_output(FILE *f, yasm_object *object, int all_syms)
{
coff_objfmt_output_info info;
unsigned char *localbuf;
* addends in the generated code.
*/
info.addr = 0;
- if (yasm_sections_traverse(sections, &info,
- coff_objfmt_set_section_addr))
+ if (yasm_object_sections_traverse(object, &info,
+ coff_objfmt_set_section_addr))
return;
}
info.addr = 0;
- if (yasm_sections_traverse(sections, &info, coff_objfmt_output_section))
+ if (yasm_object_sections_traverse(object, &info,
+ coff_objfmt_output_section))
return;
/* Symbol table */
if (all_syms) {
/* Need to put all local syms into COFF symbol table */
- yasm_symrec_traverse(NULL, coff_objfmt_append_local_sym);
+ yasm_symtab_traverse(yasm_object_get_symtab(object), NULL,
+ coff_objfmt_append_local_sym);
}
pos = ftell(f);
if (pos == -1) {
unsigned long nreloc = 0; /* for sect auxent */
/* Get symrec's of_data (needed for storage class) */
- csymd = yasm_symrec_get_of_data(entry->sym);
+ csymd = yasm_symrec_get_data(entry->sym, &coff_symrec_data_cb);
if (!csymd)
yasm_internal_error(N_("coff: expected sym data to be present"));
/* Look at symrec for value/scnum/etc. */
- if (yasm_symrec_get_label(entry->sym, §, &precbc)) {
+ if (yasm_symrec_get_label(entry->sym, &precbc)) {
+ if (precbc)
+ sect = yasm_bc_get_section(precbc);
+ else
+ sect = NULL;
/* it's a label: get value and offset.
* If there is not a section, leave as debugging symbol.
*/
if (sect) {
/*@dependent@*/ /*@null@*/ coff_section_data *csectd;
- csectd = yasm_section_get_of_data(sect);
+ csectd = yasm_section_get_data(sect, &coff_section_data_cb);
if (csectd) {
scnum = csectd->scnum;
scnlen = csectd->size;
N_("absolute section start not an integer expression"));
else
value = yasm_intnum_get_uint(intn);
- yasm_expr_delete(abs_start);
+ yasm_expr_destroy(abs_start);
scnum = 0xffff; /* -1 = absolute symbol */
} else
N_("global EQU value not an integer expression"));
} else
value = yasm_intnum_get_uint(intn);
- yasm_expr_delete(equ_val_copy);
+ yasm_expr_destroy(equ_val_copy);
scnum = 0xffff; /* -1 = absolute symbol */
} else {
|(all_syms?0:COFF_F_LSYMS));
fwrite(info.buf, 20, 1, f);
- yasm_sections_traverse(sections, &info, coff_objfmt_output_secthead);
+ yasm_object_sections_traverse(object, &info, coff_objfmt_output_secthead);
yasm_xfree(info.buf);
}
}
static /*@observer@*/ /*@null@*/ yasm_section *
-coff_objfmt_sections_switch(yasm_sectionhead *headp,
- yasm_valparamhead *valparams,
+coff_objfmt_section_switch(yasm_object *object, yasm_valparamhead *valparams,
/*@unused@*/ /*@null@*/
yasm_valparamhead *objext_valparams,
- unsigned long lindex)
+ unsigned long line)
{
yasm_valparam *vp = yasm_vps_first(valparams);
yasm_section *retval;
/* TODO: win32 format supports >8 character section names in object
* files via "/nnnn" (where nnnn is decimal offset into string table).
*/
- yasm__warning(YASM_WARN_GENERAL, lindex,
+ yasm__warning(YASM_WARN_GENERAL, line,
N_("COFF section names limited to 8 characters: truncating"));
sectname[8] = '\0';
}
if (win32)
flags |= COFF_STYP_READ | (4<<COFF_STYP_ALIGN_SHIFT); /* align=8 */
else
- yasm__warning(YASM_WARN_GENERAL, lindex,
+ yasm__warning(YASM_WARN_GENERAL, line,
N_("Standard COFF does not support read-only data sections"));
} else {
/* Default to code */
align = yasm_expr_get_intnum(&vp->param, NULL);
if (!align) {
- yasm__error(lindex,
+ yasm__error(line,
N_("argument to `%s' is not a power of two"),
vp->val);
return NULL;
*/
BitCount(bitcnt, addralign);
if (bitcnt > 1) {
- yasm__error(lindex,
+ yasm__error(line,
N_("argument to `%s' is not a power of two"),
vp->val);
return NULL;
/* Check to see if alignment is supported size */
if (addralign > 8192) {
- yasm__error(lindex,
+ yasm__error(line,
N_("Win32 does not support alignments > 8192"));
return NULL;
}
} else
win32warn = 1;
} else
- yasm__warning(YASM_WARN_GENERAL, lindex,
+ yasm__warning(YASM_WARN_GENERAL, line,
N_("Unrecognized qualifier `%s'"), vp->val);
if (win32warn)
- yasm__warning(YASM_WARN_GENERAL, lindex,
+ yasm__warning(YASM_WARN_GENERAL, line,
N_("Standard COFF does not support qualifier `%s'"), vp->val);
}
- retval = yasm_sections_switch_general(headp, sectname, 0, resonly, &isnew,
- lindex);
+ retval = yasm_object_get_general(object, sectname, 0, resonly, &isnew,
+ line);
if (isnew) {
coff_section_data *data;
data->relptr = 0;
data->nreloc = 0;
STAILQ_INIT(&data->relocs);
- yasm_section_set_of_data(retval, &yasm_coff_LTX_objfmt, data);
+ yasm_section_add_data(retval, &coff_section_data_cb, data);
- sym = yasm_symrec_define_label(sectname, retval, (yasm_bytecode *)NULL,
- 1, lindex);
+ sym =
+ yasm_symtab_define_label(yasm_object_get_symtab(object), sectname,
+ yasm_section_bcs_first(retval), 1, line);
coff_objfmt_symtab_append(sym, COFF_SCL_STAT, NULL, 1,
COFF_SYMTAB_AUX_SECT);
data->sym = sym;
} else if (flags_override)
- yasm__warning(YASM_WARN_GENERAL, lindex,
+ yasm__warning(YASM_WARN_GENERAL, line,
N_("section flags ignored on section redeclaration"));
return retval;
}
static void
-coff_objfmt_section_data_delete(/*@only@*/ void *data)
+coff_section_data_destroy(void *data)
{
coff_section_data *csd = (coff_section_data *)data;
coff_reloc *r1, *r2;
}
static void
-coff_objfmt_section_data_print(FILE *f, int indent_level, void *data)
+coff_section_data_print(void *data, FILE *f, int indent_level)
{
coff_section_data *csd = (coff_section_data *)data;
coff_reloc *reloc;
unsigned long relocnum = 0;
fprintf(f, "%*ssym=\n", indent_level, "");
- yasm_symrec_print(f, indent_level+1, csd->sym);
+ yasm_symrec_print(csd->sym, f, indent_level+1);
fprintf(f, "%*sscnum=%d\n", indent_level, "", csd->scnum);
fprintf(f, "%*sflags=", indent_level, "");
switch (csd->flags & COFF_STYP_STD_MASK) {
STAILQ_FOREACH(reloc, &csd->relocs, link) {
fprintf(f, "%*sReloc %lu:\n", indent_level+1, "", relocnum++);
fprintf(f, "%*ssym=\n", indent_level+2, "");
- yasm_symrec_print(f, indent_level+3, reloc->sym);
+ yasm_symrec_print(reloc->sym, f, indent_level+3);
fprintf(f, "%*stype=", indent_level+2, "");
switch (reloc->type) {
case COFF_RELOC_ADDR32:
static void
coff_objfmt_extglob_declare(yasm_symrec *sym, /*@unused@*/
/*@null@*/ yasm_valparamhead *objext_valparams,
- /*@unused@*/ unsigned long lindex)
+ /*@unused@*/ unsigned long line)
{
coff_objfmt_symtab_append(sym, COFF_SCL_EXT, NULL, 0,
COFF_SYMTAB_AUX_NONE);
coff_objfmt_common_declare(yasm_symrec *sym, /*@only@*/ yasm_expr *size,
/*@unused@*/ /*@null@*/
yasm_valparamhead *objext_valparams,
- /*@unused@*/ unsigned long lindex)
+ /*@unused@*/ unsigned long line)
{
coff_objfmt_symtab_append(sym, COFF_SCL_EXT, size, 0,
COFF_SYMTAB_AUX_NONE);
}
static void
-coff_objfmt_symrec_data_delete(/*@only@*/ void *data)
+coff_symrec_data_destroy(void *data)
{
coff_symrec_data *csymd = (coff_symrec_data *)data;
if (csymd->size)
- yasm_expr_delete(csymd->size);
+ yasm_expr_destroy(csymd->size);
yasm_xfree(data);
}
static void
-coff_objfmt_symrec_data_print(FILE *f, int indent_level, void *data)
+coff_symrec_data_print(void *data, FILE *f, int indent_level)
{
coff_symrec_data *csd = (coff_symrec_data *)data;
fprintf(f, "%*ssclass=%d\n", indent_level, "", csd->sclass);
fprintf(f, "%*ssize=", indent_level, "");
if (csd->size)
- yasm_expr_print(f, csd->size);
+ yasm_expr_print(csd->size, f);
else
fprintf(f, "nil");
fprintf(f, "\n");
/*@unused@*/ yasm_valparamhead *valparams,
/*@unused@*/ /*@null@*/
yasm_valparamhead *objext_valparams,
- /*@unused@*/ yasm_sectionhead *headp,
- /*@unused@*/ unsigned long lindex)
+ /*@unused@*/ yasm_object *object,
+ /*@unused@*/ unsigned long line)
{
return 1; /* no objfmt directives */
}
coff_objfmt_initialize,
coff_objfmt_output,
coff_objfmt_cleanup,
- coff_objfmt_sections_switch,
- coff_objfmt_section_data_delete,
- coff_objfmt_section_data_print,
+ coff_objfmt_section_switch,
coff_objfmt_extglob_declare,
coff_objfmt_extglob_declare,
coff_objfmt_common_declare,
- coff_objfmt_symrec_data_delete,
- coff_objfmt_symrec_data_print,
- coff_objfmt_directive,
- NULL /*coff_objfmt_bc_objfmt_data_delete*/,
- NULL /*coff_objfmt_bc_objfmt_data_print*/
+ coff_objfmt_directive
};
/* Define objfmt structure -- see objfmt.h for details */
win32_objfmt_initialize,
coff_objfmt_output,
coff_objfmt_cleanup,
- coff_objfmt_sections_switch,
- coff_objfmt_section_data_delete,
- coff_objfmt_section_data_print,
+ coff_objfmt_section_switch,
coff_objfmt_extglob_declare,
coff_objfmt_extglob_declare,
coff_objfmt_common_declare,
- coff_objfmt_symrec_data_delete,
- coff_objfmt_symrec_data_print,
- coff_objfmt_directive,
- NULL /*coff_objfmt_bc_objfmt_data_delete*/,
- NULL /*coff_objfmt_bc_objfmt_data_print*/
+ coff_objfmt_directive
};
#include <libyasm.h>
-yasm_objfmt yasm_dbg_LTX_objfmt;
+static void symrec_data_destroy(/*@only@*/ void *data);
+static void symrec_data_print(void *data, FILE *f, int indent_level);
+
+static const yasm_assoc_data_callback symrec_data_callback = {
+ symrec_data_destroy,
+ symrec_data_print
+};
/* Output file for debugging-type formats. This is so that functions that are
* called before the object file is usually opened can still write data out to
static int
dbg_objfmt_initialize(const char *in_filename, const char *obj_filename,
- yasm_dbgfmt *df, yasm_arch *a, const char *machine)
+ yasm_object *object, yasm_dbgfmt *df, yasm_arch *a)
{
dbg_objfmt_file = fopen(obj_filename, "wt");
if (!dbg_objfmt_file) {
return 0;
}
fprintf(dbg_objfmt_file,
- "initialize(\"%s\", \"%s\", %s dbgfmt, %s arch, \"%s\")\n",
- in_filename, obj_filename, df->keyword, a->keyword, machine);
+ "initialize(\"%s\", \"%s\", %s dbgfmt, %s arch)\n",
+ in_filename, obj_filename, df->keyword, a->module->keyword);
return 0;
}
static void
-dbg_objfmt_output(/*@unused@*/ FILE *f, yasm_sectionhead *sections,
- int all_syms)
+dbg_objfmt_output(/*@unused@*/ FILE *f, yasm_object *object, int all_syms)
{
- fprintf(dbg_objfmt_file, "output(f, sections->\n");
- yasm_sections_print(dbg_objfmt_file, 1, sections);
+ fprintf(dbg_objfmt_file, "output(f, object->\n");
+ yasm_object_print(object, dbg_objfmt_file, 1);
fprintf(dbg_objfmt_file, "%d)\n", all_syms);
fprintf(dbg_objfmt_file, " Symbol Table:\n");
- yasm_symrec_print_all(dbg_objfmt_file, 1);
+ yasm_symtab_print(yasm_object_get_symtab(object), dbg_objfmt_file, 1);
}
static void
}
static /*@observer@*/ /*@null@*/ yasm_section *
-dbg_objfmt_sections_switch(yasm_sectionhead *headp,
- yasm_valparamhead *valparams,
- /*@unused@*/ /*@null@*/
- yasm_valparamhead *objext_valparams,
- unsigned long lindex)
+dbg_objfmt_section_switch(yasm_object *object, yasm_valparamhead *valparams,
+ /*@unused@*/ /*@null@*/
+ yasm_valparamhead *objext_valparams,
+ unsigned long line)
{
yasm_valparam *vp;
yasm_section *retval;
int isnew;
fprintf(dbg_objfmt_file, "sections_switch(headp, ");
- yasm_vps_print(dbg_objfmt_file, valparams);
+ yasm_vps_print(valparams, dbg_objfmt_file);
fprintf(dbg_objfmt_file, ", ");
- yasm_vps_print(dbg_objfmt_file, objext_valparams);
- fprintf(dbg_objfmt_file, ", %lu), returning ", lindex);
+ yasm_vps_print(objext_valparams, dbg_objfmt_file);
+ fprintf(dbg_objfmt_file, ", %lu), returning ", line);
if ((vp = yasm_vps_first(valparams)) && !vp->param && vp->val != NULL) {
- retval = yasm_sections_switch_general(headp, vp->val,
- yasm_expr_new_ident(yasm_expr_int(yasm_intnum_new_uint(200)),
- lindex), 0, &isnew, lindex);
+ retval = yasm_object_get_general(object, vp->val,
+ yasm_expr_create_ident(yasm_expr_int(yasm_intnum_create_uint(200)),
+ line), 0, &isnew, line);
if (isnew) {
fprintf(dbg_objfmt_file, "(new) ");
- yasm_symrec_define_label(vp->val, retval, (yasm_bytecode *)NULL, 1,
- lindex);
+ yasm_symtab_define_label(yasm_object_get_symtab(object), vp->val,
+ yasm_section_bcs_first(retval), 1, line);
}
fprintf(dbg_objfmt_file, "\"%s\" section\n", vp->val);
return retval;
}
}
-static void
-dbg_objfmt_section_data_delete(/*@only@*/ void *data)
-{
- fprintf(dbg_objfmt_file, "section_data_delete(%p)\n", data);
- yasm_xfree(data);
-}
-
-static void
-dbg_objfmt_section_data_print(FILE *f, int indent_level, /*@null@*/ void *data)
-{
- if (data)
- fprintf(f, "%*s%p\n", indent_level, "", data);
- else
- fprintf(f, "%*s(none)\n", indent_level, "");
-}
-
static void
dbg_objfmt_extern_declare(yasm_symrec *sym, /*@unused@*/ /*@null@*/
yasm_valparamhead *objext_valparams,
- unsigned long lindex)
+ unsigned long line)
{
fprintf(dbg_objfmt_file, "extern_declare(\"%s\", ",
yasm_symrec_get_name(sym));
- yasm_vps_print(dbg_objfmt_file, objext_valparams);
- fprintf(dbg_objfmt_file, ", %lu), setting of_data=NULL\n", lindex);
- yasm_symrec_set_of_data(sym, &yasm_dbg_LTX_objfmt, NULL);
+ yasm_vps_print(objext_valparams, dbg_objfmt_file);
+ fprintf(dbg_objfmt_file, ", %lu)\n", line);
}
static void
dbg_objfmt_global_declare(yasm_symrec *sym, /*@unused@*/ /*@null@*/
yasm_valparamhead *objext_valparams,
- unsigned long lindex)
+ unsigned long line)
{
fprintf(dbg_objfmt_file, "global_declare(\"%s\", ",
yasm_symrec_get_name(sym));
- yasm_vps_print(dbg_objfmt_file, objext_valparams);
- fprintf(dbg_objfmt_file, ", %lu), setting of_data=NULL\n", lindex);
- yasm_symrec_set_of_data(sym, &yasm_dbg_LTX_objfmt, NULL);
+ yasm_vps_print(objext_valparams, dbg_objfmt_file);
+ fprintf(dbg_objfmt_file, ", %lu)\n", line);
}
static void
dbg_objfmt_common_declare(yasm_symrec *sym, /*@only@*/ yasm_expr *size,
/*@unused@*/ /*@null@*/
yasm_valparamhead *objext_valparams,
- unsigned long lindex)
+ unsigned long line)
{
assert(dbg_objfmt_file != NULL);
fprintf(dbg_objfmt_file, "common_declare(\"%s\", ",
yasm_symrec_get_name(sym));
- yasm_expr_print(dbg_objfmt_file, size);
+ yasm_expr_print(size, dbg_objfmt_file);
fprintf(dbg_objfmt_file, ", ");
- yasm_vps_print(dbg_objfmt_file, objext_valparams);
- fprintf(dbg_objfmt_file, ", %lu), setting of_data=", lindex);
- yasm_expr_print(dbg_objfmt_file, size);
- yasm_symrec_set_of_data(sym, &yasm_dbg_LTX_objfmt, size);
+ yasm_vps_print(objext_valparams, dbg_objfmt_file);
+ fprintf(dbg_objfmt_file, ", %lu), setting of_data=", line);
+ yasm_expr_print(size, dbg_objfmt_file);
+ yasm_symrec_add_data(sym, &symrec_data_callback, size);
fprintf(dbg_objfmt_file, "\n");
}
static void
-dbg_objfmt_symrec_data_delete(/*@only@*/ void *data)
+symrec_data_destroy(void *data)
{
fprintf(dbg_objfmt_file, "symrec_data_delete(");
if (data) {
- yasm_expr_print(dbg_objfmt_file, data);
- yasm_expr_delete(data);
+ yasm_expr_print((yasm_expr *)data, dbg_objfmt_file);
+ yasm_expr_destroy((yasm_expr *)data);
}
fprintf(dbg_objfmt_file, ")\n");
}
static void
-dbg_objfmt_symrec_data_print(FILE *f, int indent_level, /*@null@*/ void *data)
+symrec_data_print(void *data, FILE *f, int indent_level)
{
if (data) {
fprintf(f, "%*sSize=", indent_level, "");
- yasm_expr_print(f, data);
+ yasm_expr_print((yasm_expr *)data, f);
fprintf(f, "\n");
} else {
fprintf(f, "%*s(none)\n", indent_level, "");
static int
dbg_objfmt_directive(const char *name, yasm_valparamhead *valparams,
/*@null@*/ yasm_valparamhead *objext_valparams,
- /*@unused@*/ yasm_sectionhead *headp,
- unsigned long lindex)
+ /*@unused@*/ yasm_object *object,
+ unsigned long line)
{
fprintf(dbg_objfmt_file, "directive(\"%s\", ", name);
- yasm_vps_print(dbg_objfmt_file, valparams);
+ yasm_vps_print(valparams, dbg_objfmt_file);
fprintf(dbg_objfmt_file, ", ");
- yasm_vps_print(dbg_objfmt_file, objext_valparams);
- fprintf(dbg_objfmt_file, ", %lu), returning 0 (recognized)\n", lindex);
+ yasm_vps_print(objext_valparams, dbg_objfmt_file);
+ fprintf(dbg_objfmt_file, ", %lu), returning 0 (recognized)\n", line);
return 0; /* dbg format "recognizes" all directives */
}
-static void
-dbg_objfmt_bc_objfmt_data_delete(unsigned int type, /*@only@*/ void *data)
-{
- fprintf(dbg_objfmt_file, "symrec_data_delete(%u, %p)\n", type, data);
- yasm_xfree(data);
-}
-
-static void
-dbg_objfmt_bc_objfmt_data_print(FILE *f, int indent_level, unsigned int type,
- const void *data)
-{
- fprintf(f, "%*sType=%u\n", indent_level, "", type);
- fprintf(f, "%*sData=%p\n", indent_level, "", data);
-}
-
/* Define valid debug formats to use with this object format */
static const char *dbg_objfmt_dbgfmt_keywords[] = {
dbg_objfmt_initialize,
dbg_objfmt_output,
dbg_objfmt_cleanup,
- dbg_objfmt_sections_switch,
- dbg_objfmt_section_data_delete,
- dbg_objfmt_section_data_print,
+ dbg_objfmt_section_switch,
dbg_objfmt_extern_declare,
dbg_objfmt_global_declare,
dbg_objfmt_common_declare,
- dbg_objfmt_symrec_data_delete,
- dbg_objfmt_symrec_data_print,
- dbg_objfmt_directive,
- dbg_objfmt_bc_objfmt_data_delete,
- dbg_objfmt_bc_objfmt_data_print
+ dbg_objfmt_directive
};
FILE *f;
elf_secthead *shead;
yasm_section *sect;
- yasm_sectionhead *sections;
+ yasm_object *object;
unsigned long sindex;
} elf_objfmt_output_info;
static elf_strtab_head* elf_shstrtab; /* section name strtab */
static elf_strtab_head* elf_strtab; /* strtab entries */
-yasm_objfmt yasm_elf_LTX_objfmt;
static /*@dependent@*/ yasm_arch *cur_arch;
static /*@dependent@*/ yasm_dbgfmt *cur_dbgfmt;
{
elf_strtab_entry *name = elf_strtab_append_str(elf_strtab,
yasm_symrec_get_name(sym));
- elf_symtab_entry *entry = elf_symtab_entry_new(name, sym);
+ elf_symtab_entry *entry = elf_symtab_entry_create(name, sym);
elf_symtab_append_entry(elf_symtab, entry);
elf_symtab_set_nonzero(entry, NULL, sectidx, bind, STT_NOTYPE, size, 00);
- yasm_symrec_set_of_data(sym, &yasm_elf_LTX_objfmt, entry);
+ yasm_symrec_add_data(sym, &elf_symrec_data, entry);
return entry;
}
yasm_section *sect=NULL;
yasm_bytecode *precbc=NULL;
- if (!yasm_symrec_get_of_data(sym)) {
+ if (!yasm_symrec_get_data(sym, &elf_symrec_data)) {
int is_sect = 0;
- if (!yasm_symrec_get_label(sym, §, &precbc))
+ if (!yasm_symrec_get_label(sym, &precbc))
return 1;
+ sect = yasm_bc_get_section(precbc);
is_sect = strcmp(yasm_symrec_get_name(sym), yasm_section_get_name(sect))==0;
/* neither sections nor locals (except when debugging) need names */
local_names && !is_sect ? elf_strtab : NULL, sym);
elf_symtab_set_nonzero(entry, sect, 0, STB_LOCAL,
is_sect ? STT_SECTION : STT_NOTYPE, NULL, 0);
- yasm_symrec_set_of_data(sym, &yasm_elf_LTX_objfmt, entry);
+ yasm_symrec_add_data(sym, &elf_symrec_data, entry);
if (is_sect)
return 1;
}
else {
- if (!yasm_symrec_get_label(sym, §, &precbc))
+ if (!yasm_symrec_get_label(sym, &precbc))
return 1;
+ sect = yasm_bc_get_section(precbc);
}
- entry = yasm_symrec_get_of_data(sym);
+ entry = yasm_symrec_get_data(sym, &elf_symrec_data);
if (precbc)
value = precbc->offset + precbc->len;
elf_symtab_set_nonzero(entry, sect, 0, 0, 0, NULL, value);
static int
elf_objfmt_initialize(const char *in_filename,
/*@unused@*/ const char *obj_filename,
- /*@unused@*/ yasm_dbgfmt *df, yasm_arch *a,
- const char *machine)
+ yasm_object *object, /*@unused@*/ yasm_dbgfmt *df,
+ yasm_arch *a)
{
yasm_symrec *filesym;
elf_symtab_entry *entry;
cur_arch = a;
cur_dbgfmt = df;
- if (!elf_set_arch(a, machine))
+ if (!elf_set_arch(a))
return 1;
elf_objfmt_parse_scnum = 4; /* section numbering starts at 0;
4 predefined sections. */
- elf_shstrtab = elf_strtab_new();
- elf_strtab = elf_strtab_new();
- elf_symtab = elf_symtab_new();
-
- filesym = yasm_symrec_define_label(".file", NULL, NULL, 0, 0);
- entry = elf_symtab_entry_new(
+ elf_shstrtab = elf_strtab_create();
+ elf_strtab = elf_strtab_create();
+ elf_symtab = elf_symtab_create();
+
+ /* FIXME: misuse of NULL bytecode here; it works, but only barely. */
+ filesym = yasm_symtab_define_label(yasm_object_get_symtab(object), ".file",
+ NULL, 0, 0);
+ entry = elf_symtab_entry_create(
elf_strtab_append_str(elf_strtab, in_filename), filesym);
- yasm_symrec_set_of_data(filesym, &yasm_elf_LTX_objfmt, entry);
+ yasm_symrec_add_data(filesym, &elf_symrec_data, entry);
elf_symtab_set_nonzero(entry, NULL, SHN_ABS, STB_LOCAL, STT_FILE, NULL, 0);
elf_symtab_append_entry(elf_symtab, entry);
static int
elf_objfmt_output_reloc(yasm_symrec *sym, yasm_bytecode *bc,
unsigned char *buf, size_t destsize, size_t valsize,
- int rel, int warn, const yasm_section *sect, void *d)
+ int rel, int warn, void *d)
{
elf_reloc_entry *reloc;
elf_objfmt_output_info *info = d;
- yasm_intnum *zero = yasm_intnum_new_uint(0);
+ yasm_intnum *zero = yasm_intnum_create_uint(0);
int retval;
- reloc = elf_reloc_entry_new(sym,
- yasm_intnum_new_uint(bc->offset), rel, valsize);
+ reloc = elf_reloc_entry_create(sym,
+ yasm_intnum_create_uint(bc->offset), rel, valsize);
if (reloc == NULL) {
yasm__error(bc->line, N_("elf: invalid relocation size"));
return 1;
if (elf_secthead_append_reloc(info->shead, reloc))
elf_objfmt_parse_scnum++;
- retval = cur_arch->intnum_tobytes(zero, buf, destsize, valsize, 0,
- bc, rel, warn, bc->line);
- yasm_intnum_delete(zero);
+ retval = cur_arch->module->intnum_tobytes(cur_arch, zero, buf, destsize,
+ valsize, 0, bc, rel, warn,
+ bc->line);
+ yasm_intnum_destroy(zero);
return retval;
}
static int
elf_objfmt_output_expr(yasm_expr **ep, unsigned char *buf, size_t destsize,
size_t valsize, int shift, unsigned long offset,
- /*@observer@*/ const yasm_section *sect,
yasm_bytecode *bc, int rel, int warn,
/*@null@*/ void *d)
{
if (flt) {
if (shift < 0)
yasm_internal_error(N_("attempting to negative shift a float"));
- return cur_arch->floatnum_tobytes(flt, buf, destsize, valsize,
- (unsigned int)shift, warn, bc->line);
+ return cur_arch->module->floatnum_tobytes(cur_arch, flt, buf, destsize,
+ valsize, (unsigned int)shift,
+ warn, bc->line);
}
/* Handle integer expressions, with relocation if necessary */
vis = yasm_symrec_get_visibility(sym);
if (!(vis & (YASM_SYM_COMMON|YASM_SYM_EXTERN)))
{
- yasm_section *label_sect;
yasm_bytecode *label_precbc;
/* Local symbols need relocation to their section's start */
- if (yasm_symrec_get_label(sym, &label_sect, &label_precbc)) {
+ if (yasm_symrec_get_label(sym, &label_precbc)) {
+ yasm_section *label_sect = yasm_bc_get_section(label_precbc);
/*@null@*/ elf_secthead *sym_shead;
- sym_shead = yasm_section_get_of_data(label_sect);
+ sym_shead =
+ yasm_section_get_data(label_sect, &elf_section_data);
assert(sym_shead != NULL);
sym = elf_secthead_get_sym(sym_shead);
}
if (rel) {
/* Need to reference to start of section, so add $$ in. */
- *ep = yasm_expr_new(YASM_EXPR_ADD, yasm_expr_expr(*ep),
- yasm_expr_sym(yasm_symrec_define_label("$$", info->sect,
- NULL, 0, (*ep)->line)),
+ *ep = yasm_expr_create(YASM_EXPR_ADD, yasm_expr_expr(*ep),
+ yasm_expr_sym(yasm_symtab_define_label2("$$",
+ yasm_section_bcs_first(info->sect), 0, (*ep)->line)),
(*ep)->line);
/* HELP: and this seems to have the desired effect. */
- *ep = yasm_expr_new(YASM_EXPR_ADD, yasm_expr_expr(*ep),
- yasm_expr_int(yasm_intnum_new_uint(bc->offset + offset)),
+ *ep = yasm_expr_create(YASM_EXPR_ADD, yasm_expr_expr(*ep),
+ yasm_expr_int(yasm_intnum_create_uint(bc->offset + offset)),
(*ep)->line);
*ep = yasm_expr_simplify(*ep, yasm_common_calc_bc_dist);
}
- reloc = elf_reloc_entry_new(sym,
- yasm_intnum_new_uint(bc->offset + offset), rel, valsize);
+ reloc = elf_reloc_entry_create(sym,
+ yasm_intnum_create_uint(bc->offset + offset), rel, valsize);
if (reloc == NULL) {
yasm__error(bc->line, N_("elf: invalid relocation size"));
return 1;
intn = yasm_expr_get_intnum(ep, NULL);
if (intn)
- return cur_arch->intnum_tobytes(intn, buf, destsize, valsize, shift,
- bc, rel, warn, bc->line);
+ return cur_arch->module->intnum_tobytes(cur_arch, intn, buf, destsize,
+ valsize, shift, bc, rel, warn,
+ bc->line);
/* Check for complex float expressions */
if (yasm_expr__contains(*ep, YASM_EXPR_FLOAT)) {
if (info == NULL)
yasm_internal_error("null info struct");
- bigbuf = yasm_bc_tobytes(bc, buf, &size, &multiple, &gap, info->sect,
- info, elf_objfmt_output_expr,
- elf_objfmt_output_reloc, NULL);
+ bigbuf = yasm_bc_tobytes(bc, buf, &size, &multiple, &gap, info,
+ elf_objfmt_output_expr, elf_objfmt_output_reloc);
/* Don't bother doing anything else if size ended up being 0. */
if (size == 0) {
return 0;
}
else {
- yasm_intnum *bcsize = yasm_intnum_new_uint(size);
- yasm_intnum *mult = yasm_intnum_new_uint(multiple);
+ yasm_intnum *bcsize = yasm_intnum_create_uint(size);
+ yasm_intnum *mult = yasm_intnum_create_uint(multiple);
yasm_intnum_calc(bcsize, YASM_EXPR_MUL, mult, 0);
elf_secthead_add_size(info->shead, bcsize);
- yasm_intnum_delete(bcsize);
- yasm_intnum_delete(mult);
+ yasm_intnum_destroy(bcsize);
+ yasm_intnum_destroy(mult);
}
/* Warn that gaps are converted to 0 and write out the 0's. */
}
static elf_secthead *
-elf_objfmt_new_dbg_secthead(yasm_section *sect, elf_objfmt_output_info *info)
+elf_objfmt_create_dbg_secthead(yasm_section *sect,
+ elf_objfmt_output_info *info)
{
elf_secthead *shead;
elf_section_type type=SHT_PROGBITS;
elf_strtab_entry *name = elf_strtab_append_str(elf_shstrtab, sectname);
if (yasm__strcasecmp(sectname, ".stab")==0) {
- align = yasm_intnum_new_uint(4);
+ align = yasm_intnum_create_uint(4);
entsize = 12;
} else if (yasm__strcasecmp(sectname, ".stabstr")==0) {
type = SHT_STRTAB;
- align = yasm_intnum_new_uint(1);
+ align = yasm_intnum_create_uint(1);
}
else
yasm_internal_error(N_("Unrecognized section without data"));
- shead = elf_secthead_new(name, type, 0, elf_objfmt_parse_scnum++, 0, 0);
+ shead = elf_secthead_create(name, type, 0, elf_objfmt_parse_scnum++, 0, 0);
elf_secthead_set_align(shead, align);
elf_secthead_set_entsize(shead, entsize);
- yasm_section_set_of_data(sect, &yasm_elf_LTX_objfmt, shead);
+ yasm_section_add_data(sect, &elf_section_data, shead);
return shead;
}
if (info == NULL)
yasm_internal_error("null info struct");
- shead = yasm_section_get_of_data(sect);
+ shead = yasm_section_get_data(sect, &elf_section_data);
if (shead == NULL)
- shead = elf_objfmt_new_dbg_secthead(sect, info);
+ shead = elf_objfmt_create_dbg_secthead(sect, info);
/* don't output header-only sections */
if ((elf_secthead_get_type(shead) & SHT_NOBITS) == SHT_NOBITS)
{
- yasm_bytecode *last = yasm_bcs_last(yasm_section_get_bytecodes(sect));
+ yasm_bytecode *last = yasm_section_bcs_last(sect);
if (last) {
yasm_intnum *sectsize;
- sectsize = yasm_intnum_new_uint(last->offset + last->len);
+ sectsize = yasm_intnum_create_uint(last->offset + last->len);
elf_secthead_add_size(shead, sectsize);
- yasm_intnum_delete(sectsize);
+ yasm_intnum_destroy(sectsize);
}
elf_secthead_set_index(shead, ++info->sindex);
return 0;
}
/* skip empty sections */
- if (!yasm_bcs_last(yasm_section_get_bytecodes(sect))) {
+ if (yasm_section_bcs_last(sect) == yasm_section_bcs_first(sect)) {
return 0;
}
info->sect = sect;
info->shead = shead;
- yasm_bcs_traverse(yasm_section_get_bytecodes(sect), info,
- elf_objfmt_output_bytecode);
+ yasm_section_bcs_traverse(sect, info, elf_objfmt_output_bytecode);
/* Empty? Go on to next section */
if (elf_secthead_is_empty(shead))
if (info == NULL)
yasm_internal_error("null info struct");
- shead = yasm_section_get_of_data(sect);
+ shead = yasm_section_get_data(sect, &elf_section_data);
if (shead == NULL)
yasm_internal_error("no section header attached to section");
}
static void
-elf_objfmt_output(FILE *f, yasm_sectionhead *sections, int all_syms)
+elf_objfmt_output(FILE *f, yasm_object *object, int all_syms)
{
elf_objfmt_output_info info;
long pos;
/* add all (local) syms to symtab because relocation needs a symtab index
* if all_syms, register them by name. if not, use strtab entry 0 */
- yasm_symrec_traverse((void *)&all_syms, elf_objfmt_append_local_sym);
+ yasm_symtab_traverse(yasm_object_get_symtab(object), (void *)&all_syms,
+ elf_objfmt_append_local_sym);
elf_symtab_nlocal = elf_symtab_assign_indices(elf_symtab);
/* output known sections - includes reloc sections which aren't in yasm's
* list. Assign indices as we go. */
info.sindex = 3;
- if (yasm_sections_traverse(sections, &info, elf_objfmt_output_section))
+ if (yasm_object_sections_traverse(object, &info,
+ elf_objfmt_output_section))
return;
/* add final sections to the shstrtab */
/* stabs debugging support */
if (strcmp(cur_dbgfmt->keyword, "stabs")==0) {
- yasm_section *stabsect = yasm_sections_find_general(sections, ".stab");
- yasm_section *stabstrsect = yasm_sections_find_general(sections, ".stabstr");
+ yasm_section *stabsect = yasm_object_find_general(object, ".stab");
+ yasm_section *stabstrsect =
+ yasm_object_find_general(object, ".stabstr");
if (stabsect && stabstrsect) {
- elf_secthead *stab = yasm_section_get_of_data(stabsect);
- elf_secthead *stabstr = yasm_section_get_of_data(stabstrsect);
+ elf_secthead *stab =
+ yasm_section_get_data(stabsect, &elf_section_data);
+ elf_secthead *stabstr =
+ yasm_section_get_data(stabstrsect, &elf_section_data);
if (stab && stabstr) {
elf_secthead_set_link(stab, elf_secthead_get_index(stabstr));
}
/* output dummy section header - 0 */
info.sindex = 0;
- esdn = elf_secthead_new(NULL, SHT_NULL, 0, 0, 0, 0);
+ esdn = elf_secthead_create(NULL, SHT_NULL, 0, 0, 0, 0);
elf_secthead_write_to_file(f, esdn, 0);
- elf_secthead_delete(esdn);
+ elf_secthead_destroy(esdn);
- esdn = elf_secthead_new(elf_shstrtab_name, SHT_STRTAB, 0, 1,
- elf_shstrtab_offset, elf_shstrtab_size);
+ esdn = elf_secthead_create(elf_shstrtab_name, SHT_STRTAB, 0, 1,
+ elf_shstrtab_offset, elf_shstrtab_size);
elf_secthead_write_to_file(f, esdn, 1);
- elf_secthead_delete(esdn);
+ elf_secthead_destroy(esdn);
- esdn = elf_secthead_new(elf_strtab_name, SHT_STRTAB, 0, 2,
- elf_strtab_offset, elf_strtab_size);
+ esdn = elf_secthead_create(elf_strtab_name, SHT_STRTAB, 0, 2,
+ elf_strtab_offset, elf_strtab_size);
elf_secthead_write_to_file(f, esdn, 2);
- elf_secthead_delete(esdn);
+ elf_secthead_destroy(esdn);
- esdn = elf_secthead_new(elf_symtab_name, SHT_SYMTAB, 0, 3,
- elf_symtab_offset, elf_symtab_size);
+ esdn = elf_secthead_create(elf_symtab_name, SHT_SYMTAB, 0, 3,
+ elf_symtab_offset, elf_symtab_size);
elf_secthead_set_info(esdn, elf_symtab_nlocal);
elf_secthead_set_link(esdn, 2); /* for .strtab, which is index 2 */
elf_secthead_write_to_file(f, esdn, 3);
- elf_secthead_delete(esdn);
+ elf_secthead_destroy(esdn);
info.sindex = 3;
/* output remaining section headers */
- yasm_sections_traverse(sections, &info, elf_objfmt_output_secthead);
+ yasm_object_sections_traverse(object, &info, elf_objfmt_output_secthead);
/* output Ehdr */
if (fseek(f, 0, SEEK_SET) < 0) {
static void
elf_objfmt_cleanup(void)
{
- elf_symtab_delete(elf_symtab);
- elf_strtab_delete(elf_shstrtab);
- elf_strtab_delete(elf_strtab);
+ elf_symtab_destroy(elf_symtab);
+ elf_strtab_destroy(elf_shstrtab);
+ elf_strtab_destroy(elf_strtab);
}
static /*@observer@*/ /*@null@*/ yasm_section *
-elf_objfmt_sections_switch(yasm_sectionhead *headp,
- yasm_valparamhead *valparams,
- /*@unused@*/ /*@null@*/
- yasm_valparamhead *objext_valparams,
- unsigned long lindex)
+elf_objfmt_section_switch(yasm_object *object, yasm_valparamhead *valparams,
+ /*@unused@*/ /*@null@*/
+ yasm_valparamhead *objext_valparams,
+ unsigned long line)
{
yasm_valparam *vp = yasm_vps_first(valparams);
yasm_section *retval;
align_expr = yasm_expr_get_intnum(&vp->param, NULL);
if (!align_expr) {
- yasm__error(lindex,
+ yasm__error(line,
N_("argument to `%s' is not a power of two"),
vp->val);
return NULL;
/* Alignments must be a power of two. */
if ((addralign & (addralign - 1)) != 0) {
- yasm__error(lindex,
+ yasm__error(line,
N_("argument to `%s' is not a power of two"),
vp->val);
return NULL;
align_intn = yasm_intnum_copy(align_expr);
}
} else
- yasm__warning(YASM_WARN_GENERAL, lindex,
+ yasm__warning(YASM_WARN_GENERAL, line,
N_("Unrecognized qualifier `%s'"), vp->val);
}
- retval = yasm_sections_switch_general(headp, sectname, 0, resonly, &isnew,
- lindex);
+ retval = yasm_object_get_general(object, sectname, 0, resonly, &isnew,
+ line);
if (isnew) {
elf_secthead *esd;
yasm_symrec *sym;
elf_strtab_entry *name = elf_strtab_append_str(elf_shstrtab, sectname);
- esd = elf_secthead_new(name, type, flags,
- elf_objfmt_parse_scnum++, 0, 0);
+ esd = elf_secthead_create(name, type, flags, elf_objfmt_parse_scnum++,
+ 0, 0);
if (!align_intn)
- align_intn = yasm_intnum_new_uint(align);
+ align_intn = yasm_intnum_create_uint(align);
if (align_intn)
elf_secthead_set_align(esd, align_intn);
- yasm_section_set_of_data(retval, &yasm_elf_LTX_objfmt, esd);
- sym = yasm_symrec_define_label(sectname, retval, (yasm_bytecode *)NULL,
- 1, lindex);
+ yasm_section_add_data(retval, &elf_section_data, esd);
+ sym =
+ yasm_symtab_define_label(yasm_object_get_symtab(object), sectname,
+ yasm_section_bcs_first(retval), 1, line);
elf_secthead_set_sym(esd, sym);
} else if (flags_override)
- yasm__warning(YASM_WARN_GENERAL, lindex,
+ yasm__warning(YASM_WARN_GENERAL, line,
N_("section flags ignored on section redeclaration"));
return retval;
}
-static void
-elf_objfmt_section_data_delete(/*@only@*/ void *data)
-{
- elf_secthead_delete((elf_secthead *)data);
-}
-
-static void
-elf_objfmt_section_data_print(FILE *f, int indent_level, void *data)
-{
- elf_secthead_print(f, indent_level, (elf_secthead *)data);
-}
-
static void
elf_objfmt_extglob_declare(yasm_symrec *sym, /*@unused@*/
/*@null@*/ yasm_valparamhead *objext_valparams,
- /*@unused@*/ unsigned long lindex)
+ /*@unused@*/ unsigned long line)
{
elf_objfmt_symtab_append(sym, STB_GLOBAL, SHN_UNDEF, NULL);
}
elf_objfmt_common_declare(yasm_symrec *sym, /*@only@*/ yasm_expr *size,
/*@unused@*/ /*@null@*/
yasm_valparamhead *objext_valparams,
- /*@unused@*/ unsigned long lindex)
+ /*@unused@*/ unsigned long line)
{
elf_objfmt_symtab_append(sym, STB_GLOBAL, SHN_COMMON, size);
}
-static void
-elf_objfmt_symrec_data_delete(/*@only@*/ void *data)
-{
- /* do nothing, as this stuff is in the symtab anyway... this speaks of bad
- * design/use or this stuff, i fear */
-
- /* watch for double-free here ... */
- /*elf_symtab_entry_delete((elf_symtab_entry *)data);*/
-}
-
-static void
-elf_objfmt_symrec_data_print(FILE *f, int indent_level, void *data)
-{
- elf_symtab_entry_print(f, indent_level, (elf_symtab_entry *)data);
-}
-
static int
elf_objfmt_directive(/*@unused@*/ const char *name,
/*@unused@*/ yasm_valparamhead *valparams,
/*@unused@*/ /*@null@*/
yasm_valparamhead *objext_valparams,
- /*@unused@*/ yasm_sectionhead *headp,
- /*@unused@*/ unsigned long lindex)
+ /*@unused@*/ yasm_object *object,
+ /*@unused@*/ unsigned long line)
{
return 1; /* no objfmt directives */
}
elf_objfmt_initialize,
elf_objfmt_output,
elf_objfmt_cleanup,
- elf_objfmt_sections_switch,
- elf_objfmt_section_data_delete,
- elf_objfmt_section_data_print,
+ elf_objfmt_section_switch,
elf_objfmt_extglob_declare,
elf_objfmt_extglob_declare,
elf_objfmt_common_declare,
- elf_objfmt_symrec_data_delete,
- elf_objfmt_symrec_data_print,
- elf_objfmt_directive,
- NULL /*elf_objfmt_bc_objfmt_data_delete*/,
- NULL /*elf_objfmt_bc_objfmt_data_print*/
+ elf_objfmt_directive
};
#define YASM_WRITE_64Z_L(p, i) YASM_WRITE_64C_L(p, 0, i)
+static void elf_section_data_destroy(void *data);
+static void elf_secthead_print(void *data, FILE *f, int indent_level);
+
+const yasm_assoc_data_callback elf_section_data = {
+ elf_section_data_destroy,
+ elf_secthead_print
+};
+
+static void elf_symrec_data_destroy(/*@only@*/ void *d);
+static void elf_symtab_entry_print(void *data, FILE *f, int indent_level);
+
+const yasm_assoc_data_callback elf_symrec_data = {
+ elf_symrec_data_destroy,
+ elf_symtab_entry_print
+};
+
static /*@dependent@*/ yasm_arch *cur_arch;
static enum {
M_X86_32 = 1,
} cur_elf = 0;
int
-elf_set_arch(yasm_arch *arch, const char *machine)
+elf_set_arch(yasm_arch *arch)
{
+ const char *machine = arch->module->get_machine(arch);
cur_arch = arch;
/* TODO: support more than x86:x86, x86:amd64 */
- if (yasm__strcasecmp(cur_arch->keyword, "x86") == 0) {
+ if (yasm__strcasecmp(cur_arch->module->keyword, "x86") == 0) {
if (yasm__strcasecmp(machine, "x86") == 0) {
cur_machine = M_X86_32;
cur_elf = ELF32;
/* reloc functions */
/* takes ownership of addr */
elf_reloc_entry *
-elf_reloc_entry_new(yasm_symrec *sym,
- yasm_intnum *addr,
- int rel,
- size_t valsize)
+elf_reloc_entry_create(yasm_symrec *sym,
+ yasm_intnum *addr,
+ int rel,
+ size_t valsize)
{
elf_reloc_entry *entry;
switch (cur_machine) {
case M_X86_32:
if (valsize != 32) {
if (addr)
- yasm_intnum_delete(addr);
+ yasm_intnum_destroy(addr);
return NULL;
}
break;
if (valsize != 8 && valsize != 16 && valsize != 32 && valsize != 64)
{
if (addr)
- yasm_intnum_delete(addr);
+ yasm_intnum_destroy(addr);
return NULL;
}
break;
}
void
-elf_reloc_entry_delete(elf_reloc_entry *entry)
+elf_reloc_entry_destroy(elf_reloc_entry *entry)
{
if (entry->addr)
- yasm_intnum_delete(entry->addr);
+ yasm_intnum_destroy(entry->addr);
yasm_xfree(entry);
}
elf_reloc_head *
-elf_relocs_new()
+elf_relocs_create()
{
elf_reloc_head *head = yasm_xmalloc(sizeof(elf_reloc_head));
STAILQ_INIT(head);
}
void
-elf_reloc_delete(elf_reloc_head *relocs)
+elf_reloc_destroy(elf_reloc_head *relocs)
{
if (relocs == NULL)
yasm_internal_error("relocs is null");
e1 = STAILQ_FIRST(relocs);
while (e1 != NULL) {
e2 = STAILQ_NEXT(e1, qlink);
- elf_reloc_entry_delete(e1);
+ elf_reloc_entry_destroy(e1);
e1 = e2;
}
}
/* strtab functions */
elf_strtab_entry *
-elf_strtab_entry_new(const char *str)
+elf_strtab_entry_create(const char *str)
{
elf_strtab_entry *entry = yasm_xmalloc(sizeof(elf_strtab_entry));
entry->str = yasm__xstrdup(str);
}
elf_strtab_head *
-elf_strtab_new()
+elf_strtab_create()
{
elf_strtab_head *strtab = yasm_xmalloc(sizeof(elf_strtab_head));
elf_strtab_entry *entry = yasm_xmalloc(sizeof(elf_strtab_entry));
last = STAILQ_LAST(strtab, elf_strtab_entry, qlink);
- entry = elf_strtab_entry_new(str);
+ entry = elf_strtab_entry_create(str);
entry->index = last->index + strlen(last->str) + 1;
STAILQ_INSERT_TAIL(strtab, entry, qlink);
}
void
-elf_strtab_delete(elf_strtab_head *strtab)
+elf_strtab_destroy(elf_strtab_head *strtab)
{
elf_strtab_entry *s1, *s2;
/* symtab functions */
elf_symtab_entry *
-elf_symtab_entry_new(elf_strtab_entry *name,
- yasm_symrec *sym)
+elf_symtab_entry_create(elf_strtab_entry *name,
+ yasm_symrec *sym)
{
elf_symtab_entry *entry = yasm_xmalloc(sizeof(elf_symtab_entry));
entry->sym = sym;
return entry;
}
-void
-elf_symtab_entry_delete(elf_symtab_entry *entry)
+static void
+elf_symtab_entry_destroy(elf_symtab_entry *entry)
{
if (entry == NULL)
yasm_internal_error("symtab entry is null");
if (entry->xsize)
- yasm_expr_delete(entry->xsize);
+ yasm_expr_destroy(entry->xsize);
yasm_xfree(entry);
}
-void
-elf_symtab_entry_print(FILE *f, int indent_level, elf_symtab_entry *entry)
+static void
+elf_symrec_data_destroy(void *data)
{
+ /* do nothing, as this stuff is in the symtab anyway... this speaks of bad
+ * design/use or this stuff, i fear */
+
+ /* watch for double-free here ... */
+ /*elf_symtab_entry_destroy((elf_symtab_entry *)data);*/
+}
+
+static void
+elf_symtab_entry_print(void *data, FILE *f, int indent_level)
+{
+ elf_symtab_entry *entry = data;
if (entry == NULL)
yasm_internal_error("symtab entry is null");
}
fprintf(f, "%*ssize=", indent_level, "");
if (entry->xsize)
- yasm_expr_print(f, entry->xsize);
+ yasm_expr_print(entry->xsize, f);
else
fprintf(f, "%ld", entry->size);
fprintf(f, "\n");
}
elf_symtab_head *
-elf_symtab_new()
+elf_symtab_create()
{
elf_symtab_head *symtab = yasm_xmalloc(sizeof(elf_symtab_head));
elf_symtab_entry *entry = yasm_xmalloc(sizeof(elf_symtab_entry));
elf_strtab_entry *name = strtab
? elf_strtab_append_str(strtab, yasm_symrec_get_name(sym))
: NULL;
- elf_symtab_entry *entry = elf_symtab_entry_new(name, sym);
+ elf_symtab_entry *entry = elf_symtab_entry_create(name, sym);
elf_symtab_entry *after = STAILQ_FIRST(symtab);
elf_symtab_entry *before = NULL;
}
void
-elf_symtab_delete(elf_symtab_head *symtab)
+elf_symtab_destroy(elf_symtab_head *symtab)
{
elf_symtab_entry *s1, *s2;
s1 = STAILQ_FIRST(symtab);
while (s1 != NULL) {
s2 = STAILQ_NEXT(s1, qlink);
- elf_symtab_entry_delete(s1);
+ elf_symtab_entry_destroy(s1);
s1 = s2;
}
yasm_xfree(symtab);
N_("size specifier not an integer expression"));
}
else
- size_intn = yasm_intnum_new_uint(entry->size);
+ size_intn = yasm_intnum_create_uint(entry->size);
/* get EQU value for constants */
if (entry->sym) {
value_intn = yasm_intnum_copy(equ_intn);
entry->index = SHN_ABS;
- yasm_expr_delete(equ_expr);
+ yasm_expr_destroy(equ_expr);
}
}
if (value_intn == NULL)
- value_intn = yasm_intnum_new_uint(entry->value);
+ value_intn = yasm_intnum_create_uint(entry->value);
switch (cur_elf) {
case ELF32:
YASM_WRITE_8(bufp, ELF32_ST_INFO(entry->bind, entry->type));
YASM_WRITE_8(bufp, 0);
if (entry->sect) {
- elf_secthead *shead = yasm_section_get_of_data(entry->sect);
+ elf_secthead *shead =
+ yasm_section_get_data(entry->sect, &elf_section_data);
if (!shead)
yasm_internal_error(
N_("symbol references section without data"));
YASM_WRITE_8(bufp, ELF64_ST_INFO(entry->bind, entry->type));
YASM_WRITE_8(bufp, 0);
if (entry->sect) {
- elf_secthead *shead = yasm_section_get_of_data(entry->sect);
+ elf_secthead *shead =
+ yasm_section_get_data(entry->sect, &elf_section_data);
if (!shead)
yasm_internal_error(
N_("symbol references section without data"));
break;
}
- yasm_intnum_delete(size_intn);
- yasm_intnum_delete(value_intn);
+ yasm_intnum_destroy(size_intn);
+ yasm_intnum_destroy(value_intn);
prev = entry;
}
elf_secthead *
-elf_secthead_new(elf_strtab_entry *name,
- elf_section_type type,
- elf_section_flags flags,
- elf_section_index idx,
- elf_address offset,
- elf_size size)
+elf_secthead_create(elf_strtab_entry *name,
+ elf_section_type type,
+ elf_section_flags flags,
+ elf_section_index idx,
+ elf_address offset,
+ elf_size size)
{
elf_secthead *esd = yasm_xmalloc(sizeof(elf_secthead));
esd->type = type;
esd->flags = flags;
esd->offset = offset;
- esd->size = yasm_intnum_new_uint(size);
+ esd->size = yasm_intnum_create_uint(size);
esd->link = 0;
esd->info = 0;
esd->align = NULL;
switch (cur_elf) {
case ELF32:
esd->entsize = SYMTAB32_SIZE;
- esd->align = yasm_intnum_new_uint(SYMTAB32_ALIGN);
+ esd->align = yasm_intnum_create_uint(SYMTAB32_ALIGN);
break;
case ELF64:
esd->entsize = SYMTAB64_SIZE;
- esd->align = yasm_intnum_new_uint(SYMTAB64_ALIGN);
+ esd->align = yasm_intnum_create_uint(SYMTAB64_ALIGN);
break;
default:
}
void
-elf_secthead_delete(elf_secthead *shead)
+elf_secthead_destroy(elf_secthead *shead)
{
if (shead == NULL)
yasm_internal_error(N_("shead is null"));
if (shead->align)
- yasm_intnum_delete(shead->align);
+ yasm_intnum_destroy(shead->align);
if (shead->relocs)
- elf_reloc_delete(shead->relocs);
+ elf_reloc_destroy(shead->relocs);
yasm_xfree(shead);
}
-void elf_secthead_print(FILE *f, int indent_level, elf_secthead *sect)
+static void
+elf_section_data_destroy(void *data)
+{
+ elf_secthead_destroy((elf_secthead *)data);
+}
+
+static void
+elf_secthead_print(void *data, FILE *f, int indent_level)
{
+ elf_secthead *sect = data;
fprintf(f, "%*sname=%s\n", indent_level, "",
sect->name ? sect->name->str : "<undef>");
fprintf(f, "%*ssym=\n", indent_level, "");
- yasm_symrec_print(f, indent_level+1, sect->sym);
+ yasm_symrec_print(sect->sym, f, indent_level+1);
fprintf(f, "%*sindex=0x%x\n", indent_level, "", sect->index);
fprintf(f, "%*sflags=", indent_level, "");
if (sect->flags & SHF_WRITE)
if (!shead->relocs)
{
- shead->relocs = elf_relocs_new();
+ shead->relocs = elf_relocs_create();
new_sect = 1;
}
shead->nreloc++;
YASM_WRITE_64Z_L(bufp, 0);
YASM_WRITE_64Z_L(bufp, shead->rel_offset);
- nreloc = yasm_intnum_new_uint(shead->nreloc);
- relocsize = yasm_intnum_new_uint(RELOC64_SIZE);
+ nreloc = yasm_intnum_create_uint(shead->nreloc);
+ relocsize = yasm_intnum_create_uint(RELOC64_SIZE);
yasm_intnum_calc(relocsize, YASM_EXPR_MUL, nreloc, 0);
YASM_WRITE_64I_L(bufp, relocsize); /* size */
- yasm_intnum_delete(nreloc);
- yasm_intnum_delete(relocsize);
+ yasm_intnum_destroy(nreloc);
+ yasm_intnum_destroy(relocsize);
YASM_WRITE_32_L(bufp, symtab_idx); /* link: symtab index */
YASM_WRITE_32_L(bufp, shead->index); /* info: relocated's index */
unsigned char r_type=0, r_sym;
elf_symtab_entry *esym;
- esym = yasm_symrec_get_of_data(reloc->sym);
+ esym = yasm_symrec_get_data(reloc->sym, &elf_symrec_data);
if (esym)
r_sym = esym->symindex;
else
elf_secthead_set_align(elf_secthead *shead, yasm_intnum *align)
{
if (shead->align != NULL)
- yasm_intnum_delete(shead->align);
+ yasm_intnum_destroy(shead->align);
return shead->align = align;
}
#endif /* defined(YASM_OBJFMT_ELF_INTERNAL) */
+extern const yasm_assoc_data_callback elf_section_data;
+extern const yasm_assoc_data_callback elf_symrec_data;
-int elf_set_arch(struct yasm_arch *arch, const char *machine);
+int elf_set_arch(struct yasm_arch *arch);
/* reloc functions */
-elf_reloc_entry *elf_reloc_entry_new(yasm_symrec *sym,
- yasm_intnum *addr,
- int rel,
- size_t valsize);
-void elf_reloc_entry_delete(elf_reloc_entry *entry);
-elf_reloc_head *elf_relocs_new(void);
-void elf_reloc_delete(elf_reloc_head *head);
+elf_reloc_entry *elf_reloc_entry_create(yasm_symrec *sym,
+ yasm_intnum *addr,
+ int rel,
+ size_t valsize);
+void elf_reloc_entry_destroy(elf_reloc_entry *entry);
+elf_reloc_head *elf_relocs_create(void);
+void elf_reloc_destroy(elf_reloc_head *head);
/* strtab functions */
-elf_strtab_entry *elf_strtab_entry_new(const char *str);
-elf_strtab_head *elf_strtab_new(void);
+elf_strtab_entry *elf_strtab_entry_create(const char *str);
+elf_strtab_head *elf_strtab_create(void);
elf_strtab_entry *elf_strtab_append_str(elf_strtab_head *head, const char *str);
-void elf_strtab_delete(elf_strtab_head *head);
+void elf_strtab_destroy(elf_strtab_head *head);
unsigned long elf_strtab_output_to_file(FILE *f, elf_strtab_head *head);
/* symtab functions */
-elf_symtab_entry *elf_symtab_entry_new(elf_strtab_entry *name,
- struct yasm_symrec *sym);
-void elf_symtab_entry_delete(elf_symtab_entry *entry);
-void elf_symtab_entry_print(FILE *f, int indent_level, elf_symtab_entry *entry);
-elf_symtab_head *elf_symtab_new(void);
+elf_symtab_entry *elf_symtab_entry_create(elf_strtab_entry *name,
+ struct yasm_symrec *sym);
+elf_symtab_head *elf_symtab_create(void);
elf_symtab_entry *elf_symtab_append_entry(elf_symtab_head *symtab,
elf_symtab_entry *entry);
elf_symtab_entry *elf_symtab_insert_local_sym(elf_symtab_head *symtab,
elf_strtab_head *strtab,
struct yasm_symrec *sym);
-void elf_symtab_delete(elf_symtab_head *head);
+void elf_symtab_destroy(elf_symtab_head *head);
unsigned long elf_symtab_assign_indices(elf_symtab_head *symtab);
unsigned long elf_symtab_write_to_file(FILE *f, elf_symtab_head *symtab);
void elf_symtab_set_nonzero(elf_symtab_entry *entry,
/* section header functions */
-elf_secthead *elf_secthead_new(elf_strtab_entry *name,
- elf_section_type type,
- elf_section_flags flags,
- elf_section_index idx,
- elf_address offset,
- elf_size size);
-void elf_secthead_delete(elf_secthead *esh);
+elf_secthead *elf_secthead_create(elf_strtab_entry *name,
+ elf_section_type type,
+ elf_section_flags flags,
+ elf_section_index idx,
+ elf_address offset,
+ elf_size size);
+void elf_secthead_destroy(elf_secthead *esd);
unsigned long elf_secthead_write_to_file(FILE *f, elf_secthead *esd,
elf_section_index sindex);
-void elf_secthead_print(FILE *f, int indent_level, elf_secthead *esh);
int elf_secthead_append_reloc(elf_secthead *shead, elf_reloc_entry *reloc);
elf_section_type elf_secthead_get_type(elf_secthead *shead);
int elf_secthead_is_empty(elf_secthead *shead);
/*@unused@*/ /*@null@*/ void *d);
static /*@null@*/ yasm_intnum *
-basic_optimize_calc_bc_dist_1(yasm_section *sect,
- /*@null@*/ yasm_bytecode *precbc1,
- /*@null@*/ yasm_bytecode *precbc2)
+basic_optimize_calc_bc_dist_1(yasm_bytecode *precbc1, yasm_bytecode *precbc2)
{
unsigned int dist;
yasm_intnum *intn;
- if (yasm_section_get_opt_flags(sect) == SECTFLAG_NONE) {
+ if (precbc1->section != precbc2->section)
+ yasm_internal_error(N_("Trying to calc_bc_dist between sections"));
+
+ if (yasm_section_get_opt_flags(precbc1->section) == SECTFLAG_NONE) {
/* Section not started. Optimize it (recursively). */
- basic_optimize_section_1(sect, NULL);
+ basic_optimize_section_1(precbc1->section, NULL);
}
/* If a section is done, the following will always succeed. If it's in-
* progress, this will fail if the bytecode comes AFTER the current one.
*/
- if (precbc2) {
+ if (precbc2 != yasm_section_bcs_first(precbc2->section)) {
if (precbc2->opt_flags == BCFLAG_DONE) {
dist = precbc2->offset + precbc2->len;
- if (precbc1) {
+ if (precbc1 != yasm_section_bcs_first(precbc1->section)) {
if (precbc1->opt_flags == BCFLAG_DONE) {
if (dist < precbc1->offset + precbc1->len) {
- intn = yasm_intnum_new_uint(precbc1->offset +
- precbc1->len - dist);
+ intn = yasm_intnum_create_uint(precbc1->offset +
+ precbc1->len - dist);
yasm_intnum_calc(intn, YASM_EXPR_NEG, NULL,
precbc1->line);
return intn;
return NULL;
}
}
- return yasm_intnum_new_uint(dist);
+ return yasm_intnum_create_uint(dist);
} else {
return NULL;
}
} else {
- if (precbc1) {
+ if (precbc1 != yasm_section_bcs_first(precbc1->section)) {
if (precbc1->opt_flags == BCFLAG_DONE) {
- intn = yasm_intnum_new_uint(precbc1->offset + precbc1->len);
+ intn = yasm_intnum_create_uint(precbc1->offset + precbc1->len);
yasm_intnum_calc(intn, YASM_EXPR_NEG, NULL, precbc1->line);
return intn;
} else {
return NULL;
}
} else {
- return yasm_intnum_new_uint(0);
+ return yasm_intnum_create_uint(0);
}
}
}
typedef struct basic_optimize_data {
/*@observer@*/ yasm_bytecode *precbc;
- /*@observer@*/ const yasm_section *sect;
int saw_unknown;
} basic_optimize_data;
bc->opt_flags = BCFLAG_INPROGRESS;
- if (!data->precbc)
- bc->offset = 0;
- else
- bc->offset = data->precbc->offset + data->precbc->len;
+ bc->offset = data->precbc->offset + data->precbc->len;
data->precbc = bc;
/* We're doing just a single pass, so essentially ignore whether the size
* is minimum or not, and just check for indeterminate length (indicative
* of circular reference).
*/
- bcr_retval = yasm_bc_resolve(bc, 0, data->sect,
- basic_optimize_calc_bc_dist_1);
+ bcr_retval = yasm_bc_resolve(bc, 0, basic_optimize_calc_bc_dist_1);
if (bcr_retval & YASM_BC_RESOLVE_UNKNOWN_LEN) {
if (!(bcr_retval & YASM_BC_RESOLVE_ERROR))
yasm__error(bc->line, N_("circular reference detected."));
unsigned long flags;
int retval;
- data.precbc = NULL;
- data.sect = sect;
+ data.precbc = yasm_section_bcs_first(sect);
data.saw_unknown = 0;
/* Don't even bother if we're in-progress or done. */
yasm_section_set_opt_flags(sect, SECTFLAG_INPROGRESS);
- retval = yasm_bcs_traverse(yasm_section_get_bytecodes(sect), &data,
- basic_optimize_bytecode_1);
+ retval = yasm_section_bcs_traverse(sect, &data, basic_optimize_bytecode_1);
if (retval != 0)
return retval;
if (bc->opt_flags != BCFLAG_DONE)
yasm_internal_error(N_("Optimizer pass 1 missed a bytecode!"));
- if (!data->precbc)
- bc->offset = 0;
- else
- bc->offset = data->precbc->offset + data->precbc->len;
+ bc->offset = data->precbc->offset + data->precbc->len;
data->precbc = bc;
- if (yasm_bc_resolve(bc, 1, data->sect, yasm_common_calc_bc_dist) < 0)
+ if (yasm_bc_resolve(bc, 1, yasm_common_calc_bc_dist) < 0)
return -1;
return 0;
}
{
basic_optimize_data data;
- data.precbc = NULL;
- data.sect = sect;
+ data.precbc = yasm_section_bcs_first(sect);
if (yasm_section_get_opt_flags(sect) != SECTFLAG_DONE)
yasm_internal_error(N_("Optimizer pass 1 missed a section!"));
- return yasm_bcs_traverse(yasm_section_get_bytecodes(sect), &data,
- basic_optimize_bytecode_2);
+ return yasm_section_bcs_traverse(sect, &data, basic_optimize_bytecode_2);
}
static void
-basic_optimize(yasm_sectionhead *sections)
+basic_optimize(yasm_object *object)
{
int saw_unknown = 0;
* - not strictly top->bottom scanning; we scan through a section and
* hop to other sections as necessary.
*/
- if (yasm_sections_traverse(sections, &saw_unknown,
- basic_optimize_section_1) < 0 ||
+ if (yasm_object_sections_traverse(object, &saw_unknown,
+ basic_optimize_section_1) < 0 ||
saw_unknown != 0)
return;
/* Check completion of all sections and save bytecode changes */
- yasm_sections_traverse(sections, NULL, basic_optimize_section_2);
+ yasm_object_sections_traverse(object, NULL, basic_optimize_section_2);
}
/* Define optimizer structure -- see optimizer.h for details */
#include "modules/parsers/nasm/nasm-parser.h"
#include "modules/parsers/nasm/nasm-defs.h"
-
-static void nasm_parser_error(const char *);
static void nasm_parser_directive
- (const char *name, yasm_valparamhead *valparams,
+ (yasm_parser_nasm *parser_nasm, const char *name,
+ yasm_valparamhead *valparams,
/*@null@*/ yasm_valparamhead *objext_valparams);
static int fix_directive_symrec(/*@null@*/ yasm_expr__item *ei,
/*@null@*/ void *d);
-static /*@null@*/ yasm_bytecode *nasm_parser_prev_bc = (yasm_bytecode *)NULL;
-static yasm_bytecode *nasm_parser_temp_bc;
-
-/* additional data declarations (dynamically generated) */
-/* @DATADECLS@ */
+#define nasm_parser_error(s) yasm__parser_error(cur_line, s)
+#define YYPARSE_PARAM parser_nasm_arg
+#define parser_nasm ((yasm_parser_nasm *)parser_nasm_arg)
+#define nasm_parser_debug (parser_nasm->debug)
/*@-usedef -nullassign -memtrans -usereleased -compdef -mustfree@*/
%}
%%
input: /* empty */
| input line {
- nasm_parser_temp_bc =
- yasm_bcs_append(yasm_section_get_bytecodes(nasm_parser_cur_section),
- $2);
- if (nasm_parser_temp_bc)
- nasm_parser_prev_bc = nasm_parser_temp_bc;
- nasm_parser_linemgr->goto_next();
+ parser_nasm->temp_bc =
+ yasm_section_bcs_append(parser_nasm->cur_section, $2);
+ if (parser_nasm->temp_bc)
+ parser_nasm->prev_bc = parser_nasm->temp_bc;
+ yasm_linemap_goto_next(parser_nasm->linemap);
}
;
/* %line indicates the line number of the *next* line, so subtract out
* the increment when setting the line number.
*/
- nasm_parser_linemgr->set($5, yasm_intnum_get_uint($2)
- - yasm_intnum_get_uint($4),
- yasm_intnum_get_uint($4));
- yasm_intnum_delete($2);
- yasm_intnum_delete($4);
+ yasm_linemap_set(parser_nasm->linemap, $5,
+ yasm_intnum_get_uint($2) - yasm_intnum_get_uint($4),
+ yasm_intnum_get_uint($4));
+ yasm_intnum_destroy($2);
+ yasm_intnum_destroy($4);
yasm_xfree($5);
$$ = (yasm_bytecode *)NULL;
}
- | '[' { nasm_parser_set_directive_state(); } directive ']' '\n' {
+ | '[' { parser_nasm->state = DIRECTIVE; } directive ']' '\n' {
$$ = (yasm_bytecode *)NULL;
}
| error '\n' {
- yasm__error(cur_lindex,
+ yasm__error(cur_line,
N_("label or instruction expected at start of line"));
$$ = (yasm_bytecode *)NULL;
yyerrok;
| label exp { $$ = $2; }
| label TIMES expr exp { $$ = $4; yasm_bc_set_multiple($$, $3); }
| label_id_equ EQU expr {
- yasm_symrec_define_equ($1, $3, cur_lindex);
+ yasm_symtab_define_equ(p_symtab, $1, $3, cur_line);
yasm_xfree($1);
$$ = (yasm_bytecode *)NULL;
}
exp: instr
| DECLARE_DATA datavals {
- $$ = yasm_bc_new_data(&$2, $1, cur_lindex);
+ $$ = yasm_bc_create_data(&$2, $1, cur_line);
}
| RESERVE_SPACE expr {
- $$ = yasm_bc_new_reserve($2, $1, cur_lindex);
+ $$ = yasm_bc_create_reserve($2, $1, cur_line);
}
| INCBIN STRING {
- $$ = yasm_bc_new_incbin($2, NULL, NULL, cur_lindex);
+ $$ = yasm_bc_create_incbin($2, NULL, NULL, cur_line);
}
| INCBIN STRING ',' expr {
- $$ = yasm_bc_new_incbin($2, $4, NULL, cur_lindex);
+ $$ = yasm_bc_create_incbin($2, $4, NULL, cur_line);
}
| INCBIN STRING ',' expr ',' expr {
- $$ = yasm_bc_new_incbin($2, $4, $6, cur_lindex);
+ $$ = yasm_bc_create_incbin($2, $4, $6, cur_line);
}
;
instr: INSN {
- $$ = nasm_parser_arch->parse_insn($1, 0, NULL, nasm_parser_cur_section,
- nasm_parser_prev_bc, cur_lindex);
+ $$ = p_arch->module->parse_insn(p_arch, $1, 0, NULL,
+ parser_nasm->prev_bc, cur_line);
}
| INSN operands {
- $$ = nasm_parser_arch->parse_insn($1, $2.num_operands, &$2.operands,
- nasm_parser_cur_section,
- nasm_parser_prev_bc, cur_lindex);
+ $$ = p_arch->module->parse_insn(p_arch, $1, $2.num_operands,
+ &$2.operands, parser_nasm->prev_bc, cur_line);
yasm_ops_delete(&$2.operands, 0);
}
| INSN error {
- yasm__error(cur_lindex, N_("expression syntax error"));
+ yasm__error(cur_line, N_("expression syntax error"));
$$ = NULL;
}
| PREFIX instr {
$$ = $2;
- nasm_parser_arch->parse_prefix($$, $1, cur_lindex);
+ p_arch->module->parse_prefix(p_arch, $$, $1, cur_line);
}
| SEGREG instr {
$$ = $2;
- nasm_parser_arch->parse_seg_prefix($$, $1[0], cur_lindex);
+ p_arch->module->parse_seg_prefix(p_arch, $$, $1[0], cur_line);
}
;
| datavals ',' dataval { yasm_dvs_append(&$1, $3); $$ = $1; }
;
-dataval: dvexpr { $$ = yasm_dv_new_expr($1); }
- | STRING { $$ = yasm_dv_new_string($1); }
+dataval: dvexpr { $$ = yasm_dv_create_expr($1); }
+ | STRING { $$ = yasm_dv_create_string($1); }
| error {
- yasm__error(cur_lindex, N_("expression syntax error"));
+ yasm__error(cur_line, N_("expression syntax error"));
$$ = (yasm_dataval *)NULL;
}
;
label: label_id {
- yasm_symrec_define_label($1, nasm_parser_cur_section,
- nasm_parser_prev_bc, 1, cur_lindex);
+ yasm_symtab_define_label(p_symtab, $1, parser_nasm->prev_bc, 1,
+ cur_line);
yasm_xfree($1);
}
| label_id ':' {
- yasm_symrec_define_label($1, nasm_parser_cur_section,
- nasm_parser_prev_bc, 1, cur_lindex);
+ yasm_symtab_define_label(p_symtab, $1, parser_nasm->prev_bc, 1,
+ cur_line);
yasm_xfree($1);
}
;
label_id: ID {
$$ = $1;
- if (nasm_parser_locallabel_base)
- yasm_xfree(nasm_parser_locallabel_base);
- nasm_parser_locallabel_base_len = strlen($1);
- nasm_parser_locallabel_base =
- yasm_xmalloc(nasm_parser_locallabel_base_len+1);
- strcpy(nasm_parser_locallabel_base, $1);
+ if (parser_nasm->locallabel_base)
+ yasm_xfree(parser_nasm->locallabel_base);
+ parser_nasm->locallabel_base_len = strlen($1);
+ parser_nasm->locallabel_base =
+ yasm_xmalloc(parser_nasm->locallabel_base_len+1);
+ strcpy(parser_nasm->locallabel_base, $1);
}
| SPECIAL_ID
| LOCAL_ID
yasm_xfree($1);
}
| DIRECTIVE_NAME error {
- yasm__error(cur_lindex, N_("invalid arguments to [%s]"), $1);
+ yasm__error(cur_line, N_("invalid arguments to [%s]"), $1);
yasm_xfree($1);
}
;
/* $<str_val>0 is the DIRECTIVE_NAME */
/* After : is (optional) object-format specific extension */
directive_val: directive_valparams {
- nasm_parser_directive($<str_val>0, &$1, NULL);
+ nasm_parser_directive(parser_nasm, $<str_val>0, &$1, NULL);
}
| directive_valparams ':' directive_valparams {
- nasm_parser_directive($<str_val>0, &$1, &$3);
+ nasm_parser_directive(parser_nasm, $<str_val>0, &$1, &$3);
}
;
*/
const /*@null@*/ yasm_symrec *vp_symrec;
if ((vp_symrec = yasm_expr_get_symrec(&$1, 0))) {
- $$ = yasm_vp_new(yasm__xstrdup(yasm_symrec_get_name(vp_symrec)),
- NULL);
- yasm_expr_delete($1);
+ $$ = yasm_vp_create(yasm__xstrdup(yasm_symrec_get_name(vp_symrec)),
+ NULL);
+ yasm_expr_destroy($1);
} else {
- yasm_expr__traverse_leaves_in($1, NULL, fix_directive_symrec);
- $$ = yasm_vp_new(NULL, $1);
+ yasm_expr__traverse_leaves_in($1, parser_nasm,
+ fix_directive_symrec);
+ $$ = yasm_vp_create(NULL, $1);
}
}
- | STRING { $$ = yasm_vp_new($1, NULL); }
+ | STRING { $$ = yasm_vp_create($1, NULL); }
| ID '=' direxpr {
- yasm_expr__traverse_leaves_in($3, NULL, fix_directive_symrec);
- $$ = yasm_vp_new($1, $3);
+ yasm_expr__traverse_leaves_in($3, parser_nasm, fix_directive_symrec);
+ $$ = yasm_vp_create($1, $3);
}
;
/* memory addresses */
memaddr: expr {
- $$ = nasm_parser_arch->ea_new_expr($1);
+ $$ = p_arch->module->ea_create(p_arch, $1);
}
| SEGREG ':' memaddr {
$$ = $3;
- nasm_parser_arch->parse_seg_override($$, $1[0], cur_lindex);
+ p_arch->module->parse_seg_override(p_arch, $$, $1[0], cur_line);
}
| BYTE memaddr {
$$ = $2;
}
| HWORD memaddr {
$$ = $2;
- yasm_ea_set_len($$, nasm_parser_arch->wordsize/2);
+ yasm_ea_set_len($$, p_arch->module->wordsize/2);
}
| WORD memaddr {
$$ = $2;
- yasm_ea_set_len($$, nasm_parser_arch->wordsize);
+ yasm_ea_set_len($$, p_arch->module->wordsize);
}
| DWORD memaddr {
$$ = $2;
- yasm_ea_set_len($$, nasm_parser_arch->wordsize*2);
+ yasm_ea_set_len($$, p_arch->module->wordsize*2);
}
| QWORD memaddr {
$$ = $2;
- yasm_ea_set_len($$, nasm_parser_arch->wordsize*4);
+ yasm_ea_set_len($$, p_arch->module->wordsize*4);
}
| NOSPLIT memaddr { $$ = $2; yasm_ea_set_nosplit($$, 1); }
;
}
;
-operand: '[' memaddr ']' { $$ = yasm_operand_new_mem($2); }
- | expr { $$ = yasm_operand_new_imm($1); }
- | SEGREG { $$ = yasm_operand_new_segreg($1[0]); }
+operand: '[' memaddr ']' { $$ = yasm_operand_create_mem($2); }
+ | expr { $$ = yasm_operand_create_imm($1); }
+ | SEGREG { $$ = yasm_operand_create_segreg($1[0]); }
| BYTE operand {
$$ = $2;
if ($$->type == YASM_INSN__OPERAND_REG &&
- nasm_parser_arch->get_reg_size($$->data.reg) != 1)
- yasm__error(cur_lindex, N_("cannot override register size"));
+ p_arch->module->get_reg_size(p_arch, $$->data.reg) != 1)
+ yasm__error(cur_line, N_("cannot override register size"));
else
$$->size = 1;
}
| HWORD operand {
$$ = $2;
if ($$->type == YASM_INSN__OPERAND_REG &&
- nasm_parser_arch->get_reg_size($$->data.reg) !=
- nasm_parser_arch->wordsize/2)
- yasm__error(cur_lindex, N_("cannot override register size"));
+ p_arch->module->get_reg_size(p_arch, $$->data.reg) !=
+ p_arch->module->wordsize/2)
+ yasm__error(cur_line, N_("cannot override register size"));
else
- $$->size = nasm_parser_arch->wordsize/2;
+ $$->size = p_arch->module->wordsize/2;
}
| WORD operand {
$$ = $2;
if ($$->type == YASM_INSN__OPERAND_REG &&
- nasm_parser_arch->get_reg_size($$->data.reg) !=
- nasm_parser_arch->wordsize)
- yasm__error(cur_lindex, N_("cannot override register size"));
+ p_arch->module->get_reg_size(p_arch, $$->data.reg) !=
+ p_arch->module->wordsize)
+ yasm__error(cur_line, N_("cannot override register size"));
else
- $$->size = nasm_parser_arch->wordsize;
+ $$->size = p_arch->module->wordsize;
}
| DWORD operand {
$$ = $2;
if ($$->type == YASM_INSN__OPERAND_REG &&
- nasm_parser_arch->get_reg_size($$->data.reg) !=
- nasm_parser_arch->wordsize*2)
- yasm__error(cur_lindex, N_("cannot override register size"));
+ p_arch->module->get_reg_size(p_arch, $$->data.reg) !=
+ p_arch->module->wordsize*2)
+ yasm__error(cur_line, N_("cannot override register size"));
else
- $$->size = nasm_parser_arch->wordsize*2;
+ $$->size = p_arch->module->wordsize*2;
}
| QWORD operand {
$$ = $2;
if ($$->type == YASM_INSN__OPERAND_REG &&
- nasm_parser_arch->get_reg_size($$->data.reg) !=
- nasm_parser_arch->wordsize*4)
- yasm__error(cur_lindex, N_("cannot override register size"));
+ p_arch->module->get_reg_size(p_arch, $$->data.reg) !=
+ p_arch->module->wordsize*4)
+ yasm__error(cur_line, N_("cannot override register size"));
else
- $$->size = nasm_parser_arch->wordsize*4;
+ $$->size = p_arch->module->wordsize*4;
}
| TWORD operand {
$$ = $2;
if ($$->type == YASM_INSN__OPERAND_REG &&
- nasm_parser_arch->get_reg_size($$->data.reg) !=
- nasm_parser_arch->wordsize*5)
- yasm__error(cur_lindex, N_("cannot override register size"));
+ p_arch->module->get_reg_size(p_arch, $$->data.reg) !=
+ p_arch->module->wordsize*5)
+ yasm__error(cur_line, N_("cannot override register size"));
else
- $$->size = nasm_parser_arch->wordsize*5;
+ $$->size = p_arch->module->wordsize*5;
}
| DQWORD operand {
$$ = $2;
if ($$->type == YASM_INSN__OPERAND_REG &&
- nasm_parser_arch->get_reg_size($$->data.reg) !=
- nasm_parser_arch->wordsize*8)
- yasm__error(cur_lindex, N_("cannot override register size"));
+ p_arch->module->get_reg_size(p_arch, $$->data.reg) !=
+ p_arch->module->wordsize*8)
+ yasm__error(cur_line, N_("cannot override register size"));
else
- $$->size = nasm_parser_arch->wordsize*8;
+ $$->size = p_arch->module->wordsize*8;
}
| TARGETMOD operand { $$ = $2; $$->targetmod = $1[0]; }
;
direxpr: INTNUM { $$ = p_expr_new_ident(yasm_expr_int($1)); }
| ID {
$$ = p_expr_new_ident(yasm_expr_sym(
- yasm_symrec_define_label($1, NULL, NULL, 0, cur_lindex)));
+ yasm_symtab_define_label(p_symtab, $1,
+ yasm_section_bcs_first(parser_nasm->cur_section), 0,
+ cur_line)));
yasm_xfree($1);
}
| direxpr '|' direxpr { $$ = p_expr_new_tree($1, YASM_EXPR_OR, $3); }
| REG { $$ = p_expr_new_ident(yasm_expr_reg($1[0])); }
| STRING {
$$ = p_expr_new_ident(yasm_expr_int(
- yasm_intnum_new_charconst_nasm($1, cur_lindex)));
+ yasm_intnum_create_charconst_nasm($1, cur_line)));
yasm_xfree($1);
}
| explabel { $$ = p_expr_new_ident(yasm_expr_sym($1)); }
;
explabel: ID {
- $$ = yasm_symrec_use($1, cur_lindex);
+ $$ = yasm_symtab_use(p_symtab, $1, cur_line);
yasm_xfree($1);
}
| SPECIAL_ID {
- $$ = yasm_symrec_use($1, cur_lindex);
+ $$ = yasm_symtab_use(p_symtab, $1, cur_line);
yasm_xfree($1);
}
| LOCAL_ID {
- $$ = yasm_symrec_use($1, cur_lindex);
+ $$ = yasm_symtab_use(p_symtab, $1, cur_line);
yasm_xfree($1);
}
| '$' {
/* "$" references the current assembly position */
- $$ = yasm_symrec_define_label("$", nasm_parser_cur_section,
- nasm_parser_prev_bc, 0, cur_lindex);
+ $$ = yasm_symtab_define_label(p_symtab, "$", parser_nasm->prev_bc, 0,
+ cur_line);
}
| START_SECTION_ID {
/* "$$" references the start of the current section */
- $$ = yasm_symrec_define_label("$$", nasm_parser_cur_section, NULL, 0,
- cur_lindex);
+ $$ = yasm_symtab_define_label(p_symtab, "$$",
+ yasm_section_bcs_first(parser_nasm->cur_section), 0, cur_line);
}
;
%%
/*@=usedef =nullassign =memtrans =usereleased =compdef =mustfree@*/
+#undef parser_nasm
+
static int
-fix_directive_symrec(yasm_expr__item *ei, /*@unused@*/ void *d)
+fix_directive_symrec(yasm_expr__item *ei, void *d)
{
+ yasm_parser_nasm *parser_nasm = (yasm_parser_nasm *)d;
if (!ei || ei->type != YASM_EXPR_SYM)
return 0;
/* FIXME: Delete current symrec */
ei->data.sym =
- yasm_symrec_use(yasm_symrec_get_name(ei->data.sym), cur_lindex);
+ yasm_symtab_use(p_symtab, yasm_symrec_get_name(ei->data.sym),
+ cur_line);
return 0;
}
static void
-nasm_parser_directive(const char *name, yasm_valparamhead *valparams,
+nasm_parser_directive(yasm_parser_nasm *parser_nasm, const char *name,
+ yasm_valparamhead *valparams,
yasm_valparamhead *objext_valparams)
{
yasm_valparam *vp, *vp2;
yasm_symrec *sym;
- unsigned long lindex = cur_lindex;
+ unsigned long line = cur_line;
/* Handle (mostly) output-format independent directives here */
if (yasm__strcasecmp(name, "extern") == 0) {
vp = yasm_vps_first(valparams);
if (vp->val) {
- sym = yasm_symrec_declare(vp->val, YASM_SYM_EXTERN, lindex);
- if (nasm_parser_objfmt->extern_declare)
- nasm_parser_objfmt->extern_declare(sym, objext_valparams,
- lindex);
+ sym = yasm_symtab_declare(p_symtab, vp->val, YASM_SYM_EXTERN,
+ line);
+ if (parser_nasm->objfmt->extern_declare)
+ parser_nasm->objfmt->extern_declare(sym, objext_valparams,
+ line);
} else
- yasm__error(lindex, N_("invalid argument to [%s]"), "EXTERN");
+ yasm__error(line, N_("invalid argument to [%s]"), "EXTERN");
} else if (yasm__strcasecmp(name, "global") == 0) {
vp = yasm_vps_first(valparams);
if (vp->val) {
- sym = yasm_symrec_declare(vp->val, YASM_SYM_GLOBAL, lindex);
- if (nasm_parser_objfmt->global_declare)
- nasm_parser_objfmt->global_declare(sym, objext_valparams,
- lindex);
+ sym = yasm_symtab_declare(p_symtab, vp->val, YASM_SYM_GLOBAL,
+ line);
+ if (parser_nasm->objfmt->global_declare)
+ parser_nasm->objfmt->global_declare(sym, objext_valparams,
+ line);
} else
- yasm__error(lindex, N_("invalid argument to [%s]"), "GLOBAL");
+ yasm__error(line, N_("invalid argument to [%s]"), "GLOBAL");
} else if (yasm__strcasecmp(name, "common") == 0) {
vp = yasm_vps_first(valparams);
if (vp->val) {
vp2 = yasm_vps_next(vp);
if (!vp2 || (!vp2->val && !vp2->param))
- yasm__error(lindex, N_("no size specified in %s declaration"),
+ yasm__error(line, N_("no size specified in %s declaration"),
"COMMON");
else {
if (vp2->val) {
- sym = yasm_symrec_declare(vp->val, YASM_SYM_COMMON,
- lindex);
- if (nasm_parser_objfmt->common_declare)
- nasm_parser_objfmt->common_declare(sym,
+ sym = yasm_symtab_declare(p_symtab, vp->val,
+ YASM_SYM_COMMON, line);
+ if (parser_nasm->objfmt->common_declare)
+ parser_nasm->objfmt->common_declare(sym,
p_expr_new_ident(yasm_expr_sym(
- yasm_symrec_use(vp2->val, lindex))),
- objext_valparams, lindex);
+ yasm_symtab_use(p_symtab, vp2->val, line))),
+ objext_valparams, line);
} else if (vp2->param) {
- sym = yasm_symrec_declare(vp->val, YASM_SYM_COMMON,
- lindex);
- if (nasm_parser_objfmt->common_declare)
- nasm_parser_objfmt->common_declare(sym, vp2->param,
- objext_valparams,
- lindex);
+ sym = yasm_symtab_declare(p_symtab, vp->val,
+ YASM_SYM_COMMON, line);
+ if (parser_nasm->objfmt->common_declare)
+ parser_nasm->objfmt->common_declare(sym, vp2->param,
+ objext_valparams,
+ line);
vp2->param = NULL;
}
}
} else
- yasm__error(lindex, N_("invalid argument to [%s]"), "COMMON");
+ yasm__error(line, N_("invalid argument to [%s]"), "COMMON");
} else if (yasm__strcasecmp(name, "section") == 0 ||
yasm__strcasecmp(name, "segment") == 0) {
yasm_section *new_section =
- nasm_parser_objfmt->sections_switch(nasm_parser_sections,
+ parser_nasm->objfmt->section_switch(parser_nasm->object,
valparams, objext_valparams,
- lindex);
+ line);
if (new_section) {
- nasm_parser_cur_section = new_section;
- nasm_parser_prev_bc =
- yasm_bcs_last(yasm_section_get_bytecodes(new_section));
+ parser_nasm->cur_section = new_section;
+ parser_nasm->prev_bc = yasm_section_bcs_last(new_section);
} else
- yasm__error(lindex, N_("invalid argument to [%s]"), "SECTION");
+ yasm__error(line, N_("invalid argument to [%s]"), "SECTION");
} else if (yasm__strcasecmp(name, "absolute") == 0) {
/* it can be just an ID or a complete expression, so handle both. */
vp = yasm_vps_first(valparams);
if (vp->val)
- nasm_parser_cur_section =
- yasm_sections_switch_absolute(nasm_parser_sections,
+ parser_nasm->cur_section =
+ yasm_object_create_absolute(parser_nasm->object,
p_expr_new_ident(yasm_expr_sym(
- yasm_symrec_use(vp->val, lindex))));
+ yasm_symtab_use(p_symtab, vp->val, line))), line);
else if (vp->param) {
- nasm_parser_cur_section =
- yasm_sections_switch_absolute(nasm_parser_sections,
- vp->param);
+ parser_nasm->cur_section =
+ yasm_object_create_absolute(parser_nasm->object, vp->param,
+ line);
vp->param = NULL;
}
- nasm_parser_prev_bc = (yasm_bytecode *)NULL;
+ parser_nasm->prev_bc = yasm_section_bcs_last(parser_nasm->cur_section);
} else if (yasm__strcasecmp(name, "cpu") == 0) {
yasm_vps_foreach(vp, valparams) {
if (vp->val)
- nasm_parser_arch->parse_cpu(vp->val, lindex);
+ p_arch->module->parse_cpu(p_arch, vp->val, line);
else if (vp->param) {
const yasm_intnum *intcpu;
intcpu = yasm_expr_get_intnum(&vp->param, NULL);
if (!intcpu)
- yasm__error(lindex, N_("invalid argument to [%s]"), "CPU");
+ yasm__error(line, N_("invalid argument to [%s]"), "CPU");
else {
char strcpu[16];
sprintf(strcpu, "%lu", yasm_intnum_get_uint(intcpu));
- nasm_parser_arch->parse_cpu(strcpu, lindex);
+ p_arch->module->parse_cpu(p_arch, strcpu, line);
}
}
}
- } else if (!nasm_parser_arch->parse_directive(name, valparams,
- objext_valparams,
- nasm_parser_sections,
- lindex)) {
+ } else if (!p_arch->module->parse_directive(p_arch, name, valparams,
+ objext_valparams, parser_nasm->object, line)) {
;
- } else if (nasm_parser_objfmt->directive(name, valparams, objext_valparams,
- nasm_parser_sections, lindex)) {
- yasm__error(lindex, N_("unrecognized directive [%s]"), name);
+ } else if (parser_nasm->objfmt->directive(name, valparams,
+ objext_valparams, parser_nasm->object, line)) {
+ yasm__error(line, N_("unrecognized directive [%s]"), name);
}
yasm_vps_delete(valparams);
if (objext_valparams)
yasm_vps_delete(objext_valparams);
}
-
-static void
-nasm_parser_error(const char *s)
-{
- yasm__parser_error(cur_lindex, s);
-}
-
#include "nasm-parser.h"
-FILE *nasm_parser_in = NULL;
-size_t (*nasm_parser_input) (char *buf, size_t max_size);
+static void
+nasm_parser_do_parse(yasm_object *object, yasm_preproc *pp, yasm_arch *a,
+ yasm_objfmt *of, FILE *f, const char *in_filename,
+ int save_input, yasm_section *def_sect)
+{
+ yasm_parser_nasm parser_nasm;
-/*@only@*/ yasm_sectionhead *nasm_parser_sections;
-/*@dependent@*/ yasm_section *nasm_parser_cur_section;
+ parser_nasm.object = object;
+ parser_nasm.linemap = yasm_object_get_linemap(parser_nasm.object);
+ parser_nasm.symtab = yasm_object_get_symtab(parser_nasm.object);
-/* last "base" label for local (.) labels */
-char *nasm_parser_locallabel_base = (char *)NULL;
-size_t nasm_parser_locallabel_base_len = 0;
+ yasm_linemap_set(parser_nasm.linemap, in_filename, 1, 1);
-/*@dependent@*/ yasm_arch *nasm_parser_arch;
-/*@dependent@*/ yasm_objfmt *nasm_parser_objfmt;
-/*@dependent@*/ yasm_linemgr *nasm_parser_linemgr;
+ pp->initialize(f, in_filename, parser_nasm.linemap);
+ parser_nasm.in = f;
+ parser_nasm.input = pp->input;
-int nasm_parser_save_input;
+ parser_nasm.locallabel_base = (char *)NULL;
+ parser_nasm.locallabel_base_len = 0;
-static /*@only@*/ yasm_sectionhead *
-nasm_parser_do_parse(yasm_preproc *pp, yasm_arch *a, yasm_objfmt *of,
- yasm_linemgr *lm, FILE *f, const char *in_filename,
- int save_input)
- /*@globals killed nasm_parser_locallabel_base @*/
-{
- pp->initialize(f, in_filename, lm);
- nasm_parser_in = f;
- nasm_parser_input = pp->input;
- nasm_parser_arch = a;
- nasm_parser_objfmt = of;
- nasm_parser_linemgr = lm;
- nasm_parser_save_input = save_input;
+ parser_nasm.arch = a;
+ parser_nasm.objfmt = of;
+
+ parser_nasm.cur_section = def_sect;
+ parser_nasm.prev_bc = yasm_section_bcs_first(def_sect);
- /* Initialize section list */
- nasm_parser_sections = yasm_sections_new(&nasm_parser_cur_section, of);
+ parser_nasm.save_input = save_input;
+
+ /* initialize scanner structure */
+ parser_nasm.s.bot = NULL;
+ parser_nasm.s.tok = NULL;
+ parser_nasm.s.ptr = NULL;
+ parser_nasm.s.cur = NULL;
+ parser_nasm.s.pos = NULL;
+ parser_nasm.s.lim = NULL;
+ parser_nasm.s.top = NULL;
+ parser_nasm.s.eof = NULL;
+ parser_nasm.s.tchar = 0;
+ parser_nasm.s.tline = 0;
+ parser_nasm.s.cline = 1;
+
+ parser_nasm.state = INITIAL;
/* yacc debugging, needs YYDEBUG set in bison.y.in to work */
/* nasm_parser_debug = 1; */
- nasm_parser_parse();
+ nasm_parser_parse(&parser_nasm);
- nasm_parser_cleanup();
+ nasm_parser_cleanup(&parser_nasm);
/* Free locallabel base if necessary */
- if (nasm_parser_locallabel_base)
- yasm_xfree(nasm_parser_locallabel_base);
-
- return nasm_parser_sections;
+ if (parser_nasm.locallabel_base)
+ yasm_xfree(parser_nasm.locallabel_base);
}
/* Define valid preprocessors to use with this parser */
};
/* Define parser structure -- see parser.h for details */
-yasm_parser yasm_nasm_LTX_parser = {
+yasm_parser_module yasm_nasm_LTX_parser = {
YASM_PARSER_VERSION,
"NASM-compatible parser",
"nasm",
-/* $IdPath: yasm/modules/parsers/nasm/nasm-parser.h,v 1.6 2003/03/13 06:54:19 peter Exp $
+/* $IdPath$
* NASM-compatible parser header file
*
* Copyright (C) 2002 Peter Johnson
#ifndef YASM_NASM_PARSER_H
#define YASM_NASM_PARSER_H
-int nasm_parser_parse(void);
-void nasm_parser_cleanup(void);
-int nasm_parser_lex(void);
-void nasm_parser_set_directive_state(void);
+#define YYCTYPE char
+typedef struct Scanner {
+ YYCTYPE *bot, *tok, *ptr, *cur, *pos, *lim, *top, *eof;
+ unsigned int tchar, tline, cline;
+} Scanner;
-extern FILE *nasm_parser_in;
-extern int nasm_parser_debug;
-extern size_t (*nasm_parser_input) (char *buf, size_t max_size);
+#define MAX_SAVED_LINE_LEN 80
-extern yasm_sectionhead *nasm_parser_sections;
-extern /*@dependent@*/ yasm_section *nasm_parser_cur_section;
+typedef struct yasm_parser_nasm {
+ FILE *in;
+ int debug;
+ size_t (*input) (char *buf, size_t max_size);
-extern char *nasm_parser_locallabel_base;
-extern size_t nasm_parser_locallabel_base_len;
+ /*@only@*/ yasm_object *object;
+ /*@dependent@*/ yasm_section *cur_section;
-extern /*@dependent@*/ yasm_arch *nasm_parser_arch;
-extern /*@dependent@*/ yasm_objfmt *nasm_parser_objfmt;
-extern /*@dependent@*/ yasm_linemgr *nasm_parser_linemgr;
+ /* last "base" label for local (.) labels */
+ /*@null@*/ char *locallabel_base;
+ size_t locallabel_base_len;
-extern int nasm_parser_save_input;
+ /*@dependent@*/ yasm_arch *arch;
+ /*@dependent@*/ yasm_objfmt *objfmt;
-#define cur_lindex (nasm_parser_linemgr->get_current())
+ /*@dependent@*/ yasm_linemap *linemap;
+ /*@dependent@*/ yasm_symtab *symtab;
-#define p_expr_new_tree(l,o,r) yasm_expr_new_tree(l,o,r,cur_lindex)
-#define p_expr_new_branch(o,r) yasm_expr_new_branch(o,r,cur_lindex)
-#define p_expr_new_ident(r) yasm_expr_new_ident(r,cur_lindex)
+ /*@null@*/ yasm_bytecode *prev_bc;
+ yasm_bytecode *temp_bc;
+
+ int save_input;
+ YYCTYPE save_line[MAX_SAVED_LINE_LEN];
+
+ Scanner s;
+ enum {
+ INITIAL,
+ DIRECTIVE,
+ DIRECTIVE2,
+ LINECHG,
+ LINECHG2
+ } state;
+} yasm_parser_nasm;
+
+/* shorter access names to commonly used parser_nasm fields */
+#define p_arch (parser_nasm->arch)
+#define p_symtab (parser_nasm->symtab)
+
+#define cur_line (yasm_linemap_get_current(parser_nasm->linemap))
+
+#define p_expr_new_tree(l,o,r) yasm_expr_create_tree(l,o,r,cur_line)
+#define p_expr_new_branch(o,r) yasm_expr_create_branch(o,r,cur_line)
+#define p_expr_new_ident(r) yasm_expr_create_ident(r,cur_line)
+
+int nasm_parser_parse(void *parser_nasm_arg);
+void nasm_parser_cleanup(yasm_parser_nasm *parser_nasm);
+int nasm_parser_lex_arg(yasm_parser_nasm *parser_nasm);
+#define nasm_parser_lex() nasm_parser_lex_arg(parser_nasm)
#endif
#define BSIZE 8192
-#define YYCTYPE char
#define YYCURSOR cursor
-#define YYLIMIT s.lim
-#define YYMARKER s.ptr
-#define YYFILL(n) {cursor = fill(cursor);}
+#define YYLIMIT (s->lim)
+#define YYMARKER (s->ptr)
+#define YYFILL(n) {cursor = fill(parser_nasm, cursor);}
-#define RETURN(i) {s.cur = cursor; return i;}
+#define RETURN(i) {s->cur = cursor; return i;}
#define SCANINIT() { \
- s.tchar = cursor - s.pos; \
- s.tline = s.cline; \
- s.tok = cursor; \
+ s->tchar = cursor - s->pos; \
+ s->tline = s->cline; \
+ s->tok = cursor; \
}
-#define TOKLEN (size_t)(cursor-s.tok)
+#define TOKLEN (size_t)(cursor-s->tok)
-typedef struct Scanner {
- YYCTYPE *bot, *tok, *ptr, *cur, *pos, *lim, *top, *eof;
- unsigned int tchar, tline, cline;
-} Scanner;
-
-#define MAX_SAVED_LINE_LEN 80
-static char cur_line[MAX_SAVED_LINE_LEN];
-
-static Scanner s = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, 0, 1 };
static YYCTYPE *
-fill(YYCTYPE *cursor)
+fill(yasm_parser_nasm *parser_nasm, YYCTYPE *cursor)
{
+ Scanner *s = &parser_nasm->s;
int first = 0;
- if(!s.eof){
- size_t cnt = s.tok - s.bot;
+ if(!s->eof){
+ size_t cnt = s->tok - s->bot;
if(cnt){
- memcpy(s.bot, s.tok, (size_t)(s.lim - s.tok));
- s.tok = s.bot;
- s.ptr -= cnt;
+ memcpy(s->bot, s->tok, (size_t)(s->lim - s->tok));
+ s->tok = s->bot;
+ s->ptr -= cnt;
cursor -= cnt;
- s.pos -= cnt;
- s.lim -= cnt;
+ s->pos -= cnt;
+ s->lim -= cnt;
}
- if (!s.bot)
+ if (!s->bot)
first = 1;
- if((s.top - s.lim) < BSIZE){
- char *buf = yasm_xmalloc((size_t)(s.lim - s.bot) + BSIZE);
- memcpy(buf, s.tok, (size_t)(s.lim - s.tok));
- s.tok = buf;
- s.ptr = &buf[s.ptr - s.bot];
- cursor = &buf[cursor - s.bot];
- s.pos = &buf[s.pos - s.bot];
- s.lim = &buf[s.lim - s.bot];
- s.top = &s.lim[BSIZE];
- if (s.bot)
- yasm_xfree(s.bot);
- s.bot = buf;
+ if((s->top - s->lim) < BSIZE){
+ char *buf = yasm_xmalloc((size_t)(s->lim - s->bot) + BSIZE);
+ memcpy(buf, s->tok, (size_t)(s->lim - s->tok));
+ s->tok = buf;
+ s->ptr = &buf[s->ptr - s->bot];
+ cursor = &buf[cursor - s->bot];
+ s->pos = &buf[s->pos - s->bot];
+ s->lim = &buf[s->lim - s->bot];
+ s->top = &s->lim[BSIZE];
+ if (s->bot)
+ yasm_xfree(s->bot);
+ s->bot = buf;
}
- if((cnt = nasm_parser_input(s.lim, BSIZE)) == 0){
- s.eof = &s.lim[cnt]; *s.eof++ = '\n';
+ if((cnt = parser_nasm->input(s->lim, BSIZE)) == 0){
+ s->eof = &s->lim[cnt]; *s->eof++ = '\n';
}
- s.lim += cnt;
- if (first && nasm_parser_save_input) {
+ s->lim += cnt;
+ if (first && parser_nasm->save_input) {
int i;
/* save next line into cur_line */
- for (i=0; i<79 && &s.tok[i] < s.lim && s.tok[i] != '\n'; i++)
- cur_line[i] = s.tok[i];
- cur_line[i] = '\0';
+ for (i=0; i<79 && &s->tok[i] < s->lim && s->tok[i] != '\n'; i++)
+ parser_nasm->save_line[i] = s->tok[i];
+ parser_nasm->save_line[i] = '\0';
}
}
return cursor;
}
static void
-delete_line(/*@only@*/ void *data)
+destroy_line(/*@only@*/ void *data)
{
yasm_xfree(data);
}
+static void
+print_line(void *data, FILE *f, int indent_level)
+{
+ fprintf(f, "%*s\"%s\"\n", indent_level, "", (char *)data);
+}
+
+static const yasm_assoc_data_callback line_assoc_data = {
+ destroy_line,
+ print_line
+};
+
static YYCTYPE *
-save_line(YYCTYPE *cursor)
+save_line(yasm_parser_nasm *parser_nasm, YYCTYPE *cursor)
{
+ Scanner *s = &parser_nasm->s;
int i = 0;
/* save previous line using assoc_data */
- nasm_parser_linemgr->add_assoc_data(YASM_LINEMGR_STD_TYPE_SOURCE,
- yasm__xstrdup(cur_line), delete_line);
+ yasm_linemap_add_data(parser_nasm->linemap, &line_assoc_data,
+ yasm__xstrdup(parser_nasm->save_line), 1);
/* save next line into cur_line */
if ((YYLIMIT - YYCURSOR) < 80)
YYFILL(80);
- for (i=0; i<79 && &cursor[i] < s.lim && cursor[i] != '\n'; i++)
- cur_line[i] = cursor[i];
- cur_line[i] = '\0';
+ for (i=0; i<79 && &cursor[i] < s->lim && cursor[i] != '\n'; i++)
+ parser_nasm->save_line[i] = cursor[i];
+ parser_nasm->save_line[i] = '\0';
return cursor;
}
void
-nasm_parser_cleanup(void)
+nasm_parser_cleanup(yasm_parser_nasm *parser_nasm)
{
- if (s.bot)
- yasm_xfree(s.bot);
+ if (parser_nasm->s.bot)
+ yasm_xfree(parser_nasm->s.bot);
}
/* starting size of string buffer */
Z = [zZ];
*/
-static enum {
- INITIAL,
- DIRECTIVE,
- DIRECTIVE2,
- LINECHG,
- LINECHG2
-} state = INITIAL;
-
-void
-nasm_parser_set_directive_state(void)
-{
- state = DIRECTIVE;
-}
int
-nasm_parser_lex(void)
+nasm_parser_lex_arg(yasm_parser_nasm *parser_nasm)
{
- YYCTYPE *cursor = s.cur;
+ Scanner *s = &parser_nasm->s;
+ YYCTYPE *cursor = s->cur;
YYCTYPE endch;
size_t count, len;
YYCTYPE savech;
yasm_arch_check_id_retval check_id_ret;
/* Catch EOF */
- if (s.eof && cursor == s.eof)
+ if (s->eof && cursor == s->eof)
return 0;
/* Jump to proper "exclusive" states */
- switch (state) {
+ switch (parser_nasm->state) {
case DIRECTIVE:
goto directive;
case LINECHG:
/*!re2c
/* standard decimal integer */
digit+ {
- savech = s.tok[TOKLEN];
- s.tok[TOKLEN] = '\0';
- yylval.intn = yasm_intnum_new_dec(s.tok, cur_lindex);
- s.tok[TOKLEN] = savech;
+ savech = s->tok[TOKLEN];
+ s->tok[TOKLEN] = '\0';
+ yylval.intn = yasm_intnum_create_dec(s->tok, cur_line);
+ s->tok[TOKLEN] = savech;
RETURN(INTNUM);
}
/* 10010011b - binary number */
bindigit+ "b" {
- s.tok[TOKLEN-1] = '\0'; /* strip off 'b' */
- yylval.intn = yasm_intnum_new_bin(s.tok, cur_lindex);
+ s->tok[TOKLEN-1] = '\0'; /* strip off 'b' */
+ yylval.intn = yasm_intnum_create_bin(s->tok, cur_line);
RETURN(INTNUM);
}
/* 777q - octal number */
octdigit+ "q" {
- s.tok[TOKLEN-1] = '\0'; /* strip off 'q' */
- yylval.intn = yasm_intnum_new_oct(s.tok, cur_lindex);
+ s->tok[TOKLEN-1] = '\0'; /* strip off 'q' */
+ yylval.intn = yasm_intnum_create_oct(s->tok, cur_line);
RETURN(INTNUM);
}
/* 0AAh form of hexidecimal number */
digit hexdigit* "h" {
- s.tok[TOKLEN-1] = '\0'; /* strip off 'h' */
- yylval.intn = yasm_intnum_new_hex(s.tok, cur_lindex);
+ s->tok[TOKLEN-1] = '\0'; /* strip off 'h' */
+ yylval.intn = yasm_intnum_create_hex(s->tok, cur_line);
RETURN(INTNUM);
}
/* $0AA and 0xAA forms of hexidecimal number */
(("$" digit) | "0x") hexdigit+ {
- savech = s.tok[TOKLEN];
- s.tok[TOKLEN] = '\0';
- if (s.tok[1] == 'x')
+ savech = s->tok[TOKLEN];
+ s->tok[TOKLEN] = '\0';
+ if (s->tok[1] == 'x')
/* skip 0 and x */
- yylval.intn = yasm_intnum_new_hex(s.tok+2, cur_lindex);
+ yylval.intn = yasm_intnum_create_hex(s->tok+2, cur_line);
else
/* don't skip 0 */
- yylval.intn = yasm_intnum_new_hex(s.tok+1, cur_lindex);
- s.tok[TOKLEN] = savech;
+ yylval.intn = yasm_intnum_create_hex(s->tok+1, cur_line);
+ s->tok[TOKLEN] = savech;
RETURN(INTNUM);
}
/* floating point value */
digit+ "." digit* (E [-+]? digit+)? {
- savech = s.tok[TOKLEN];
- s.tok[TOKLEN] = '\0';
- yylval.flt = yasm_floatnum_new(s.tok);
- s.tok[TOKLEN] = savech;
+ savech = s->tok[TOKLEN];
+ s->tok[TOKLEN] = '\0';
+ yylval.flt = yasm_floatnum_create(s->tok);
+ s->tok[TOKLEN] = savech;
RETURN(FLTNUM);
}
/* string/character constant values */
quot {
- endch = s.tok[0];
+ endch = s->tok[0];
goto stringconst;
}
/* %line linenum+lineinc filename */
"%line" {
- state = LINECHG;
+ parser_nasm->state = LINECHG;
linechg_numcount = 0;
RETURN(LINE);
}
"//" { RETURN(SIGNDIV); }
"%%" { RETURN(SIGNMOD); }
"$$" { RETURN(START_SECTION_ID); }
- [-+|^*&/%~$():=,\[] { RETURN(s.tok[0]); }
+ [-+|^*&/%~$():=,\[] { RETURN(s->tok[0]); }
/* handle ] separately for directives */
"]" {
- if (state == DIRECTIVE2)
- state = INITIAL;
- RETURN(s.tok[0]);
+ if (parser_nasm->state == DIRECTIVE2)
+ parser_nasm->state = INITIAL;
+ RETURN(s->tok[0]);
}
/* special non-local ..@label and labels like ..start */
".." [a-zA-Z0-9_$#@~.?]+ {
- yylval.str_val = yasm__xstrndup(s.tok, TOKLEN);
+ yylval.str_val = yasm__xstrndup(s->tok, TOKLEN);
RETURN(SPECIAL_ID);
}
/* local label (.label) */
"." [a-zA-Z0-9_$#@~?][a-zA-Z0-9_$#@~.?]* {
/* override local labels in directive state */
- if (state == DIRECTIVE2) {
- yylval.str_val = yasm__xstrndup(s.tok, TOKLEN);
+ if (parser_nasm->state == DIRECTIVE2) {
+ yylval.str_val = yasm__xstrndup(s->tok, TOKLEN);
RETURN(ID);
- } else if (!nasm_parser_locallabel_base) {
- yylval.str_val = yasm__xstrndup(s.tok, TOKLEN);
- yasm__warning(YASM_WARN_GENERAL, cur_lindex,
+ } else if (!parser_nasm->locallabel_base) {
+ yylval.str_val = yasm__xstrndup(s->tok, TOKLEN);
+ yasm__warning(YASM_WARN_GENERAL, cur_line,
N_("no non-local label before `%s'"),
yylval.str_val);
} else {
- len = TOKLEN + nasm_parser_locallabel_base_len;
+ len = TOKLEN + parser_nasm->locallabel_base_len;
yylval.str_val = yasm_xmalloc(len + 1);
- strcpy(yylval.str_val, nasm_parser_locallabel_base);
- strncat(yylval.str_val, s.tok, TOKLEN);
+ strcpy(yylval.str_val, parser_nasm->locallabel_base);
+ strncat(yylval.str_val, s->tok, TOKLEN);
yylval.str_val[len] = '\0';
}
/* forced identifier */
"$" [a-zA-Z_?][a-zA-Z0-9_$#@~.?]* {
- yylval.str_val = yasm__xstrndup(s.tok, TOKLEN);
+ yylval.str_val = yasm__xstrndup(s->tok, TOKLEN);
RETURN(ID);
}
/* identifier that may be a register, instruction, etc. */
[a-zA-Z_?][a-zA-Z0-9_$#@~.?]* {
- savech = s.tok[TOKLEN];
- s.tok[TOKLEN] = '\0';
- check_id_ret = nasm_parser_arch->parse_check_id(yylval.arch_data,
- s.tok, cur_lindex);
- s.tok[TOKLEN] = savech;
+ savech = s->tok[TOKLEN];
+ s->tok[TOKLEN] = '\0';
+ check_id_ret = p_arch->module->parse_check_id(p_arch,
+ yylval.arch_data,
+ s->tok, cur_line);
+ s->tok[TOKLEN] = savech;
switch (check_id_ret) {
case YASM_ARCH_CHECK_ID_NONE:
/* Just an identifier, return as such. */
- yylval.str_val = yasm__xstrndup(s.tok, TOKLEN);
+ yylval.str_val = yasm__xstrndup(s->tok, TOKLEN);
RETURN(ID);
case YASM_ARCH_CHECK_ID_INSN:
RETURN(INSN);
case YASM_ARCH_CHECK_ID_TARGETMOD:
RETURN(TARGETMOD);
default:
- yasm__warning(YASM_WARN_GENERAL, cur_lindex,
+ yasm__warning(YASM_WARN_GENERAL, cur_line,
N_("Arch feature not supported, treating as identifier"));
- yylval.str_val = yasm__xstrndup(s.tok, TOKLEN);
+ yylval.str_val = yasm__xstrndup(s->tok, TOKLEN);
RETURN(ID);
}
}
ws+ { goto scan; }
"\n" {
- if (nasm_parser_save_input && cursor != s.eof)
- cursor = save_line(cursor);
- state = INITIAL;
- RETURN(s.tok[0]);
+ if (parser_nasm->save_input && cursor != s->eof)
+ cursor = save_line(parser_nasm, cursor);
+ parser_nasm->state = INITIAL;
+ RETURN(s->tok[0]);
}
any {
- yasm__warning(YASM_WARN_UNREC_CHAR, cur_lindex,
+ yasm__warning(YASM_WARN_UNREC_CHAR, cur_line,
N_("ignoring unrecognized character `%s'"),
- yasm__conv_unprint(s.tok[0]));
+ yasm__conv_unprint(s->tok[0]));
goto scan;
}
*/
/*!re2c
digit+ {
linechg_numcount++;
- savech = s.tok[TOKLEN];
- s.tok[TOKLEN] = '\0';
- yylval.intn = yasm_intnum_new_dec(s.tok, cur_lindex);
- s.tok[TOKLEN] = savech;
+ savech = s->tok[TOKLEN];
+ s->tok[TOKLEN] = '\0';
+ yylval.intn = yasm_intnum_create_dec(s->tok, cur_line);
+ s->tok[TOKLEN] = savech;
RETURN(INTNUM);
}
"\n" {
- if (nasm_parser_save_input && cursor != s.eof)
- cursor = save_line(cursor);
- state = INITIAL;
- RETURN(s.tok[0]);
+ if (parser_nasm->save_input && cursor != s->eof)
+ cursor = save_line(parser_nasm, cursor);
+ parser_nasm->state = INITIAL;
+ RETURN(s->tok[0]);
}
"+" {
- RETURN(s.tok[0]);
+ RETURN(s->tok[0]);
}
ws+ {
if (linechg_numcount == 2) {
- state = LINECHG2;
+ parser_nasm->state = LINECHG2;
goto linechg2;
}
goto linechg;
}
any {
- yasm__warning(YASM_WARN_UNREC_CHAR, cur_lindex,
+ yasm__warning(YASM_WARN_UNREC_CHAR, cur_line,
N_("ignoring unrecognized character `%s'"),
- yasm__conv_unprint(s.tok[0]));
+ yasm__conv_unprint(s->tok[0]));
goto linechg;
}
*/
/*!re2c
"\n" {
- if (nasm_parser_save_input && cursor != s.eof)
- cursor = save_line(cursor);
- state = INITIAL;
- RETURN(s.tok[0]);
+ if (parser_nasm->save_input && cursor != s->eof)
+ cursor = save_line(parser_nasm, cursor);
+ parser_nasm->state = INITIAL;
+ RETURN(s->tok[0]);
}
"\r" { }
(any \ [\r\n])+ {
- state = LINECHG;
- yylval.str_val = yasm__xstrndup(s.tok, TOKLEN);
+ parser_nasm->state = LINECHG;
+ yylval.str_val = yasm__xstrndup(s->tok, TOKLEN);
RETURN(FILENAME);
}
*/
/*!re2c
[\]\n] {
- if (nasm_parser_save_input && cursor != s.eof)
- cursor = save_line(cursor);
- state = INITIAL;
- RETURN(s.tok[0]);
+ if (parser_nasm->save_input && cursor != s->eof)
+ cursor = save_line(parser_nasm, cursor);
+ parser_nasm->state = INITIAL;
+ RETURN(s->tok[0]);
}
iletter+ {
- state = DIRECTIVE2;
- yylval.str_val = yasm__xstrndup(s.tok, TOKLEN);
+ parser_nasm->state = DIRECTIVE2;
+ yylval.str_val = yasm__xstrndup(s->tok, TOKLEN);
RETURN(DIRECTIVE_NAME);
}
any {
- yasm__warning(YASM_WARN_UNREC_CHAR, cur_lindex,
+ yasm__warning(YASM_WARN_UNREC_CHAR, cur_line,
N_("ignoring unrecognized character `%s'"),
- yasm__conv_unprint(s.tok[0]));
+ yasm__conv_unprint(s->tok[0]));
goto directive;
}
*/
/*!re2c
"\n" {
- if (cursor == s.eof)
- yasm__error(cur_lindex,
+ if (cursor == s->eof)
+ yasm__error(cur_line,
N_("unexpected end of file in string"));
else
- yasm__error(cur_lindex, N_("unterminated string"));
+ yasm__error(cur_line, N_("unterminated string"));
strbuf[count] = '\0';
yylval.str_val = strbuf;
- if (nasm_parser_save_input && cursor != s.eof)
- cursor = save_line(cursor);
+ if (parser_nasm->save_input && cursor != s->eof)
+ cursor = save_line(parser_nasm, cursor);
RETURN(STRING);
}
any {
- if (s.tok[0] == endch) {
+ if (s->tok[0] == endch) {
strbuf[count] = '\0';
yylval.str_val = strbuf;
RETURN(STRING);
}
- strbuf[count++] = s.tok[0];
+ strbuf[count++] = s->tok[0];
if (count >= strbuf_size) {
strbuf = yasm_xrealloc(strbuf, strbuf_size + STRBUF_ALLOC_SIZE);
strbuf_size += STRBUF_ALLOC_SIZE;
#include "nasm-eval.h"
static FILE *in;
-static yasm_linemgr *cur_lm;
+static yasm_linemap *cur_lm;
static char *line, *linepos;
static size_t lineleft;
static char *file_name;
va_start(va, fmt);
switch (severity & ERR_MASK) {
case ERR_WARNING:
- yasm__warning_va(YASM_WARN_PREPROC, cur_lm->get_current(), fmt,
- va);
+ yasm__warning_va(YASM_WARN_PREPROC,
+ yasm_linemap_get_current(cur_lm), fmt, va);
break;
case ERR_NONFATAL:
- yasm__error_va(cur_lm->get_current(), fmt, va);
+ yasm__error_va(yasm_linemap_get_current(cur_lm), fmt, va);
break;
case ERR_FATAL:
yasm_fatal(N_("unknown")); /* FIXME */
}
static void
-nasm_preproc_initialize(FILE *f, const char *in_filename, yasm_linemgr *lm)
+nasm_preproc_initialize(FILE *f, const char *in_filename, yasm_linemap *lm)
{
in = f;
cur_lm = lm;
nasm_preproc_cleanup(void)
{
nasmpp.cleanup(0);
+ nasm_eval_cleanup();
}
static size_t
static int is_interactive;
static FILE *in;
-static yasm_linemgr *cur_lm;
+static yasm_linemap *cur_lm;
int isatty(int);
static void
-raw_preproc_initialize(FILE *f, const char *in_filename, yasm_linemgr *lm)
+raw_preproc_initialize(FILE *f, const char *in_filename, yasm_linemap *lm)
{
in = f;
cur_lm = lm;
if (c == '\n')
buf[n++] = (char)c;
if (c == EOF && ferror(in))
- yasm__error(cur_lm->get_current(),
+ yasm__error(yasm_linemap_get_current(cur_lm),
N_("error when reading from file"));
} else if (((n = fread(buf, 1, max_size, in)) == 0) && ferror(in))
- yasm__error(cur_lm->get_current(), N_("error when reading from file"));
+ yasm__error(yasm_linemap_get_current(cur_lm),
+ N_("error when reading from file"));
return n;
}