Init
This commit is contained in:
@ -0,0 +1,9 @@
|
||||
#ifndef _YASM_LIBYASM_STDINT_H
|
||||
#define _YASM_LIBYASM_STDINT_H 1
|
||||
#ifndef _GENERATED_STDINT_H
|
||||
#define _GENERATED_STDINT_H "yasm 1.3.0"
|
||||
/* generated using /mnt/disks/build-disk/src/android/ndk-r27-release/prebuilts/clang/host/linux-x86/clang-r522817d/bin/clang --target=x86_64-w64-mingw32 -I/mnt/disks/build-disk/src/android/ndk-r27-release/prebuilts/clang/host/windows-x86/clang-r522817d/include/c++/v1 --sysroot=/mnt/disks/build-disk/src/android/ndk-r27-release/prebuilts/gcc/linux-x86/host/x86_64-w64-mingw32-4.8/x86_64-w64-mingw32 -L/mnt/disks/build-disk/src/android/ndk-r27-release/prebuilts/gcc/linux-x86/host/x86_64-w64-mingw32-4.8/lib/gcc/x86_64-w64-mingw32/4.8.3 -B/mnt/disks/build-disk/src/android/ndk-r27-release/prebuilts/gcc/linux-x86/host/x86_64-w64-mingw32-4.8/lib/gcc/x86_64-w64-mingw32/4.8.3 -L/mnt/disks/build-disk/src/android/ndk-r27-release/prebuilts/gcc/linux-x86/host/x86_64-w64-mingw32-4.8/x86_64-w64-mingw32/lib64 -B/mnt/disks/build-disk/src/android/ndk-r27-release/prebuilts/gcc/linux-x86/host/x86_64-w64-mingw32-4.8/x86_64-w64-mingw32/lib64 -L/mnt/disks/build-disk/src/android/ndk-r27-release/prebuilts/clang/host/windows-x86/clang-r522817d/lib64 -B/mnt/disks/build-disk/src/android/ndk-r27-release/prebuilts/clang/host/windows-x86/clang-r522817d/lib64 -Os -fomit-frame-pointer -w -fuse-ld=lld -s */
|
||||
#define _STDINT_HAVE_STDINT_H 1
|
||||
#include <stdint.h>
|
||||
#endif
|
||||
#endif
|
||||
@ -0,0 +1,75 @@
|
||||
/**
|
||||
* \file libyasm.h
|
||||
* \brief YASM library primary header file.
|
||||
*
|
||||
* \license
|
||||
* Copyright (C) 2003-2007 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_LIB_H
|
||||
#define YASM_LIB_H
|
||||
|
||||
#ifdef YASM_PYXELATOR
|
||||
typedef struct __FILE FILE;
|
||||
typedef struct __va_list va_list;
|
||||
typedef unsigned long size_t;
|
||||
typedef unsigned long uintptr_t;
|
||||
#else
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <libyasm-stdint.h>
|
||||
#endif
|
||||
|
||||
#include <libyasm/compat-queue.h>
|
||||
|
||||
#include <libyasm/coretype.h>
|
||||
#include <libyasm/valparam.h>
|
||||
|
||||
#include <libyasm/linemap.h>
|
||||
|
||||
#include <libyasm/errwarn.h>
|
||||
#include <libyasm/intnum.h>
|
||||
#include <libyasm/floatnum.h>
|
||||
#include <libyasm/expr.h>
|
||||
#include <libyasm/value.h>
|
||||
#include <libyasm/symrec.h>
|
||||
|
||||
#include <libyasm/bytecode.h>
|
||||
#include <libyasm/section.h>
|
||||
#include <libyasm/insn.h>
|
||||
|
||||
#include <libyasm/arch.h>
|
||||
#include <libyasm/dbgfmt.h>
|
||||
#include <libyasm/objfmt.h>
|
||||
#include <libyasm/listfmt.h>
|
||||
#include <libyasm/parser.h>
|
||||
#include <libyasm/preproc.h>
|
||||
|
||||
#include <libyasm/file.h>
|
||||
#include <libyasm/module.h>
|
||||
|
||||
#include <libyasm/hamt.h>
|
||||
#include <libyasm/md5.h>
|
||||
|
||||
#endif
|
||||
@ -0,0 +1,495 @@
|
||||
/**
|
||||
* \file libyasm/arch.h
|
||||
* \brief YASM architecture interface.
|
||||
*
|
||||
* \license
|
||||
* Copyright (C) 2002-2007 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_ARCH_H
|
||||
#define YASM_ARCH_H
|
||||
|
||||
/** Errors that may be returned by yasm_arch_module::create(). */
|
||||
typedef enum yasm_arch_create_error {
|
||||
YASM_ARCH_CREATE_OK = 0, /**< No error. */
|
||||
YASM_ARCH_CREATE_BAD_MACHINE, /**< Unrecognized machine name. */
|
||||
YASM_ARCH_CREATE_BAD_PARSER /**< Unrecognized parser name. */
|
||||
} yasm_arch_create_error;
|
||||
|
||||
/** Return values for yasm_arch_module::parse_check_insnprefix(). */
|
||||
typedef enum yasm_arch_insnprefix {
|
||||
YASM_ARCH_NOTINSNPREFIX = 0, /**< Unrecognized */
|
||||
YASM_ARCH_INSN, /**< An instruction */
|
||||
YASM_ARCH_PREFIX /**< An instruction prefix */
|
||||
} yasm_arch_insnprefix;
|
||||
|
||||
/** Types of registers / target modifiers that may be returned by
|
||||
* yasm_arch_module::parse_check_regtmod().
|
||||
*/
|
||||
typedef enum yasm_arch_regtmod {
|
||||
YASM_ARCH_NOTREGTMOD = 0, /**< Unrecognized */
|
||||
YASM_ARCH_REG, /**< A "normal" register */
|
||||
YASM_ARCH_REGGROUP, /**< A group of indexable registers */
|
||||
YASM_ARCH_SEGREG, /**< A segment register */
|
||||
YASM_ARCH_TARGETMOD /**< A target modifier (for jumps) */
|
||||
} yasm_arch_regtmod;
|
||||
|
||||
#ifndef YASM_DOXYGEN
|
||||
/** Base #yasm_arch structure. Must be present as the first element in any
|
||||
* #yasm_arch implementation.
|
||||
*/
|
||||
typedef struct yasm_arch_base {
|
||||
/** #yasm_arch_module implementation for this architecture. */
|
||||
const struct yasm_arch_module *module;
|
||||
} yasm_arch_base;
|
||||
#endif
|
||||
|
||||
/** YASM machine subtype. A number of different machine types may be
|
||||
* associated with a single architecture. These may be specific CPU's, but
|
||||
* the ABI used to interface with the architecture should be the primary
|
||||
* differentiator between machines. Some object formats (ELF) use the machine
|
||||
* to determine parameters within the generated output.
|
||||
*/
|
||||
typedef struct yasm_arch_machine {
|
||||
/** One-line description of the machine. */
|
||||
const char *name;
|
||||
|
||||
/** Keyword used to select machine. */
|
||||
const char *keyword;
|
||||
} yasm_arch_machine;
|
||||
|
||||
/** YASM architecture module interface.
|
||||
* \note All "data" in parser-related functions (yasm_arch_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.
|
||||
*/
|
||||
typedef struct yasm_arch_module {
|
||||
/** One-line description of the architecture.
|
||||
* Call yasm_arch_name() to get the name of a particular #yasm_arch.
|
||||
*/
|
||||
const char *name;
|
||||
|
||||
/** Keyword used to select architecture.
|
||||
* Call yasm_arch_keyword() to get the keyword of a particular #yasm_arch.
|
||||
*/
|
||||
const char *keyword;
|
||||
|
||||
/** NULL-terminated list of directives. NULL if none. */
|
||||
/*@null@*/ const yasm_directive *directives;
|
||||
|
||||
/** Create architecture.
|
||||
* Module-level implementation of yasm_arch_create().
|
||||
* Call yasm_arch_create() instead of calling this function.
|
||||
*/
|
||||
/*@only@*/ yasm_arch * (*create) (const char *machine, const char *parser,
|
||||
/*@out@*/ yasm_arch_create_error *error);
|
||||
|
||||
/** Module-level implementation of yasm_arch_destroy().
|
||||
* Call yasm_arch_destroy() instead of calling this function.
|
||||
*/
|
||||
void (*destroy) (/*@only@*/ yasm_arch *arch);
|
||||
|
||||
/** Module-level implementation of yasm_arch_get_machine().
|
||||
* Call yasm_arch_get_machine() instead of calling this function.
|
||||
*/
|
||||
const char * (*get_machine) (const yasm_arch *arch);
|
||||
|
||||
/** Module-level implementation of yasm_arch_get_address_size().
|
||||
* Call yasm_arch_get_address_size() instead of calling this function.
|
||||
*/
|
||||
unsigned int (*get_address_size) (const yasm_arch *arch);
|
||||
|
||||
/** Module-level implementation of yasm_arch_set_var().
|
||||
* Call yasm_arch_set_var() instead of calling this function.
|
||||
*/
|
||||
int (*set_var) (yasm_arch *arch, const char *var, unsigned long val);
|
||||
|
||||
/** Module-level implementation of yasm_arch_parse_check_insnprefix().
|
||||
* Call yasm_arch_parse_check_insnprefix() instead of calling this function.
|
||||
*/
|
||||
yasm_arch_insnprefix (*parse_check_insnprefix)
|
||||
(yasm_arch *arch, const char *id, size_t id_len, unsigned long line,
|
||||
/*@out@*/ /*@only@*/ yasm_bytecode **bc, /*@out@*/ uintptr_t *prefix);
|
||||
|
||||
/** Module-level implementation of yasm_arch_parse_check_regtmod().
|
||||
* Call yasm_arch_parse_check_regtmod() instead of calling this function.
|
||||
*/
|
||||
yasm_arch_regtmod (*parse_check_regtmod)
|
||||
(yasm_arch *arch, const char *id, size_t id_len,
|
||||
/*@out@*/ uintptr_t *data);
|
||||
|
||||
/** Module-level implementation of yasm_arch_get_fill().
|
||||
* Call yasm_arch_get_fill() instead of calling this function.
|
||||
*/
|
||||
const unsigned char ** (*get_fill) (const yasm_arch *arch);
|
||||
|
||||
/** Module-level implementation of yasm_arch_floatnum_tobytes().
|
||||
* Call yasm_arch_floatnum_tobytes() instead of calling this function.
|
||||
*/
|
||||
int (*floatnum_tobytes) (yasm_arch *arch, const yasm_floatnum *flt,
|
||||
unsigned char *buf, size_t destsize,
|
||||
size_t valsize, size_t shift, int warn);
|
||||
|
||||
/** Module-level implementation of yasm_arch_intnum_tobytes().
|
||||
* Call yasm_arch_intnum_tobytes() instead of calling this function.
|
||||
*/
|
||||
int (*intnum_tobytes) (yasm_arch *arch, const yasm_intnum *intn,
|
||||
unsigned char *buf, size_t destsize, size_t valsize,
|
||||
int shift, const yasm_bytecode *bc,
|
||||
int warn);
|
||||
|
||||
/** Module-level implementation of yasm_arch_get_reg_size().
|
||||
* Call yasm_arch_get_reg_size() instead of calling this function.
|
||||
*/
|
||||
unsigned int (*get_reg_size) (yasm_arch *arch, uintptr_t reg);
|
||||
|
||||
/** Module-level implementation of yasm_arch_reggroup_get_reg().
|
||||
* Call yasm_arch_reggroup_get_reg() instead of calling this function.
|
||||
*/
|
||||
uintptr_t (*reggroup_get_reg) (yasm_arch *arch, uintptr_t reggroup,
|
||||
unsigned long regindex);
|
||||
|
||||
/** Module-level implementation of yasm_arch_reg_print().
|
||||
* Call yasm_arch_reg_print() instead of calling this function.
|
||||
*/
|
||||
void (*reg_print) (yasm_arch *arch, uintptr_t reg, FILE *f);
|
||||
|
||||
/** Module-level implementation of yasm_arch_segreg_print().
|
||||
* Call yasm_arch_segreg_print() instead of calling this function.
|
||||
*/
|
||||
void (*segreg_print) (yasm_arch *arch, uintptr_t segreg, FILE *f);
|
||||
|
||||
/** Module-level implementation of yasm_arch_ea_create().
|
||||
* Call yasm_arch_ea_create() instead of calling this function.
|
||||
*/
|
||||
yasm_effaddr * (*ea_create) (yasm_arch *arch, /*@keep@*/ yasm_expr *e);
|
||||
|
||||
/** Module-level implementation of yasm_arch_ea_destroy().
|
||||
* Call yasm_arch_ea_destroy() instead of calling this function.
|
||||
*/
|
||||
void (*ea_destroy) (/*@only@*/ yasm_effaddr *ea);
|
||||
|
||||
/** Module-level implementation of yasm_arch_ea_print().
|
||||
* Call yasm_arch_ea_print() instead of calling this function.
|
||||
*/
|
||||
void (*ea_print) (const yasm_effaddr *ea, FILE *f, int indent_level);
|
||||
|
||||
/** Module-level implementation of yasm_arch_create_empty_insn().
|
||||
* Call yasm_arch_create_empty_insn() instead of calling this function.
|
||||
*/
|
||||
/*@only@*/ yasm_bytecode * (*create_empty_insn) (yasm_arch *arch,
|
||||
unsigned long line);
|
||||
|
||||
/** NULL-terminated list of machines for this architecture.
|
||||
* Call yasm_arch_get_machine() to get the active machine of a particular
|
||||
* #yasm_arch.
|
||||
*/
|
||||
const yasm_arch_machine *machines;
|
||||
|
||||
/** Default machine keyword.
|
||||
* Call yasm_arch_get_machine() to get the active machine of a particular
|
||||
* #yasm_arch.
|
||||
*/
|
||||
const char *default_machine_keyword;
|
||||
|
||||
/** Canonical "word" size in bits.
|
||||
* Call yasm_arch_wordsize() to get the word size of a particular
|
||||
* #yasm_arch.
|
||||
*/
|
||||
unsigned int wordsize;
|
||||
|
||||
/** Worst case minimum instruction length in bytes.
|
||||
* Call yasm_arch_min_insn_len() to get the minimum instruction length of
|
||||
* a particular #yasm_arch.
|
||||
*/
|
||||
unsigned int min_insn_len;
|
||||
} yasm_arch_module;
|
||||
|
||||
/** Get the one-line description of an architecture.
|
||||
* \param arch architecture
|
||||
* \return One-line description of architecture.
|
||||
*/
|
||||
const char *yasm_arch_name(const yasm_arch *arch);
|
||||
|
||||
/** Get the keyword used to select an architecture.
|
||||
* \param arch architecture
|
||||
* \return Architecture keyword.
|
||||
*/
|
||||
const char *yasm_arch_keyword(const yasm_arch *arch);
|
||||
|
||||
/** Get the word size of an architecture.
|
||||
* \param arch architecture
|
||||
* \return Word size (in bits).
|
||||
*/
|
||||
unsigned int yasm_arch_wordsize(const yasm_arch *arch);
|
||||
|
||||
/** Get the minimum instruction length of an architecture.
|
||||
* \param arch architecture
|
||||
* \return Minimum instruction length (in bytes).
|
||||
*/
|
||||
unsigned int yasm_arch_min_insn_len(const yasm_arch *arch);
|
||||
|
||||
/** Create architecture.
|
||||
* \param module architecture module
|
||||
* \param machine keyword of machine in use (must be one listed in
|
||||
* #yasm_arch_module.machines)
|
||||
* \param parser keyword of parser in use
|
||||
* \param error error return value
|
||||
* \return NULL on error (error returned in error parameter), otherwise new
|
||||
* architecture.
|
||||
*/
|
||||
/*@only@*/ yasm_arch *yasm_arch_create(const yasm_arch_module *module,
|
||||
const char *machine, const char *parser,
|
||||
/*@out@*/ yasm_arch_create_error *error);
|
||||
|
||||
/** Clean up, free any architecture-allocated memory.
|
||||
* \param arch architecture
|
||||
*/
|
||||
void yasm_arch_destroy(/*@only@*/ yasm_arch *arch);
|
||||
|
||||
/** Get architecture's active machine name.
|
||||
* \param arch architecture
|
||||
* \return Active machine name.
|
||||
*/
|
||||
const char *yasm_arch_get_machine(const yasm_arch *arch);
|
||||
|
||||
/** Get architecture's active address size, in bits.
|
||||
* \param arch architecture
|
||||
* \return Active address size (in bits).
|
||||
*/
|
||||
unsigned int yasm_arch_get_address_size(const yasm_arch *arch);
|
||||
|
||||
/** Set any arch-specific variables. For example, "mode_bits" in x86.
|
||||
* \param arch architecture
|
||||
* \param var variable name
|
||||
* \param val value to set
|
||||
* \return Zero on success, non-zero on failure (variable does not exist).
|
||||
*/
|
||||
int yasm_arch_set_var(yasm_arch *arch, const char *var, unsigned long val);
|
||||
|
||||
/** Check an generic identifier to see if it matches architecture specific
|
||||
* names for instructions or instruction prefixes. Unrecognized identifiers
|
||||
* should return #YASM_ARCH_NOTINSNPREFIX so they can be treated as normal
|
||||
* symbols. Any additional data beyond just the type (almost always necessary)
|
||||
* should be returned into the space provided by the data parameter.
|
||||
* \param arch architecture
|
||||
* \param id identifier as in the input file
|
||||
* \param id_len length of id string
|
||||
* \param line virtual line
|
||||
* \param bc for instructions, yasm_insn-based bytecode is returned
|
||||
* (and NULL otherwise)
|
||||
* \param prefix for prefixes, yasm_arch-specific value is returned
|
||||
* (and 0 otherwise)
|
||||
* \return Identifier type (#YASM_ARCH_NOTINSNPREFIX if unrecognized)
|
||||
*/
|
||||
yasm_arch_insnprefix yasm_arch_parse_check_insnprefix
|
||||
(yasm_arch *arch, const char *id, size_t id_len, unsigned long line,
|
||||
/*@out@*/ /*@only@*/ yasm_bytecode **bc, /*@out@*/ uintptr_t *prefix);
|
||||
|
||||
/** Check an generic identifier to see if it matches architecture specific
|
||||
* names for registers or target modifiers. Unrecognized identifiers should
|
||||
* return #YASM_ARCH_NOTREGTMOD. Any additional data beyond just the type
|
||||
* (almost always necessary) should be returned into the space provided by the
|
||||
* data parameter.
|
||||
* \param arch architecture
|
||||
* \param id identifier as in the input file
|
||||
* \param id_len length of id string
|
||||
* \param data extra identification information (yasm_arch-specific)
|
||||
* [output]
|
||||
* \return Identifier type (#YASM_ARCH_NOTREGTMOD if unrecognized)
|
||||
*/
|
||||
yasm_arch_regtmod yasm_arch_parse_check_regtmod
|
||||
(yasm_arch *arch, const char *id, size_t id_len,
|
||||
/*@out@*/ uintptr_t *data);
|
||||
|
||||
/** Get NOP fill patterns for 1-15 bytes of fill.
|
||||
* \param arch architecture
|
||||
* \return 16-entry array of arrays; [0] is unused, [1] - [15] point to arrays
|
||||
* of 1-15 bytes (respectively) in length.
|
||||
*/
|
||||
const unsigned char **yasm_arch_get_fill(const yasm_arch *arch);
|
||||
|
||||
/** Output #yasm_floatnum to buffer. Puts the value into the least
|
||||
* significant bits of the destination, or may be shifted into more
|
||||
* significant bits by the shift parameter. The destination bits are
|
||||
* cleared before being set.
|
||||
* Architecture-specific because of endianness.
|
||||
* \param arch architecture
|
||||
* \param flt floating point value
|
||||
* \param buf buffer to write into
|
||||
* \param destsize destination size (in bytes)
|
||||
* \param valsize size (in bits)
|
||||
* \param shift left shift (in bits)
|
||||
* \param warn enables standard overflow/underflow warnings
|
||||
* \return Nonzero on error.
|
||||
*/
|
||||
int yasm_arch_floatnum_tobytes(yasm_arch *arch, const yasm_floatnum *flt,
|
||||
unsigned char *buf, size_t destsize,
|
||||
size_t valsize, size_t shift, int warn);
|
||||
|
||||
/** Output #yasm_intnum to buffer. Puts the value into the least
|
||||
* significant bits of the destination, or may be shifted into more
|
||||
* significant bits by the shift parameter. The destination bits are
|
||||
* cleared before being set.
|
||||
* \param arch architecture
|
||||
* \param intn integer value
|
||||
* \param buf buffer to write into
|
||||
* \param destsize destination size (in bytes)
|
||||
* \param valsize size (in bits)
|
||||
* \param shift left shift (in bits); may be negative to specify right
|
||||
* shift (standard warnings include truncation to boundary)
|
||||
* \param bc bytecode being output ("parent" of value)
|
||||
* \param warn enables standard warnings (value doesn't fit into
|
||||
* valsize bits)
|
||||
* \return Nonzero on error.
|
||||
*/
|
||||
int yasm_arch_intnum_tobytes(yasm_arch *arch, const yasm_intnum *intn,
|
||||
unsigned char *buf, size_t destsize,
|
||||
size_t valsize, int shift,
|
||||
const yasm_bytecode *bc, int warn);
|
||||
|
||||
/** Get the equivalent size of a register in bits.
|
||||
* \param arch architecture
|
||||
* \param reg register
|
||||
* \return 0 if there is no suitable equivalent size, otherwise the size.
|
||||
*/
|
||||
unsigned int yasm_arch_get_reg_size(yasm_arch *arch, uintptr_t reg);
|
||||
|
||||
/** Get a specific register of a register group, based on the register
|
||||
* group and the index within the group.
|
||||
* \param arch architecture
|
||||
* \param reggroup register group
|
||||
* \param regindex register index
|
||||
* \return 0 if regindex is not valid for that register group, otherwise the
|
||||
* specific register value.
|
||||
*/
|
||||
uintptr_t yasm_arch_reggroup_get_reg(yasm_arch *arch, uintptr_t reggroup,
|
||||
unsigned long regindex);
|
||||
|
||||
/** Print a register. For debugging purposes.
|
||||
* \param arch architecture
|
||||
* \param reg register
|
||||
* \param f file
|
||||
*/
|
||||
void yasm_arch_reg_print(yasm_arch *arch, uintptr_t reg, FILE *f);
|
||||
|
||||
/** Print a segment register. For debugging purposes.
|
||||
* \param arch architecture
|
||||
* \param segreg segment register
|
||||
* \param f file
|
||||
*/
|
||||
void yasm_arch_segreg_print(yasm_arch *arch, uintptr_t segreg, FILE *f);
|
||||
|
||||
/** Create an effective address from an expression.
|
||||
* \param arch architecture
|
||||
* \param e expression (kept, do not delete)
|
||||
* \return Newly allocated effective address.
|
||||
*/
|
||||
yasm_effaddr *yasm_arch_ea_create(yasm_arch *arch, /*@keep@*/ yasm_expr *e);
|
||||
|
||||
/** Delete (free allocated memory for) an effective address.
|
||||
* \param arch architecture
|
||||
* \param ea effective address (only pointer to it).
|
||||
*/
|
||||
void yasm_arch_ea_destroy(yasm_arch *arch, /*@only@*/ yasm_effaddr *ea);
|
||||
|
||||
/** Print an effective address. For debugging purposes.
|
||||
* \param arch architecture
|
||||
* \param ea effective address
|
||||
* \param f file
|
||||
* \param indent_level indentation level
|
||||
*/
|
||||
void yasm_arch_ea_print(const yasm_arch *arch, const yasm_effaddr *ea,
|
||||
FILE *f, int indent_level);
|
||||
|
||||
/** Create a bytecode that represents a single empty (0 length) instruction.
|
||||
* This is used for handling solitary prefixes.
|
||||
* \param arch architecture
|
||||
* \param line virtual line (from yasm_linemap)
|
||||
* \return Newly allocated bytecode.
|
||||
*/
|
||||
/*@only@*/ yasm_bytecode *yasm_arch_create_empty_insn(yasm_arch *arch,
|
||||
unsigned long line);
|
||||
|
||||
#ifndef YASM_DOXYGEN
|
||||
|
||||
/* Inline macro implementations for arch functions */
|
||||
|
||||
#define yasm_arch_name(arch) \
|
||||
(((yasm_arch_base *)arch)->module->name)
|
||||
#define yasm_arch_keyword(arch) \
|
||||
(((yasm_arch_base *)arch)->module->keyword)
|
||||
#define yasm_arch_wordsize(arch) \
|
||||
(((yasm_arch_base *)arch)->module->wordsize)
|
||||
#define yasm_arch_min_insn_len(arch) \
|
||||
(((yasm_arch_base *)arch)->module->min_insn_len)
|
||||
|
||||
#define yasm_arch_create(module, machine, parser, error) \
|
||||
module->create(machine, parser, error)
|
||||
|
||||
#define yasm_arch_destroy(arch) \
|
||||
((yasm_arch_base *)arch)->module->destroy(arch)
|
||||
#define yasm_arch_get_machine(arch) \
|
||||
((yasm_arch_base *)arch)->module->get_machine(arch)
|
||||
#define yasm_arch_get_address_size(arch) \
|
||||
((yasm_arch_base *)arch)->module->get_address_size(arch)
|
||||
#define yasm_arch_set_var(arch, var, val) \
|
||||
((yasm_arch_base *)arch)->module->set_var(arch, var, val)
|
||||
#define yasm_arch_parse_check_insnprefix(arch, id, id_len, line, bc, prefix) \
|
||||
((yasm_arch_base *)arch)->module->parse_check_insnprefix \
|
||||
(arch, id, id_len, line, bc, prefix)
|
||||
#define yasm_arch_parse_check_regtmod(arch, id, id_len, data) \
|
||||
((yasm_arch_base *)arch)->module->parse_check_regtmod \
|
||||
(arch, id, id_len, data)
|
||||
#define yasm_arch_get_fill(arch) \
|
||||
((yasm_arch_base *)arch)->module->get_fill(arch)
|
||||
#define yasm_arch_floatnum_tobytes(arch, flt, buf, destsize, valsize, shift, \
|
||||
warn) \
|
||||
((yasm_arch_base *)arch)->module->floatnum_tobytes \
|
||||
(arch, flt, buf, destsize, valsize, shift, warn)
|
||||
#define yasm_arch_intnum_tobytes(arch, intn, buf, destsize, valsize, shift, \
|
||||
bc, warn) \
|
||||
((yasm_arch_base *)arch)->module->intnum_tobytes \
|
||||
(arch, intn, buf, destsize, valsize, shift, bc, warn)
|
||||
#define yasm_arch_get_reg_size(arch, reg) \
|
||||
((yasm_arch_base *)arch)->module->get_reg_size(arch, reg)
|
||||
#define yasm_arch_reggroup_get_reg(arch, regg, regi) \
|
||||
((yasm_arch_base *)arch)->module->reggroup_get_reg(arch, regg, regi)
|
||||
#define yasm_arch_reg_print(arch, reg, f) \
|
||||
((yasm_arch_base *)arch)->module->reg_print(arch, reg, f)
|
||||
#define yasm_arch_segreg_print(arch, segreg, f) \
|
||||
((yasm_arch_base *)arch)->module->segreg_print(arch, segreg, f)
|
||||
#define yasm_arch_ea_create(arch, e) \
|
||||
((yasm_arch_base *)arch)->module->ea_create(arch, e)
|
||||
#define yasm_arch_ea_destroy(arch, ea) \
|
||||
((yasm_arch_base *)arch)->module->ea_destroy(ea)
|
||||
#define yasm_arch_ea_print(arch, ea, f, i) \
|
||||
((yasm_arch_base *)arch)->module->ea_print(ea, f, i)
|
||||
#define yasm_arch_create_empty_insn(arch, line) \
|
||||
((yasm_arch_base *)arch)->module->create_empty_insn(arch, line)
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@ -0,0 +1,76 @@
|
||||
/**
|
||||
* \file assocdat.h
|
||||
* \brief YASM associated data storage (libyasm internal use)
|
||||
*
|
||||
* \license
|
||||
* Copyright (C) 2003-2007 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
|
||||
|
||||
#ifndef YASM_LIB_DECL
|
||||
#define YASM_LIB_DECL
|
||||
#endif
|
||||
|
||||
/** Associated data container. */
|
||||
typedef struct yasm__assoc_data yasm__assoc_data;
|
||||
|
||||
/** Create an associated data container. */
|
||||
YASM_LIB_DECL
|
||||
/*@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).
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
/*@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
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
/*@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. */
|
||||
YASM_LIB_DECL
|
||||
void yasm__assoc_data_destroy
|
||||
(/*@null@*/ /*@only@*/ yasm__assoc_data *assoc_data);
|
||||
|
||||
/** Print all associated data in a container. */
|
||||
YASM_LIB_DECL
|
||||
void yasm__assoc_data_print(const yasm__assoc_data *assoc_data, FILE *f,
|
||||
int indent_level);
|
||||
|
||||
#endif
|
||||
@ -0,0 +1,666 @@
|
||||
#ifndef YASM_BITVECT_H
|
||||
#define YASM_BITVECT_H
|
||||
/*****************************************************************************/
|
||||
/* MODULE NAME: BitVector.h MODULE TYPE: (adt) */
|
||||
/*****************************************************************************/
|
||||
/* MODULE IMPORTS: */
|
||||
/*****************************************************************************/
|
||||
|
||||
/* ToolBox.h */
|
||||
/*****************************************************************************/
|
||||
/* NOTE: The type names that have been chosen here are somewhat weird on */
|
||||
/* purpose, in order to avoid name clashes with system header files */
|
||||
/* and your own application(s) which might - directly or indirectly - */
|
||||
/* include this definitions file. */
|
||||
/*****************************************************************************/
|
||||
#ifndef YASM_LIB_DECL
|
||||
#define YASM_LIB_DECL
|
||||
#endif
|
||||
|
||||
typedef unsigned char N_char;
|
||||
typedef unsigned char N_byte;
|
||||
typedef unsigned short N_short;
|
||||
typedef unsigned short N_shortword;
|
||||
typedef unsigned int N_int;
|
||||
typedef unsigned int N_word;
|
||||
typedef unsigned long N_long;
|
||||
typedef unsigned long N_longword;
|
||||
|
||||
/* Mnemonic 1: The natural numbers, N = { 0, 1, 2, 3, ... } */
|
||||
/* Mnemonic 2: Nnnn = u_N_signed, _N_ot signed */
|
||||
|
||||
typedef signed char Z_char;
|
||||
typedef signed char Z_byte;
|
||||
typedef signed short Z_short;
|
||||
typedef signed short Z_shortword;
|
||||
typedef signed int Z_int;
|
||||
typedef signed int Z_word;
|
||||
typedef signed long Z_long;
|
||||
typedef signed long Z_longword;
|
||||
|
||||
/* Mnemonic 1: The whole numbers, Z = { 0, -1, 1, -2, 2, -3, 3, ... } */
|
||||
/* Mnemonic 2: Zzzz = Ssss_igned */
|
||||
|
||||
typedef void *voidptr;
|
||||
typedef N_char *charptr;
|
||||
typedef N_byte *byteptr;
|
||||
typedef N_short *shortptr;
|
||||
typedef N_shortword *shortwordptr;
|
||||
typedef N_int *intptr;
|
||||
typedef N_word *wordptr;
|
||||
typedef N_long *longptr;
|
||||
typedef N_longword *longwordptr;
|
||||
|
||||
typedef N_char *N_charptr;
|
||||
typedef N_byte *N_byteptr;
|
||||
typedef N_short *N_shortptr;
|
||||
typedef N_shortword *N_shortwordptr;
|
||||
typedef N_int *N_intptr;
|
||||
typedef N_word *N_wordptr;
|
||||
typedef N_long *N_longptr;
|
||||
typedef N_longword *N_longwordptr;
|
||||
|
||||
typedef Z_char *Z_charptr;
|
||||
typedef Z_byte *Z_byteptr;
|
||||
typedef Z_short *Z_shortptr;
|
||||
typedef Z_shortword *Z_shortwordptr;
|
||||
typedef Z_int *Z_intptr;
|
||||
typedef Z_word *Z_wordptr;
|
||||
typedef Z_long *Z_longptr;
|
||||
typedef Z_longword *Z_longwordptr;
|
||||
|
||||
#ifndef FALSE
|
||||
#define FALSE (0!=0)
|
||||
#endif
|
||||
|
||||
#ifndef TRUE
|
||||
#define TRUE (0==0)
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
typedef bool boolean;
|
||||
#else
|
||||
#ifdef MACOS_TRADITIONAL
|
||||
#define boolean Boolean
|
||||
#else
|
||||
typedef enum boolean { false = FALSE, true = TRUE } boolean;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*****************************************************************************/
|
||||
/* MODULE INTERFACE: */
|
||||
/*****************************************************************************/
|
||||
|
||||
typedef enum ErrCode
|
||||
{
|
||||
ErrCode_Ok = 0, /* everything went allright */
|
||||
|
||||
ErrCode_Type, /* types word and size_t have incompatible sizes */
|
||||
ErrCode_Bits, /* bits of word and sizeof(word) are inconsistent */
|
||||
ErrCode_Word, /* size of word is less than 16 bits */
|
||||
ErrCode_Long, /* size of word is greater than size of long */
|
||||
ErrCode_Powr, /* number of bits of word is not a power of two */
|
||||
ErrCode_Loga, /* error in calculation of logarithm */
|
||||
|
||||
ErrCode_Null, /* unable to allocate memory */
|
||||
|
||||
ErrCode_Indx, /* index out of range */
|
||||
ErrCode_Ordr, /* minimum > maximum index */
|
||||
ErrCode_Size, /* bit vector size mismatch */
|
||||
ErrCode_Pars, /* input string syntax error */
|
||||
ErrCode_Ovfl, /* numeric overflow error */
|
||||
ErrCode_Same, /* operands must be distinct */
|
||||
ErrCode_Expo, /* exponent must be positive */
|
||||
ErrCode_Zero /* division by zero error */
|
||||
} ErrCode;
|
||||
|
||||
typedef wordptr *listptr;
|
||||
|
||||
/* ===> MISCELLANEOUS BASIC FUNCTIONS: <=== */
|
||||
|
||||
YASM_LIB_DECL
|
||||
const char * BitVector_Error (ErrCode error); /* return string for err code */
|
||||
|
||||
YASM_LIB_DECL
|
||||
ErrCode BitVector_Boot (void); /* 0 = ok, 1..7 = error */
|
||||
YASM_LIB_DECL
|
||||
void BitVector_Shutdown (void); /* undo Boot */
|
||||
|
||||
YASM_LIB_DECL
|
||||
N_word BitVector_Size (N_int bits); /* bit vector size (# of words) */
|
||||
YASM_LIB_DECL
|
||||
N_word BitVector_Mask (N_int bits); /* bit vector mask (unused bits) */
|
||||
|
||||
/* ===> CLASS METHODS: <=== */
|
||||
|
||||
YASM_LIB_DECL
|
||||
const char * BitVector_Version (void); /* returns version string */
|
||||
|
||||
YASM_LIB_DECL
|
||||
N_int BitVector_Word_Bits (void); /* return # of bits in machine word */
|
||||
YASM_LIB_DECL
|
||||
N_int BitVector_Long_Bits (void); /* return # of bits in unsigned long */
|
||||
|
||||
/* ===> CONSTRUCTOR METHODS: <=== */
|
||||
|
||||
YASM_LIB_DECL
|
||||
/*@only@*/ wordptr BitVector_Create (N_int bits, boolean clear); /* malloc */
|
||||
YASM_LIB_DECL
|
||||
listptr BitVector_Create_List(N_int bits, boolean clear, N_int count);
|
||||
|
||||
YASM_LIB_DECL
|
||||
wordptr BitVector_Resize (wordptr oldaddr, N_int bits); /* realloc */
|
||||
|
||||
YASM_LIB_DECL
|
||||
wordptr BitVector_Shadow (wordptr addr); /* make new same size but empty */
|
||||
YASM_LIB_DECL
|
||||
wordptr BitVector_Clone (wordptr addr); /* make exact duplicate */
|
||||
|
||||
YASM_LIB_DECL
|
||||
wordptr BitVector_Concat (wordptr X, wordptr Y); /* return concatenation */
|
||||
|
||||
/* ===> DESTRUCTOR METHODS: <=== */
|
||||
|
||||
YASM_LIB_DECL
|
||||
void BitVector_Dispose (/*@only@*/ /*@out@*/ charptr string); /* string */
|
||||
YASM_LIB_DECL
|
||||
void BitVector_Destroy (/*@only@*/ wordptr addr); /* bitvec */
|
||||
YASM_LIB_DECL
|
||||
void BitVector_Destroy_List (listptr list, N_int count); /* list */
|
||||
|
||||
/* ===> OBJECT METHODS: <=== */
|
||||
|
||||
/* ===> bit vector copy function: */
|
||||
|
||||
YASM_LIB_DECL
|
||||
void BitVector_Copy (wordptr X, wordptr Y); /* X = Y */
|
||||
|
||||
/* ===> bit vector initialization: */
|
||||
|
||||
YASM_LIB_DECL
|
||||
void BitVector_Empty (wordptr addr); /* X = {} */
|
||||
YASM_LIB_DECL
|
||||
void BitVector_Fill (wordptr addr); /* X = ~{} */
|
||||
YASM_LIB_DECL
|
||||
void BitVector_Flip (wordptr addr); /* X = ~X */
|
||||
|
||||
YASM_LIB_DECL
|
||||
void BitVector_Primes (wordptr addr);
|
||||
|
||||
/* ===> miscellaneous functions: */
|
||||
|
||||
YASM_LIB_DECL
|
||||
void BitVector_Reverse (wordptr X, wordptr Y);
|
||||
|
||||
/* ===> bit vector interval operations and functions: */
|
||||
|
||||
YASM_LIB_DECL
|
||||
void BitVector_Interval_Empty (/*@out@*/ wordptr addr, N_int lower, N_int upper);
|
||||
YASM_LIB_DECL
|
||||
void BitVector_Interval_Fill (/*@out@*/ wordptr addr, N_int lower, N_int upper);
|
||||
YASM_LIB_DECL
|
||||
void BitVector_Interval_Flip (/*@out@*/ wordptr addr, N_int lower, N_int upper);
|
||||
YASM_LIB_DECL
|
||||
void BitVector_Interval_Reverse (/*@out@*/ wordptr addr, N_int lower, N_int upper);
|
||||
|
||||
YASM_LIB_DECL
|
||||
boolean BitVector_interval_scan_inc (wordptr addr, N_int start,
|
||||
N_intptr min, N_intptr max);
|
||||
YASM_LIB_DECL
|
||||
boolean BitVector_interval_scan_dec (wordptr addr, N_int start,
|
||||
N_intptr min, N_intptr max);
|
||||
|
||||
YASM_LIB_DECL
|
||||
void BitVector_Interval_Copy (/*@out@*/ wordptr X, wordptr Y, N_int Xoffset,
|
||||
N_int Yoffset, N_int length);
|
||||
|
||||
YASM_LIB_DECL
|
||||
wordptr BitVector_Interval_Substitute(/*@out@*/ wordptr X, wordptr Y,
|
||||
N_int Xoffset, N_int Xlength,
|
||||
N_int Yoffset, N_int Ylength);
|
||||
|
||||
/* ===> bit vector test functions: */
|
||||
|
||||
YASM_LIB_DECL
|
||||
boolean BitVector_is_empty (wordptr addr); /* X == {} ? */
|
||||
YASM_LIB_DECL
|
||||
boolean BitVector_is_full (wordptr addr); /* X == ~{} ? */
|
||||
|
||||
YASM_LIB_DECL
|
||||
boolean BitVector_equal (wordptr X, wordptr Y); /* X == Y ? */
|
||||
YASM_LIB_DECL
|
||||
Z_int BitVector_Lexicompare(wordptr X, wordptr Y); /* X <,=,> Y ? */
|
||||
YASM_LIB_DECL
|
||||
Z_int BitVector_Compare (wordptr X, wordptr Y); /* X <,=,> Y ? */
|
||||
|
||||
/* ===> bit vector string conversion functions: */
|
||||
|
||||
YASM_LIB_DECL
|
||||
/*@only@*/ charptr BitVector_to_Hex (wordptr addr);
|
||||
YASM_LIB_DECL
|
||||
ErrCode BitVector_from_Hex (/*@out@*/wordptr addr, charptr string);
|
||||
|
||||
YASM_LIB_DECL
|
||||
ErrCode BitVector_from_Oct(/*@out@*/ wordptr addr, charptr string);
|
||||
|
||||
YASM_LIB_DECL
|
||||
/*@only@*/ charptr BitVector_to_Bin (wordptr addr);
|
||||
YASM_LIB_DECL
|
||||
ErrCode BitVector_from_Bin (/*@out@*/ wordptr addr, charptr string);
|
||||
|
||||
YASM_LIB_DECL
|
||||
/*@only@*/ charptr BitVector_to_Dec (wordptr addr);
|
||||
YASM_LIB_DECL
|
||||
ErrCode BitVector_from_Dec (/*@out@*/ wordptr addr, charptr string);
|
||||
|
||||
typedef struct BitVector_from_Dec_static_data BitVector_from_Dec_static_data;
|
||||
YASM_LIB_DECL
|
||||
BitVector_from_Dec_static_data *BitVector_from_Dec_static_Boot(N_word bits);
|
||||
YASM_LIB_DECL
|
||||
void BitVector_from_Dec_static_Shutdown(/*@null@*/ BitVector_from_Dec_static_data *data);
|
||||
YASM_LIB_DECL
|
||||
ErrCode BitVector_from_Dec_static(BitVector_from_Dec_static_data *data,
|
||||
/*@out@*/ wordptr addr, charptr string);
|
||||
|
||||
YASM_LIB_DECL
|
||||
/*@only@*/ charptr BitVector_to_Enum (wordptr addr);
|
||||
YASM_LIB_DECL
|
||||
ErrCode BitVector_from_Enum (/*@out@*/ wordptr addr, charptr string);
|
||||
|
||||
/* ===> bit vector bit operations, functions & tests: */
|
||||
|
||||
YASM_LIB_DECL
|
||||
void BitVector_Bit_Off (/*@out@*/ wordptr addr, N_int indx); /* X = X \ {x} */
|
||||
YASM_LIB_DECL
|
||||
void BitVector_Bit_On (/*@out@*/ wordptr addr, N_int indx); /* X = X + {x} */
|
||||
YASM_LIB_DECL
|
||||
boolean BitVector_bit_flip (/*@out@*/ wordptr addr, N_int indx); /* (X+{x})\(X*{x}) */
|
||||
|
||||
YASM_LIB_DECL
|
||||
boolean BitVector_bit_test (wordptr addr, N_int indx); /* {x} in X ? */
|
||||
|
||||
YASM_LIB_DECL
|
||||
void BitVector_Bit_Copy (/*@out@*/ wordptr addr, N_int indx, boolean bit);
|
||||
|
||||
/* ===> bit vector bit shift & rotate functions: */
|
||||
|
||||
YASM_LIB_DECL
|
||||
void BitVector_LSB (/*@out@*/ wordptr addr, boolean bit);
|
||||
YASM_LIB_DECL
|
||||
void BitVector_MSB (/*@out@*/ wordptr addr, boolean bit);
|
||||
YASM_LIB_DECL
|
||||
boolean BitVector_lsb_ (wordptr addr);
|
||||
YASM_LIB_DECL
|
||||
boolean BitVector_msb_ (wordptr addr);
|
||||
YASM_LIB_DECL
|
||||
boolean /*@alt void@*/ BitVector_rotate_left (wordptr addr);
|
||||
YASM_LIB_DECL
|
||||
boolean /*@alt void@*/ BitVector_rotate_right (wordptr addr);
|
||||
YASM_LIB_DECL
|
||||
boolean /*@alt void@*/ BitVector_shift_left (wordptr addr, boolean carry_in);
|
||||
YASM_LIB_DECL
|
||||
boolean /*@alt void@*/ BitVector_shift_right (wordptr addr, boolean carry_in);
|
||||
YASM_LIB_DECL
|
||||
void BitVector_Move_Left (wordptr addr, N_int bits);
|
||||
YASM_LIB_DECL
|
||||
void BitVector_Move_Right (wordptr addr, N_int bits);
|
||||
|
||||
/* ===> bit vector insert/delete bits: */
|
||||
|
||||
YASM_LIB_DECL
|
||||
void BitVector_Insert (wordptr addr, N_int offset, N_int count,
|
||||
boolean clear);
|
||||
YASM_LIB_DECL
|
||||
void BitVector_Delete (wordptr addr, N_int offset, N_int count,
|
||||
boolean clear);
|
||||
|
||||
/* ===> bit vector arithmetic: */
|
||||
|
||||
YASM_LIB_DECL
|
||||
boolean /*@alt void@*/ BitVector_increment (wordptr addr); /* X++ */
|
||||
YASM_LIB_DECL
|
||||
boolean /*@alt void@*/ BitVector_decrement (wordptr addr); /* X-- */
|
||||
|
||||
YASM_LIB_DECL
|
||||
boolean /*@alt void@*/ BitVector_compute (wordptr X, wordptr Y, wordptr Z, boolean minus,
|
||||
boolean *carry);
|
||||
YASM_LIB_DECL
|
||||
boolean /*@alt void@*/ BitVector_add (wordptr X, wordptr Y, wordptr Z, boolean *carry);
|
||||
YASM_LIB_DECL
|
||||
boolean /*@alt void@*/ BitVector_sub (wordptr X, wordptr Y, wordptr Z, boolean *carry);
|
||||
YASM_LIB_DECL
|
||||
boolean /*@alt void@*/ BitVector_inc (wordptr X, wordptr Y);
|
||||
YASM_LIB_DECL
|
||||
boolean /*@alt void@*/ BitVector_dec (wordptr X, wordptr Y);
|
||||
|
||||
YASM_LIB_DECL
|
||||
void BitVector_Negate (wordptr X, wordptr Y);
|
||||
YASM_LIB_DECL
|
||||
void BitVector_Absolute (wordptr X, wordptr Y);
|
||||
YASM_LIB_DECL
|
||||
Z_int BitVector_Sign (wordptr addr);
|
||||
YASM_LIB_DECL
|
||||
ErrCode BitVector_Mul_Pos (wordptr X, wordptr Y, wordptr Z, boolean strict);
|
||||
YASM_LIB_DECL
|
||||
ErrCode BitVector_Multiply (wordptr X, wordptr Y, wordptr Z);
|
||||
YASM_LIB_DECL
|
||||
ErrCode BitVector_Div_Pos (wordptr Q, wordptr X, wordptr Y, wordptr R);
|
||||
YASM_LIB_DECL
|
||||
ErrCode BitVector_Divide (wordptr Q, wordptr X, wordptr Y, wordptr R);
|
||||
YASM_LIB_DECL
|
||||
ErrCode BitVector_GCD (wordptr X, wordptr Y, wordptr Z);
|
||||
YASM_LIB_DECL
|
||||
ErrCode BitVector_GCD2 (wordptr U, wordptr V, wordptr W, /* O */
|
||||
wordptr X, wordptr Y); /* I */
|
||||
YASM_LIB_DECL
|
||||
ErrCode BitVector_Power (wordptr X, wordptr Y, wordptr Z);
|
||||
|
||||
/* ===> direct memory access functions: */
|
||||
|
||||
YASM_LIB_DECL
|
||||
void BitVector_Block_Store(wordptr addr, charptr buffer, N_int length);
|
||||
YASM_LIB_DECL
|
||||
charptr BitVector_Block_Read (wordptr addr, /*@out@*/ N_intptr length);
|
||||
|
||||
/* ===> word array functions: */
|
||||
|
||||
YASM_LIB_DECL
|
||||
void BitVector_Word_Store (wordptr addr, N_int offset, N_int value);
|
||||
YASM_LIB_DECL
|
||||
N_int BitVector_Word_Read (wordptr addr, N_int offset);
|
||||
|
||||
YASM_LIB_DECL
|
||||
void BitVector_Word_Insert(wordptr addr, N_int offset, N_int count,
|
||||
boolean clear);
|
||||
YASM_LIB_DECL
|
||||
void BitVector_Word_Delete(wordptr addr, N_int offset, N_int count,
|
||||
boolean clear);
|
||||
|
||||
/* ===> arbitrary size chunk functions: */
|
||||
|
||||
YASM_LIB_DECL
|
||||
void BitVector_Chunk_Store(wordptr addr, N_int chunksize,
|
||||
N_int offset, N_long value);
|
||||
YASM_LIB_DECL
|
||||
N_long BitVector_Chunk_Read (wordptr addr, N_int chunksize,
|
||||
N_int offset);
|
||||
|
||||
/* ===> set operations: */
|
||||
|
||||
YASM_LIB_DECL
|
||||
void Set_Union (wordptr X, wordptr Y, wordptr Z); /* X = Y + Z */
|
||||
YASM_LIB_DECL
|
||||
void Set_Intersection (wordptr X, wordptr Y, wordptr Z); /* X = Y * Z */
|
||||
YASM_LIB_DECL
|
||||
void Set_Difference (wordptr X, wordptr Y, wordptr Z); /* X = Y \ Z */
|
||||
YASM_LIB_DECL
|
||||
void Set_ExclusiveOr (wordptr X, wordptr Y, wordptr Z); /*(Y+Z)\(Y*Z)*/
|
||||
YASM_LIB_DECL
|
||||
void Set_Complement (wordptr X, wordptr Y); /* X = ~Y */
|
||||
|
||||
/* ===> set functions: */
|
||||
|
||||
YASM_LIB_DECL
|
||||
boolean Set_subset (wordptr X, wordptr Y); /* X in Y ? */
|
||||
|
||||
YASM_LIB_DECL
|
||||
N_int Set_Norm (wordptr addr); /* = | X | */
|
||||
YASM_LIB_DECL
|
||||
N_int Set_Norm2 (wordptr addr); /* = | X | */
|
||||
YASM_LIB_DECL
|
||||
N_int Set_Norm3 (wordptr addr); /* = | X | */
|
||||
YASM_LIB_DECL
|
||||
Z_long Set_Min (wordptr addr); /* = min(X) */
|
||||
YASM_LIB_DECL
|
||||
Z_long Set_Max (wordptr addr); /* = max(X) */
|
||||
|
||||
/* ===> matrix-of-booleans operations: */
|
||||
|
||||
YASM_LIB_DECL
|
||||
void Matrix_Multiplication(wordptr X, N_int rowsX, N_int colsX,
|
||||
wordptr Y, N_int rowsY, N_int colsY,
|
||||
wordptr Z, N_int rowsZ, N_int colsZ);
|
||||
|
||||
YASM_LIB_DECL
|
||||
void Matrix_Product (wordptr X, N_int rowsX, N_int colsX,
|
||||
wordptr Y, N_int rowsY, N_int colsY,
|
||||
wordptr Z, N_int rowsZ, N_int colsZ);
|
||||
|
||||
YASM_LIB_DECL
|
||||
void Matrix_Closure (wordptr addr, N_int rows, N_int cols);
|
||||
|
||||
YASM_LIB_DECL
|
||||
void Matrix_Transpose (wordptr X, N_int rowsX, N_int colsX,
|
||||
wordptr Y, N_int rowsY, N_int colsY);
|
||||
|
||||
/*****************************************************************************/
|
||||
/* VERSION: 6.4 */
|
||||
/*****************************************************************************/
|
||||
/* VERSION HISTORY: */
|
||||
/*****************************************************************************/
|
||||
/* */
|
||||
/* Version 6.4 03.10.04 Added C++ comp. directives. Improved "Norm()". */
|
||||
/* Version 6.3 28.09.02 Added "Create_List()" and "GCD2()". */
|
||||
/* Version 6.2 15.09.02 Overhauled error handling. Fixed "GCD()". */
|
||||
/* Version 6.1 08.10.01 Make VMS linker happy: _lsb,_msb => _lsb_,_msb_ */
|
||||
/* Version 6.0 08.10.00 Corrected overflow handling. */
|
||||
/* Version 5.8 14.07.00 Added "Power()". Changed "Copy()". */
|
||||
/* Version 5.7 19.05.99 Quickened "Div_Pos()". Added "Product()". */
|
||||
/* Version 5.6 02.11.98 Leading zeros eliminated in "to_Hex()". */
|
||||
/* Version 5.5 21.09.98 Fixed bug of uninitialized "error" in Multiply. */
|
||||
/* Version 5.4 07.09.98 Fixed bug of uninitialized "error" in Divide. */
|
||||
/* Version 5.3 12.05.98 Improved Norm. Completed history. */
|
||||
/* Version 5.2 31.03.98 Improved Norm. */
|
||||
/* Version 5.1 09.03.98 No changes. */
|
||||
/* Version 5.0 01.03.98 Major additions and rewrite. */
|
||||
/* Version 4.2 16.07.97 Added is_empty, is_full. */
|
||||
/* Version 4.1 30.06.97 Added word-ins/del, move-left/right, inc/dec. */
|
||||
/* Version 4.0 23.04.97 Rewrite. Added bit shift and bool. matrix ops. */
|
||||
/* Version 3.2 04.02.97 Added interval methods. */
|
||||
/* Version 3.1 21.01.97 Fixed bug on 64 bit machines. */
|
||||
/* Version 3.0 12.01.97 Added flip. */
|
||||
/* Version 2.0 14.12.96 Efficiency and consistency improvements. */
|
||||
/* Version 1.1 08.01.96 Added Resize and ExclusiveOr. */
|
||||
/* Version 1.0 14.12.95 First version under UNIX (with Perl module). */
|
||||
/* Version 0.9 01.11.93 First version of C library under MS-DOS. */
|
||||
/* Version 0.1 ??.??.89 First version in Turbo Pascal under CP/M. */
|
||||
/* */
|
||||
/*****************************************************************************/
|
||||
/* AUTHOR: */
|
||||
/*****************************************************************************/
|
||||
/* */
|
||||
/* Steffen Beyer */
|
||||
/* mailto:sb@engelschall.com */
|
||||
/* http://www.engelschall.com/u/sb/download/ */
|
||||
/* */
|
||||
/*****************************************************************************/
|
||||
/* COPYRIGHT: */
|
||||
/*****************************************************************************/
|
||||
/* */
|
||||
/* Copyright (c) 1995 - 2004 by Steffen Beyer. */
|
||||
/* All rights reserved. */
|
||||
/* */
|
||||
/*****************************************************************************/
|
||||
/* LICENSE: */
|
||||
/*****************************************************************************/
|
||||
/* This package is free software; you can use, modify and redistribute */
|
||||
/* it under the same terms as Perl itself, i.e., under the terms of */
|
||||
/* the "Artistic License" or the "GNU General Public License". */
|
||||
/* */
|
||||
/* The C library at the core of this Perl module can additionally */
|
||||
/* be used, modified and redistributed under the terms of the */
|
||||
/* "GNU Library General Public License". */
|
||||
/* */
|
||||
/*****************************************************************************/
|
||||
/* ARTISTIC LICENSE: */
|
||||
/*****************************************************************************/
|
||||
/*
|
||||
The "Artistic License"
|
||||
|
||||
Preamble
|
||||
|
||||
The intent of this document is to state the conditions under which a
|
||||
Package may be copied, such that the Copyright Holder maintains some
|
||||
semblance of artistic control over the development of the package,
|
||||
while giving the users of the package the right to use and distribute
|
||||
the Package in a more-or-less customary fashion, plus the right to make
|
||||
reasonable modifications.
|
||||
|
||||
Definitions:
|
||||
|
||||
"Package" refers to the collection of files distributed by the
|
||||
Copyright Holder, and derivatives of that collection of files
|
||||
created through textual modification.
|
||||
|
||||
"Standard Version" refers to such a Package if it has not been
|
||||
modified, or has been modified in accordance with the wishes
|
||||
of the Copyright Holder as specified below.
|
||||
|
||||
"Copyright Holder" is whoever is named in the copyright or
|
||||
copyrights for the package.
|
||||
|
||||
"You" is you, if you're thinking about copying or distributing
|
||||
this Package.
|
||||
|
||||
"Reasonable copying fee" is whatever you can justify on the
|
||||
basis of media cost, duplication charges, time of people involved,
|
||||
and so on. (You will not be required to justify it to the
|
||||
Copyright Holder, but only to the computing community at large
|
||||
as a market that must bear the fee.)
|
||||
|
||||
"Freely Available" means that no fee is charged for the item
|
||||
itself, though there may be fees involved in handling the item.
|
||||
It also means that recipients of the item may redistribute it
|
||||
under the same conditions they received it.
|
||||
|
||||
1. You may make and give away verbatim copies of the source form of the
|
||||
Standard Version of this Package without restriction, provided that you
|
||||
duplicate all of the original copyright notices and associated disclaimers.
|
||||
|
||||
2. You may apply bug fixes, portability fixes and other modifications
|
||||
derived from the Public Domain or from the Copyright Holder. A Package
|
||||
modified in such a way shall still be considered the Standard Version.
|
||||
|
||||
3. You may otherwise modify your copy of this Package in any way, provided
|
||||
that you insert a prominent notice in each changed file stating how and
|
||||
when you changed that file, and provided that you do at least ONE of the
|
||||
following:
|
||||
|
||||
a) place your modifications in the Public Domain or otherwise make them
|
||||
Freely Available, such as by posting said modifications to Usenet or
|
||||
an equivalent medium, or placing the modifications on a major archive
|
||||
site such as uunet.uu.net, or by allowing the Copyright Holder to include
|
||||
your modifications in the Standard Version of the Package.
|
||||
|
||||
b) use the modified Package only within your corporation or organization.
|
||||
|
||||
c) rename any non-standard executables so the names do not conflict
|
||||
with standard executables, which must also be provided, and provide
|
||||
a separate manual page for each non-standard executable that clearly
|
||||
documents how it differs from the Standard Version.
|
||||
|
||||
d) make other distribution arrangements with the Copyright Holder.
|
||||
|
||||
4. You may distribute the programs of this Package in object code or
|
||||
executable form, provided that you do at least ONE of the following:
|
||||
|
||||
a) distribute a Standard Version of the executables and library files,
|
||||
together with instructions (in the manual page or equivalent) on where
|
||||
to get the Standard Version.
|
||||
|
||||
b) accompany the distribution with the machine-readable source of
|
||||
the Package with your modifications.
|
||||
|
||||
c) give non-standard executables non-standard names, and clearly
|
||||
document the differences in manual pages (or equivalent), together
|
||||
with instructions on where to get the Standard Version.
|
||||
|
||||
d) make other distribution arrangements with the Copyright Holder.
|
||||
|
||||
5. You may charge a reasonable copying fee for any distribution of this
|
||||
Package. You may charge any fee you choose for support of this
|
||||
Package. You may not charge a fee for this Package itself. However,
|
||||
you may distribute this Package in aggregate with other (possibly
|
||||
commercial) programs as part of a larger (possibly commercial) software
|
||||
distribution provided that you do not advertise this Package as a
|
||||
product of your own. You may embed this Package's interpreter within
|
||||
an executable of yours (by linking); this shall be construed as a mere
|
||||
form of aggregation, provided that the complete Standard Version of the
|
||||
interpreter is so embedded.
|
||||
|
||||
6. The scripts and library files supplied as input to or produced as
|
||||
output from the programs of this Package do not automatically fall
|
||||
under the copyright of this Package, but belong to whoever generated
|
||||
them, and may be sold commercially, and may be aggregated with this
|
||||
Package. If such scripts or library files are aggregated with this
|
||||
Package via the so-called "undump" or "unexec" methods of producing a
|
||||
binary executable image, then distribution of such an image shall
|
||||
neither be construed as a distribution of this Package nor shall it
|
||||
fall under the restrictions of Paragraphs 3 and 4, provided that you do
|
||||
not represent such an executable image as a Standard Version of this
|
||||
Package.
|
||||
|
||||
7. C subroutines (or comparably compiled subroutines in other
|
||||
languages) supplied by you and linked into this Package in order to
|
||||
emulate subroutines and variables of the language defined by this
|
||||
Package shall not be considered part of this Package, but are the
|
||||
equivalent of input as in Paragraph 6, provided these subroutines do
|
||||
not change the language in any way that would cause it to fail the
|
||||
regression tests for the language.
|
||||
|
||||
8. Aggregation of this Package with a commercial distribution is always
|
||||
permitted provided that the use of this Package is embedded; that is,
|
||||
when no overt attempt is made to make this Package's interfaces visible
|
||||
to the end user of the commercial distribution. Such use shall not be
|
||||
construed as a distribution of this Package.
|
||||
|
||||
9. The name of the Copyright Holder may not be used to endorse or promote
|
||||
products derived from this software without specific prior written permission.
|
||||
|
||||
10. THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR
|
||||
IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
The End
|
||||
*/
|
||||
/*****************************************************************************/
|
||||
/* GNU GENERAL PUBLIC LICENSE: */
|
||||
/*****************************************************************************/
|
||||
/* This program is free software; you can redistribute it and/or */
|
||||
/* modify it under the terms of the GNU General Public License */
|
||||
/* as published by the Free Software Foundation; either version 2 */
|
||||
/* of the License, or (at your option) any later version. */
|
||||
/* */
|
||||
/* This program is distributed in the hope that it will be useful, */
|
||||
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
|
||||
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
|
||||
/* GNU General Public License for more details. */
|
||||
/* */
|
||||
/* You should have received a copy of the GNU General Public License */
|
||||
/* along with this program; if not, write to the */
|
||||
/* Free Software Foundation, Inc., */
|
||||
/* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
/* */
|
||||
/*****************************************************************************/
|
||||
/* GNU LIBRARY GENERAL PUBLIC LICENSE: */
|
||||
/*****************************************************************************/
|
||||
/* */
|
||||
/* This library is free software; you can redistribute it and/or */
|
||||
/* modify it under the terms of the GNU Library General Public */
|
||||
/* License as published by the Free Software Foundation; either */
|
||||
/* version 2 of the License, or (at your option) any later version. */
|
||||
/* */
|
||||
/* This library is distributed in the hope that it will be useful, */
|
||||
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
|
||||
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */
|
||||
/* Library General Public License for more details. */
|
||||
/* */
|
||||
/* You should have received a copy of the GNU Library General Public */
|
||||
/* License along with this library; if not, write to the */
|
||||
/* Free Software Foundation, Inc., */
|
||||
/* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
/* */
|
||||
/* or download a copy from ftp://ftp.gnu.org/pub/gnu/COPYING.LIB-2.0 */
|
||||
/* */
|
||||
/*****************************************************************************/
|
||||
#endif
|
||||
@ -0,0 +1,638 @@
|
||||
/**
|
||||
* \file libyasm/bytecode.h
|
||||
* \brief YASM bytecode interface.
|
||||
*
|
||||
* \license
|
||||
* Copyright (C) 2001-2007 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_BYTECODE_H
|
||||
#define YASM_BYTECODE_H
|
||||
|
||||
#ifndef YASM_LIB_DECL
|
||||
#define YASM_LIB_DECL
|
||||
#endif
|
||||
|
||||
/** A data value (opaque type). */
|
||||
typedef struct yasm_dataval yasm_dataval;
|
||||
/** A list of data values. */
|
||||
typedef struct yasm_datavalhead yasm_datavalhead;
|
||||
|
||||
/** Linked list of data values. */
|
||||
/*@reldef@*/ STAILQ_HEAD(yasm_datavalhead, yasm_dataval);
|
||||
|
||||
/** Add a dependent span for a bytecode.
|
||||
* \param add_span_data add_span_data passed into bc_calc_len()
|
||||
* \param bc bytecode containing span
|
||||
* \param id non-zero identifier for span; may be any non-zero value
|
||||
* if <0, expand is called for any change;
|
||||
* if >0, expand is only called when exceeds threshold
|
||||
* \param value dependent value for bytecode expansion
|
||||
* \param neg_thres negative threshold for long/short decision
|
||||
* \param pos_thres positive threshold for long/short decision
|
||||
*/
|
||||
typedef void (*yasm_bc_add_span_func)
|
||||
(void *add_span_data, yasm_bytecode *bc, int id, const yasm_value *value,
|
||||
long neg_thres, long pos_thres);
|
||||
|
||||
/** Bytecode callback structure. Any implementation of a specific bytecode
|
||||
* must implement these functions and this callback structure. The bytecode
|
||||
* implementation-specific data is stored in #yasm_bytecode.contents.
|
||||
*/
|
||||
typedef struct yasm_bytecode_callback {
|
||||
/** Destroys the implementation-specific data.
|
||||
* Called from yasm_bc_destroy().
|
||||
* \param contents #yasm_bytecode.contents
|
||||
*/
|
||||
void (*destroy) (/*@only@*/ void *contents);
|
||||
|
||||
/** Prints the implementation-specific data (for debugging purposes).
|
||||
* Called from yasm_bc_print().
|
||||
* \param contents #yasm_bytecode.contents
|
||||
* \param f file
|
||||
* \param indent_level indentation level
|
||||
*/
|
||||
void (*print) (const void *contents, FILE *f, int indent_level);
|
||||
|
||||
/** Finalizes the bytecode after parsing. Called from yasm_bc_finalize().
|
||||
* A generic fill-in for this is yasm_bc_finalize_common().
|
||||
* \param bc bytecode
|
||||
* \param prev_bc bytecode directly preceding bc
|
||||
*/
|
||||
void (*finalize) (yasm_bytecode *bc, yasm_bytecode *prev_bc);
|
||||
|
||||
/** Return elements size of a data bytecode.
|
||||
* This function should return the size of each elements of a data
|
||||
* bytecode, for proper dereference of symbols attached to it.
|
||||
* \param bc bytecode
|
||||
* \return 0 if element size is unknown.
|
||||
*/
|
||||
int (*elem_size) (yasm_bytecode *bc);
|
||||
|
||||
/** Calculates the minimum size of a bytecode.
|
||||
* Called from yasm_bc_calc_len().
|
||||
* A generic fill-in for this is yasm_bc_calc_len_common(), but as this
|
||||
* function internal errors when called, be very careful when using it!
|
||||
* This function should simply add to bc->len and not set it directly
|
||||
* (it's initialized by yasm_bc_calc_len() prior to passing control to
|
||||
* this function).
|
||||
*
|
||||
* \param bc bytecode
|
||||
* \param add_span function to call to add a span
|
||||
* \param add_span_data extra data to be passed to add_span function
|
||||
* \return 0 if no error occurred, nonzero if there was an error
|
||||
* recognized (and output) during execution.
|
||||
* \note May store to bytecode updated expressions.
|
||||
*/
|
||||
int (*calc_len) (yasm_bytecode *bc, yasm_bc_add_span_func add_span,
|
||||
void *add_span_data);
|
||||
|
||||
/** Recalculates the bytecode's length based on an expanded span length.
|
||||
* Called from yasm_bc_expand().
|
||||
* A generic fill-in for this is yasm_bc_expand_common(), but as this
|
||||
* function internal errors when called, if used, ensure that calc_len()
|
||||
* never adds a span.
|
||||
* This function should simply add to bc->len to increase the length by
|
||||
* a delta amount.
|
||||
* \param bc bytecode
|
||||
* \param span span ID (as given to add_span in calc_len)
|
||||
* \param old_val previous span value
|
||||
* \param new_val new span value
|
||||
* \param neg_thres negative threshold for long/short decision
|
||||
* (returned)
|
||||
* \param pos_thres positive threshold for long/short decision
|
||||
* (returned)
|
||||
* \return 0 if bc no longer dependent on this span's length, negative if
|
||||
* there was an error recognized (and output) during execution,
|
||||
* and positive if bc size may increase for this span further
|
||||
* based on the new negative and positive thresholds returned.
|
||||
* \note May store to bytecode updated expressions.
|
||||
*/
|
||||
int (*expand) (yasm_bytecode *bc, int span, long old_val, long new_val,
|
||||
/*@out@*/ long *neg_thres, /*@out@*/ long *pos_thres);
|
||||
|
||||
/** Convert a bytecode into its byte representation.
|
||||
* Called from yasm_bc_tobytes().
|
||||
* A generic fill-in for this is yasm_bc_tobytes_common(), but as this
|
||||
* function internal errors when called, be very careful when using it!
|
||||
* \param bc bytecode
|
||||
* \param bufp byte representation destination buffer;
|
||||
* should be incremented as it's written to,
|
||||
* so that on return its delta from the
|
||||
* passed-in buf matches the bytecode length
|
||||
* (it's okay not to do this if an error
|
||||
* indication is returned)
|
||||
* \param bufstart For calculating the correct offset parameter for
|
||||
* the \a output_value calls: *bufp - bufstart.
|
||||
* \param d data to pass to each call to
|
||||
* output_value/output_reloc
|
||||
* \param output_value function to call to convert values into their byte
|
||||
* representation
|
||||
* \param output_reloc function to call to output relocation entries
|
||||
* for a single sym
|
||||
* \return Nonzero on error, 0 on success.
|
||||
* \note May result in non-reversible changes to the bytecode, but it's
|
||||
* preferable if calling this function twice would result in the
|
||||
* same output.
|
||||
*/
|
||||
int (*tobytes) (yasm_bytecode *bc, unsigned char **bufp,
|
||||
unsigned char *bufstart, void *d,
|
||||
yasm_output_value_func output_value,
|
||||
/*@null@*/ yasm_output_reloc_func output_reloc);
|
||||
|
||||
/** Special bytecode classifications. Most bytecode types should use
|
||||
* #YASM_BC_SPECIAL_NONE. Others cause special handling to kick in
|
||||
* in various parts of yasm.
|
||||
*/
|
||||
enum yasm_bytecode_special_type {
|
||||
YASM_BC_SPECIAL_NONE = 0,
|
||||
|
||||
/** Bytecode reserves space instead of outputting data. */
|
||||
YASM_BC_SPECIAL_RESERVE,
|
||||
|
||||
/** Adjusts offset instead of calculating len. */
|
||||
YASM_BC_SPECIAL_OFFSET,
|
||||
|
||||
/** Instruction bytecode. */
|
||||
YASM_BC_SPECIAL_INSN
|
||||
} special;
|
||||
} yasm_bytecode_callback;
|
||||
|
||||
/** A bytecode. */
|
||||
struct yasm_bytecode {
|
||||
/** Bytecodes are stored as a singly linked list, with tail insertion.
|
||||
* \see section.h (#yasm_section).
|
||||
*/
|
||||
/*@reldef@*/ STAILQ_ENTRY(yasm_bytecode) link;
|
||||
|
||||
/** The bytecode callback structure for this bytecode. May be NULL
|
||||
* during partial initialization.
|
||||
*/
|
||||
/*@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 (to save space in the common case).
|
||||
*/
|
||||
/*@only@*/ /*@null@*/ yasm_expr *multiple;
|
||||
|
||||
/** Total length of entire bytecode (not including multiple copies). */
|
||||
unsigned long len;
|
||||
|
||||
/** Number of copies, integer version. */
|
||||
long mult_int;
|
||||
|
||||
/** Line number where bytecode was defined. */
|
||||
unsigned long line;
|
||||
|
||||
/** Offset of bytecode from beginning of its section.
|
||||
* 0-based, ~0UL (e.g. all 1 bits) if unknown.
|
||||
*/
|
||||
unsigned long offset;
|
||||
|
||||
/** Unique integer index of bytecode. Used during optimization. */
|
||||
unsigned long bc_index;
|
||||
|
||||
/** NULL-terminated array of labels that point to this bytecode (as the
|
||||
* bytecode previous to the label). NULL if no labels point here.
|
||||
*/
|
||||
/*@null@*/ yasm_symrec **symrecs;
|
||||
|
||||
/** Implementation-specific data (type identified by callback). */
|
||||
void *contents;
|
||||
};
|
||||
|
||||
/** Create a bytecode of any specified type.
|
||||
* \param callback bytecode callback functions, if NULL, creates empty
|
||||
* bytecode (may not be resolved or output)
|
||||
* \param contents type-specific data
|
||||
* \param line virtual line (from yasm_linemap)
|
||||
* \return Newly allocated bytecode of the specified type.
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
/*@only@*/ yasm_bytecode *yasm_bc_create_common
|
||||
(/*@null@*/ const yasm_bytecode_callback *callback,
|
||||
/*@only@*/ /*@null@*/ void *contents, unsigned long line);
|
||||
|
||||
/** Transform a bytecode of any type into a different type.
|
||||
* \param bc bytecode to transform
|
||||
* \param callback new bytecode callback function
|
||||
* \param contents new type-specific data
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
void yasm_bc_transform(yasm_bytecode *bc,
|
||||
const yasm_bytecode_callback *callback,
|
||||
void *contents);
|
||||
|
||||
/** Common bytecode callback finalize function, for where no finalization
|
||||
* is ever required for this type of bytecode.
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
void yasm_bc_finalize_common(yasm_bytecode *bc, yasm_bytecode *prev_bc);
|
||||
|
||||
/** Common bytecode callback calc_len function, for where the bytecode has
|
||||
* no calculatable length. Causes an internal error if called.
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
int yasm_bc_calc_len_common(yasm_bytecode *bc, yasm_bc_add_span_func add_span,
|
||||
void *add_span_data);
|
||||
|
||||
/** Common bytecode callback expand function, for where the bytecode is
|
||||
* always short (calc_len never calls add_span). Causes an internal
|
||||
* error if called.
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
int yasm_bc_expand_common
|
||||
(yasm_bytecode *bc, int span, long old_val, long new_val,
|
||||
/*@out@*/ long *neg_thres, /*@out@*/ long *pos_thres);
|
||||
|
||||
/** Common bytecode callback tobytes function, for where the bytecode
|
||||
* cannot be converted to bytes. Causes an internal error if called.
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
int yasm_bc_tobytes_common
|
||||
(yasm_bytecode *bc, unsigned char **bufp, unsigned char *bufstart, void *d,
|
||||
yasm_output_value_func output_value,
|
||||
/*@null@*/ yasm_output_reloc_func output_reloc);
|
||||
|
||||
/** Get the next bytecode in a linked list of bytecodes.
|
||||
* \param bc bytecode
|
||||
* \return Next bytecode.
|
||||
*/
|
||||
#define yasm_bc__next(bc) STAILQ_NEXT(bc, link)
|
||||
|
||||
/** Set multiple field of a bytecode.
|
||||
* A bytecode can be repeated a number of times when output. This function
|
||||
* sets that multiple.
|
||||
* \param bc bytecode
|
||||
* \param e multiple (kept, do not free)
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
void yasm_bc_set_multiple(yasm_bytecode *bc, /*@keep@*/ yasm_expr *e);
|
||||
|
||||
/** 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 append_zero append a single zero byte after each data value
|
||||
* (if non-zero)
|
||||
* \param arch architecture (optional); if provided, data items
|
||||
* are directly simplified to bytes if possible
|
||||
* \param line virtual line (from yasm_linemap)
|
||||
* \return Newly allocated bytecode.
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
/*@only@*/ yasm_bytecode *yasm_bc_create_data
|
||||
(yasm_datavalhead *datahead, unsigned int size, int append_zero,
|
||||
/*@null@*/ yasm_arch *arch, unsigned long line);
|
||||
|
||||
/** Create a bytecode containing LEB128-encoded data value(s).
|
||||
* \param datahead list of data values (kept, do not free)
|
||||
* \param sign signedness (1=signed, 0=unsigned) of each data value
|
||||
* \param line virtual line (from yasm_linemap)
|
||||
* \return Newly allocated bytecode.
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
/*@only@*/ yasm_bytecode *yasm_bc_create_leb128
|
||||
(yasm_datavalhead *datahead, int sign, 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 line virtual line (from yasm_linemap)
|
||||
* \return Newly allocated bytecode.
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
/*@only@*/ yasm_bytecode *yasm_bc_create_reserve
|
||||
(/*@only@*/ yasm_expr *numitems, unsigned int itemsize,
|
||||
unsigned long line);
|
||||
|
||||
/** Get the number of items and itemsize for a reserve bytecode. If bc
|
||||
* is not a reserve bytecode, returns NULL.
|
||||
* \param bc bytecode
|
||||
* \param itemsize reserved size (in bytes) for each item (returned)
|
||||
* \return NULL if bc is not a reserve bytecode, otherwise an expression
|
||||
* for the number of items to reserve.
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
/*@null@*/ const yasm_expr *yasm_bc_reserve_numitems
|
||||
(yasm_bytecode *bc, /*@out@*/ unsigned int *itemsize);
|
||||
|
||||
/** Create a bytecode that includes a binary file verbatim.
|
||||
* \param filename path to binary file (kept, do not free)
|
||||
* \param start starting location in file (in bytes) to read data from
|
||||
* (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 linemap line mapping repository
|
||||
* \param line virtual line (from yasm_linemap) for the bytecode
|
||||
* \return Newly allocated bytecode.
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
/*@only@*/ yasm_bytecode *yasm_bc_create_incbin
|
||||
(/*@only@*/ char *filename, /*@only@*/ /*@null@*/ yasm_expr *start,
|
||||
/*@only@*/ /*@null@*/ yasm_expr *maxlen, yasm_linemap *linemap,
|
||||
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 fill fill data (if NULL, code_fill or 0 is used)
|
||||
* \param maxskip maximum number of bytes to skip
|
||||
* \param code_fill code fill data (if NULL, 0 is used)
|
||||
* \param line virtual line (from yasm_linemap)
|
||||
* \return Newly allocated bytecode.
|
||||
* \note The precedence on generated fill is as follows:
|
||||
* - from fill parameter (if not NULL)
|
||||
* - from code_fill parameter (if not NULL)
|
||||
* - 0
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
/*@only@*/ yasm_bytecode *yasm_bc_create_align
|
||||
(/*@keep@*/ yasm_expr *boundary, /*@keep@*/ /*@null@*/ yasm_expr *fill,
|
||||
/*@keep@*/ /*@null@*/ yasm_expr *maxskip,
|
||||
/*@null@*/ const unsigned char **code_fill, unsigned long line);
|
||||
|
||||
/** Create a bytecode that puts the following bytecode at a fixed section
|
||||
* offset.
|
||||
* \param start section offset of following bytecode
|
||||
* \param fill fill value
|
||||
* \param line virtual line (from yasm_linemap)
|
||||
* \return Newly allocated bytecode.
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
/*@only@*/ yasm_bytecode *yasm_bc_create_org
|
||||
(unsigned long start, unsigned long fill, unsigned long line);
|
||||
|
||||
/** 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).
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
/*@dependent@*/ /*@null@*/ yasm_section *yasm_bc_get_section
|
||||
(yasm_bytecode *bc);
|
||||
|
||||
/** Add to the list of symrecs that reference a bytecode. For symrec use
|
||||
* only.
|
||||
* \param bc bytecode
|
||||
* \param sym symbol
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
void yasm_bc__add_symrec(yasm_bytecode *bc, /*@dependent@*/ yasm_symrec *sym);
|
||||
|
||||
/** Delete (free allocated memory for) a bytecode.
|
||||
* \param bc bytecode (only pointer to it); may be NULL
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
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
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
void yasm_bc_print(const yasm_bytecode *bc, FILE *f, int indent_level);
|
||||
|
||||
/** Finalize a bytecode after parsing.
|
||||
* \param bc bytecode
|
||||
* \param prev_bc bytecode directly preceding bc in a list of bytecodes
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
void yasm_bc_finalize(yasm_bytecode *bc, yasm_bytecode *prev_bc);
|
||||
|
||||
/** 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.
|
||||
* \warning Only valid /after/ optimization.
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
/*@null@*/ /*@only@*/ yasm_intnum *yasm_calc_bc_dist
|
||||
(yasm_bytecode *precbc1, yasm_bytecode *precbc2);
|
||||
|
||||
/** Get the offset of the next bytecode (the next bytecode doesn't have to
|
||||
* actually exist).
|
||||
* \param precbc preceding bytecode
|
||||
* \return Offset of the next bytecode in bytes.
|
||||
* \warning Only valid /after/ optimization.
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
unsigned long yasm_bc_next_offset(yasm_bytecode *precbc);
|
||||
|
||||
/** Return elemens size of a data bytecode.
|
||||
* Returns the size of each elements of a data bytecode, for proper dereference
|
||||
* of symbols attached to it.
|
||||
* \param bc bytecode
|
||||
* \return 0 if element size is unknown
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
int yasm_bc_elem_size(yasm_bytecode *bc);
|
||||
|
||||
/** Resolve EQUs in a bytecode and calculate its minimum size.
|
||||
* Generates dependent bytecode spans for cases where, if the length spanned
|
||||
* increases, it could cause the bytecode size to increase.
|
||||
* Any bytecode multiple is NOT included in the length or spans generation;
|
||||
* this must be handled at a higher level.
|
||||
* \param bc bytecode
|
||||
* \param add_span function to call to add a span
|
||||
* \param add_span_data extra data to be passed to add_span function
|
||||
* \return 0 if no error occurred, nonzero if there was an error recognized
|
||||
* (and output) during execution.
|
||||
* \note May store to bytecode updated expressions and the short length.
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
int yasm_bc_calc_len(yasm_bytecode *bc, yasm_bc_add_span_func add_span,
|
||||
void *add_span_data);
|
||||
|
||||
/** Recalculate a bytecode's length based on an expanded span length.
|
||||
* \param bc bytecode
|
||||
* \param span span ID (as given to yasm_bc_add_span_func in
|
||||
* yasm_bc_calc_len)
|
||||
* \param old_val previous span value
|
||||
* \param new_val new span value
|
||||
* \param neg_thres negative threshold for long/short decision (returned)
|
||||
* \param pos_thres positive threshold for long/short decision (returned)
|
||||
* \return 0 if bc no longer dependent on this span's length, negative if
|
||||
* there was an error recognized (and output) during execution, and
|
||||
* positive if bc size may increase for this span further based on the
|
||||
* new negative and positive thresholds returned.
|
||||
* \note May store to bytecode updated expressions and the updated length.
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
int yasm_bc_expand(yasm_bytecode *bc, int span, long old_val, long new_val,
|
||||
/*@out@*/ long *neg_thres, /*@out@*/ long *pos_thres);
|
||||
|
||||
/** Convert a bytecode into its byte representation.
|
||||
* \param bc bytecode
|
||||
* \param buf byte representation destination buffer
|
||||
* \param bufsize size of buf (in bytes) prior to call; size of the
|
||||
* generated data after call
|
||||
* \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 d data to pass to each call to output_value/output_reloc
|
||||
* \param output_value function to call to convert values 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
|
||||
* reading the byte representation, or NULL if buf was big enough to
|
||||
* hold the entire byte representation.
|
||||
* \note Calling twice on the same bytecode may \em not produce the same
|
||||
* results on the second call, as calling this function may result in
|
||||
* non-reversible changes to the bytecode.
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
/*@null@*/ /*@only@*/ unsigned char *yasm_bc_tobytes
|
||||
(yasm_bytecode *bc, unsigned char *buf, unsigned long *bufsize,
|
||||
/*@out@*/ int *gap, void *d, yasm_output_value_func output_value,
|
||||
/*@null@*/ yasm_output_reloc_func output_reloc)
|
||||
/*@sets *buf@*/;
|
||||
|
||||
/** Get the bytecode multiple value as an integer.
|
||||
* \param bc bytecode
|
||||
* \param multiple multiple value (output)
|
||||
* \param calc_bc_dist nonzero if distances between bytecodes should be
|
||||
* calculated, 0 if error should be returned in this case
|
||||
* \return 1 on error (set with yasm_error_set), 0 on success.
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
int yasm_bc_get_multiple(yasm_bytecode *bc, /*@out@*/ long *multiple,
|
||||
int calc_bc_dist);
|
||||
|
||||
/** Get the bytecode multiple value as an expression.
|
||||
* \param bc bytecode
|
||||
* \return Bytecode multiple, NULL if =1.
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
const yasm_expr *yasm_bc_get_multiple_expr(const yasm_bytecode *bc);
|
||||
|
||||
/** Get a #yasm_insn structure from an instruction bytecode (if possible).
|
||||
* \param bc bytecode
|
||||
* \return Instruction details if bytecode is an instruction bytecode,
|
||||
* otherwise NULL.
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
/*@dependent@*/ /*@null@*/ yasm_insn *yasm_bc_get_insn(yasm_bytecode *bc);
|
||||
|
||||
/** Create a new data value from an expression.
|
||||
* \param expn expression
|
||||
* \return Newly allocated data value.
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
yasm_dataval *yasm_dv_create_expr(/*@keep@*/ yasm_expr *expn);
|
||||
|
||||
/** Create a new data value from a string.
|
||||
* \param contents string (may contain NULs)
|
||||
* \param len length of string
|
||||
* \return Newly allocated data value.
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
yasm_dataval *yasm_dv_create_string(/*@keep@*/ char *contents, size_t len);
|
||||
|
||||
/** Create a new data value from raw bytes data.
|
||||
* \param contents raw data (may contain NULs)
|
||||
* \param len length
|
||||
* \return Newly allocated data value.
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
yasm_dataval *yasm_dv_create_raw(/*@keep@*/ unsigned char *contents,
|
||||
unsigned long len);
|
||||
|
||||
/** Create a new uninitialized data value.
|
||||
* \return Newly allocated data value.
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
yasm_dataval *yasm_dv_create_reserve(void);
|
||||
|
||||
#ifndef YASM_DOXYGEN
|
||||
#define yasm_dv_create_string(s, l) yasm_dv_create_raw((unsigned char *)(s), \
|
||||
(unsigned long)(l))
|
||||
#endif
|
||||
|
||||
/** Get the underlying value of a data value.
|
||||
* \param dv data value
|
||||
* \return Value, or null if non-value (e.g. string or raw).
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
yasm_value *yasm_dv_get_value(yasm_dataval *dv);
|
||||
|
||||
/** Set multiple field of a data value.
|
||||
* A data value can be repeated a number of times when output. This function
|
||||
* sets that multiple.
|
||||
* \param dv data value
|
||||
* \param e multiple (kept, do not free)
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
void yasm_dv_set_multiple(yasm_dataval *dv, /*@keep@*/ yasm_expr *e);
|
||||
|
||||
/** Get the data value multiple value as an unsigned long integer.
|
||||
* \param dv data value
|
||||
* \param multiple multiple value (output)
|
||||
* \return 1 on error (set with yasm_error_set), 0 on success.
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
int yasm_dv_get_multiple(yasm_dataval *dv, /*@out@*/ unsigned long *multiple);
|
||||
|
||||
/** Initialize a list of data values.
|
||||
* \param headp list of data values
|
||||
*/
|
||||
void yasm_dvs_initialize(yasm_datavalhead *headp);
|
||||
#ifndef YASM_DOXYGEN
|
||||
#define yasm_dvs_initialize(headp) STAILQ_INIT(headp)
|
||||
#endif
|
||||
|
||||
/** Delete (free allocated memory for) a list of data values.
|
||||
* \param headp list of data values
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
void yasm_dvs_delete(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
|
||||
* static or local variables, and discard the dv pointer after calling
|
||||
* this function.
|
||||
* \param headp data value list
|
||||
* \param dv data value (may be NULL)
|
||||
* \return If data value was actually appended (it wasn't NULL), the data
|
||||
* value; otherwise NULL.
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
/*@null@*/ yasm_dataval *yasm_dvs_append
|
||||
(yasm_datavalhead *headp, /*@returned@*/ /*@null@*/ yasm_dataval *dv);
|
||||
|
||||
/** Print a data value list. For debugging purposes.
|
||||
* \param f file
|
||||
* \param indent_level indentation level
|
||||
* \param headp data value list
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
void yasm_dvs_print(const yasm_datavalhead *headp, FILE *f, int indent_level);
|
||||
|
||||
#endif
|
||||
@ -0,0 +1,456 @@
|
||||
/*
|
||||
* <sys/queue.h> implementation for systems that don't have it.
|
||||
*
|
||||
* Copyright (c) 1991, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND 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 REGENTS OR 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.
|
||||
*
|
||||
* @(#)queue.h 8.5 (Berkeley) 8/20/94
|
||||
* $FreeBSD: src/sys/sys/queue.h,v 1.32.2.4 2001/03/31 03:33:39 hsu Exp $
|
||||
*/
|
||||
|
||||
#ifndef SYS_QUEUE_H
|
||||
#define SYS_QUEUE_H
|
||||
|
||||
/*
|
||||
* This file defines four types of data structures: singly-linked lists,
|
||||
* singly-linked tail queues, lists and tail queues.
|
||||
*
|
||||
* A singly-linked list is headed by a single forward pointer. The elements
|
||||
* are singly linked for minimum space and pointer manipulation overhead at
|
||||
* the expense of O(n) removal for arbitrary elements. New elements can be
|
||||
* added to the list after an existing element or at the head of the list.
|
||||
* Elements being removed from the head of the list should use the explicit
|
||||
* macro for this purpose for optimum efficiency. A singly-linked list may
|
||||
* only be traversed in the forward direction. Singly-linked lists are ideal
|
||||
* for applications with large datasets and few or no removals or for
|
||||
* implementing a LIFO queue.
|
||||
*
|
||||
* A singly-linked tail queue is headed by a pair of pointers, one to the
|
||||
* head of the list and the other to the tail of the list. The elements are
|
||||
* singly linked for minimum space and pointer manipulation overhead at the
|
||||
* expense of O(n) removal for arbitrary elements. New elements can be added
|
||||
* to the list after an existing element, at the head of the list, or at the
|
||||
* end of the list. Elements being removed from the head of the tail queue
|
||||
* should use the explicit macro for this purpose for optimum efficiency.
|
||||
* A singly-linked tail queue may only be traversed in the forward direction.
|
||||
* Singly-linked tail queues are ideal for applications with large datasets
|
||||
* and few or no removals or for implementing a FIFO queue.
|
||||
*
|
||||
* A list is headed by a single forward pointer (or an array of forward
|
||||
* pointers for a hash table header). The elements are doubly linked
|
||||
* so that an arbitrary element can be removed without a need to
|
||||
* traverse the list. New elements can be added to the list before
|
||||
* or after an existing element or at the head of the list. A list
|
||||
* may only be traversed in the forward direction.
|
||||
*
|
||||
* A tail queue is headed by a pair of pointers, one to the head of the
|
||||
* list and the other to the tail of the list. The elements are doubly
|
||||
* linked so that an arbitrary element can be removed without a need to
|
||||
* traverse the list. New elements can be added to the list before or
|
||||
* after an existing element, at the head of the list, or at the end of
|
||||
* the list. A tail queue may be traversed in either direction.
|
||||
*
|
||||
* For details on the use of these macros, see the queue(3) manual page.
|
||||
*
|
||||
*
|
||||
* SLIST LIST STAILQ TAILQ
|
||||
* _HEAD + + + +
|
||||
* _HEAD_INITIALIZER + + + +
|
||||
* _ENTRY + + + +
|
||||
* _INIT + + + +
|
||||
* _EMPTY + + + +
|
||||
* _FIRST + + + +
|
||||
* _NEXT + + + +
|
||||
* _PREV - - - +
|
||||
* _LAST - - + +
|
||||
* _FOREACH + + + +
|
||||
* _FOREACH_SAFE + + + +
|
||||
* _FOREACH_REVERSE - - - +
|
||||
* _FOREACH_REVERSE_SAFE - - - +
|
||||
* _INSERT_HEAD + + + +
|
||||
* _INSERT_BEFORE - + - +
|
||||
* _INSERT_AFTER + + + +
|
||||
* _INSERT_TAIL - - + +
|
||||
* _CONCAT - - + +
|
||||
* _REMOVE_HEAD + - + -
|
||||
* _REMOVE + + + +
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Singly-linked List declarations.
|
||||
*/
|
||||
#define SLIST_HEAD(name, type) \
|
||||
struct name { \
|
||||
struct type *slh_first; /* first element */ \
|
||||
}
|
||||
|
||||
#define SLIST_HEAD_INITIALIZER(head) \
|
||||
{ NULL }
|
||||
|
||||
#define SLIST_ENTRY(type) \
|
||||
struct { \
|
||||
struct type *sle_next; /* next element */ \
|
||||
}
|
||||
|
||||
/*
|
||||
* Singly-linked List functions.
|
||||
*/
|
||||
#define SLIST_EMPTY(head) ((head)->slh_first == NULL)
|
||||
|
||||
#define SLIST_FIRST(head) ((head)->slh_first)
|
||||
|
||||
#define SLIST_FOREACH(var, head, field) \
|
||||
for ((var) = SLIST_FIRST((head)); \
|
||||
(var); \
|
||||
(var) = SLIST_NEXT((var), field))
|
||||
|
||||
#define SLIST_FOREACH_SAFE(var, head, field, tvar) \
|
||||
for ((var) = SLIST_FIRST((head)); \
|
||||
(var) && ((tvar) = SLIST_NEXT((var), field), 1); \
|
||||
(var) = (tvar))
|
||||
|
||||
#define SLIST_FOREACH_PREVPTR(var, varp, head, field) \
|
||||
for ((varp) = &SLIST_FIRST((head)); \
|
||||
((var) = *(varp)) != NULL; \
|
||||
(varp) = &SLIST_NEXT((var), field))
|
||||
|
||||
#define SLIST_INIT(head) do { \
|
||||
SLIST_FIRST((head)) = NULL; \
|
||||
} while (0)
|
||||
|
||||
#define SLIST_INSERT_AFTER(slistelm, elm, field) do { \
|
||||
SLIST_NEXT((elm), field) = SLIST_NEXT((slistelm), field); \
|
||||
SLIST_NEXT((slistelm), field) = (elm); \
|
||||
} while (0)
|
||||
|
||||
#define SLIST_INSERT_HEAD(head, elm, field) do { \
|
||||
SLIST_NEXT((elm), field) = SLIST_FIRST((head)); \
|
||||
SLIST_FIRST((head)) = (elm); \
|
||||
} while (0)
|
||||
|
||||
#define SLIST_NEXT(elm, field) ((elm)->field.sle_next)
|
||||
|
||||
#define SLIST_REMOVE(head, elm, type, field) do { \
|
||||
if (SLIST_FIRST((head)) == (elm)) { \
|
||||
SLIST_REMOVE_HEAD((head), field); \
|
||||
} \
|
||||
else { \
|
||||
struct type *curelm = SLIST_FIRST((head)); \
|
||||
while (SLIST_NEXT(curelm, field) != (elm)) \
|
||||
curelm = SLIST_NEXT(curelm, field); \
|
||||
SLIST_NEXT(curelm, field) = \
|
||||
SLIST_NEXT(SLIST_NEXT(curelm, field), field); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define SLIST_REMOVE_HEAD(head, field) do { \
|
||||
SLIST_FIRST((head)) = SLIST_NEXT(SLIST_FIRST((head)), field); \
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
* Singly-linked Tail queue declarations.
|
||||
*/
|
||||
#define STAILQ_HEAD(name, type) \
|
||||
struct name { \
|
||||
struct type *stqh_first;/* first element */ \
|
||||
struct type **stqh_last;/* addr of last next element */ \
|
||||
}
|
||||
|
||||
#define STAILQ_HEAD_INITIALIZER(head) \
|
||||
{ NULL, &(head).stqh_first }
|
||||
|
||||
#define STAILQ_ENTRY(type) \
|
||||
struct { \
|
||||
struct type *stqe_next; /* next element */ \
|
||||
}
|
||||
|
||||
/*
|
||||
* Singly-linked Tail queue functions.
|
||||
*/
|
||||
#define STAILQ_CONCAT(head1, head2) do { \
|
||||
if (!STAILQ_EMPTY((head2))) { \
|
||||
*(head1)->stqh_last = (head2)->stqh_first; \
|
||||
(head1)->stqh_last = (head2)->stqh_last; \
|
||||
STAILQ_INIT((head2)); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define STAILQ_EMPTY(head) ((head)->stqh_first == NULL)
|
||||
|
||||
#define STAILQ_FIRST(head) ((head)->stqh_first)
|
||||
|
||||
#define STAILQ_FOREACH(var, head, field) \
|
||||
for((var) = STAILQ_FIRST((head)); \
|
||||
(var); \
|
||||
(var) = STAILQ_NEXT((var), field))
|
||||
|
||||
|
||||
#define STAILQ_FOREACH_SAFE(var, head, field, tvar) \
|
||||
for ((var) = STAILQ_FIRST((head)); \
|
||||
(var) && ((tvar) = STAILQ_NEXT((var), field), 1); \
|
||||
(var) = (tvar))
|
||||
|
||||
#define STAILQ_INIT(head) do { \
|
||||
STAILQ_FIRST((head)) = NULL; \
|
||||
(head)->stqh_last = &STAILQ_FIRST((head)); \
|
||||
} while (0)
|
||||
|
||||
#define STAILQ_INSERT_AFTER(head, tqelm, elm, field) do { \
|
||||
if ((STAILQ_NEXT((elm), field) = STAILQ_NEXT((tqelm), field)) == NULL)\
|
||||
(head)->stqh_last = &STAILQ_NEXT((elm), field); \
|
||||
STAILQ_NEXT((tqelm), field) = (elm); \
|
||||
} while (0)
|
||||
|
||||
#define STAILQ_INSERT_HEAD(head, elm, field) do { \
|
||||
if ((STAILQ_NEXT((elm), field) = STAILQ_FIRST((head))) == NULL) \
|
||||
(head)->stqh_last = &STAILQ_NEXT((elm), field); \
|
||||
STAILQ_FIRST((head)) = (elm); \
|
||||
} while (0)
|
||||
|
||||
#define STAILQ_INSERT_TAIL(head, elm, field) do { \
|
||||
STAILQ_NEXT((elm), field) = NULL; \
|
||||
*(head)->stqh_last = (elm); \
|
||||
(head)->stqh_last = &STAILQ_NEXT((elm), field); \
|
||||
} while (0)
|
||||
|
||||
#define STAILQ_LAST(head, type, field) \
|
||||
(STAILQ_EMPTY((head)) ? \
|
||||
NULL : \
|
||||
((struct type *) \
|
||||
((char *)((head)->stqh_last) - offsetof(struct type, field))))
|
||||
|
||||
#define STAILQ_NEXT(elm, field) ((elm)->field.stqe_next)
|
||||
|
||||
#define STAILQ_REMOVE(head, elm, type, field) do { \
|
||||
if (STAILQ_FIRST((head)) == (elm)) { \
|
||||
STAILQ_REMOVE_HEAD((head), field); \
|
||||
} \
|
||||
else { \
|
||||
struct type *curelm = STAILQ_FIRST((head)); \
|
||||
while (STAILQ_NEXT(curelm, field) != (elm)) \
|
||||
curelm = STAILQ_NEXT(curelm, field); \
|
||||
if ((STAILQ_NEXT(curelm, field) = \
|
||||
STAILQ_NEXT(STAILQ_NEXT(curelm, field), field)) == NULL)\
|
||||
(head)->stqh_last = &STAILQ_NEXT((curelm), field);\
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define STAILQ_REMOVE_HEAD(head, field) do { \
|
||||
if ((STAILQ_FIRST((head)) = \
|
||||
STAILQ_NEXT(STAILQ_FIRST((head)), field)) == NULL) \
|
||||
(head)->stqh_last = &STAILQ_FIRST((head)); \
|
||||
} while (0)
|
||||
|
||||
#define STAILQ_REMOVE_HEAD_UNTIL(head, elm, field) do { \
|
||||
if ((STAILQ_FIRST((head)) = STAILQ_NEXT((elm), field)) == NULL) \
|
||||
(head)->stqh_last = &STAILQ_FIRST((head)); \
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
* List declarations.
|
||||
*/
|
||||
#define LIST_HEAD(name, type) \
|
||||
struct name { \
|
||||
struct type *lh_first; /* first element */ \
|
||||
}
|
||||
|
||||
#define LIST_HEAD_INITIALIZER(head) \
|
||||
{ NULL }
|
||||
|
||||
#define LIST_ENTRY(type) \
|
||||
struct { \
|
||||
struct type *le_next; /* next element */ \
|
||||
struct type **le_prev; /* address of previous next element */ \
|
||||
}
|
||||
|
||||
/*
|
||||
* List functions.
|
||||
*/
|
||||
|
||||
#define LIST_EMPTY(head) ((head)->lh_first == NULL)
|
||||
|
||||
#define LIST_FIRST(head) ((head)->lh_first)
|
||||
|
||||
#define LIST_FOREACH(var, head, field) \
|
||||
for ((var) = LIST_FIRST((head)); \
|
||||
(var); \
|
||||
(var) = LIST_NEXT((var), field))
|
||||
|
||||
#define LIST_FOREACH_SAFE(var, head, field, tvar) \
|
||||
for ((var) = LIST_FIRST((head)); \
|
||||
(var) && ((tvar) = LIST_NEXT((var), field), 1); \
|
||||
(var) = (tvar))
|
||||
|
||||
#define LIST_INIT(head) do { \
|
||||
LIST_FIRST((head)) = NULL; \
|
||||
} while (0)
|
||||
|
||||
#define LIST_INSERT_AFTER(listelm, elm, field) do { \
|
||||
if ((LIST_NEXT((elm), field) = LIST_NEXT((listelm), field)) != NULL)\
|
||||
LIST_NEXT((listelm), field)->field.le_prev = \
|
||||
&LIST_NEXT((elm), field); \
|
||||
LIST_NEXT((listelm), field) = (elm); \
|
||||
(elm)->field.le_prev = &LIST_NEXT((listelm), field); \
|
||||
} while (0)
|
||||
|
||||
#define LIST_INSERT_BEFORE(listelm, elm, field) do { \
|
||||
(elm)->field.le_prev = (listelm)->field.le_prev; \
|
||||
LIST_NEXT((elm), field) = (listelm); \
|
||||
*(listelm)->field.le_prev = (elm); \
|
||||
(listelm)->field.le_prev = &LIST_NEXT((elm), field); \
|
||||
} while (0)
|
||||
|
||||
#define LIST_INSERT_HEAD(head, elm, field) do { \
|
||||
if ((LIST_NEXT((elm), field) = LIST_FIRST((head))) != NULL) \
|
||||
LIST_FIRST((head))->field.le_prev = &LIST_NEXT((elm), field);\
|
||||
LIST_FIRST((head)) = (elm); \
|
||||
(elm)->field.le_prev = &LIST_FIRST((head)); \
|
||||
} while (0)
|
||||
|
||||
#define LIST_NEXT(elm, field) ((elm)->field.le_next)
|
||||
|
||||
#define LIST_REMOVE(elm, field) do { \
|
||||
if (LIST_NEXT((elm), field) != NULL) \
|
||||
LIST_NEXT((elm), field)->field.le_prev = \
|
||||
(elm)->field.le_prev; \
|
||||
*(elm)->field.le_prev = LIST_NEXT((elm), field); \
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
* Tail queue declarations.
|
||||
*/
|
||||
#define TAILQ_HEAD(name, type) \
|
||||
struct name { \
|
||||
struct type *tqh_first; /* first element */ \
|
||||
struct type **tqh_last; /* addr of last next element */ \
|
||||
}
|
||||
|
||||
#define TAILQ_HEAD_INITIALIZER(head) \
|
||||
{ NULL, &(head).tqh_first }
|
||||
|
||||
#define TAILQ_ENTRY(type) \
|
||||
struct { \
|
||||
struct type *tqe_next; /* next element */ \
|
||||
struct type **tqe_prev; /* address of previous next element */ \
|
||||
}
|
||||
|
||||
/*
|
||||
* Tail queue functions.
|
||||
*/
|
||||
#define TAILQ_CONCAT(head1, head2, field) do { \
|
||||
if (!TAILQ_EMPTY(head2)) { \
|
||||
*(head1)->tqh_last = (head2)->tqh_first; \
|
||||
(head2)->tqh_first->field.tqe_prev = (head1)->tqh_last; \
|
||||
(head1)->tqh_last = (head2)->tqh_last; \
|
||||
TAILQ_INIT((head2)); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define TAILQ_EMPTY(head) ((head)->tqh_first == NULL)
|
||||
|
||||
#define TAILQ_FIRST(head) ((head)->tqh_first)
|
||||
|
||||
#define TAILQ_FOREACH(var, head, field) \
|
||||
for ((var) = TAILQ_FIRST((head)); \
|
||||
(var); \
|
||||
(var) = TAILQ_NEXT((var), field))
|
||||
|
||||
#define TAILQ_FOREACH_SAFE(var, head, field, tvar) \
|
||||
for ((var) = TAILQ_FIRST((head)); \
|
||||
(var) && ((tvar) = TAILQ_NEXT((var), field), 1); \
|
||||
(var) = (tvar))
|
||||
|
||||
#define TAILQ_FOREACH_REVERSE(var, head, headname, field) \
|
||||
for ((var) = TAILQ_LAST((head), headname); \
|
||||
(var); \
|
||||
(var) = TAILQ_PREV((var), headname, field))
|
||||
|
||||
#define TAILQ_FOREACH_REVERSE_SAFE(var, head, headname, field, tvar) \
|
||||
for ((var) = TAILQ_LAST((head), headname); \
|
||||
(var) && ((tvar) = TAILQ_PREV((var), headname, field), 1); \
|
||||
(var) = (tvar))
|
||||
|
||||
#define TAILQ_INIT(head) do { \
|
||||
TAILQ_FIRST((head)) = NULL; \
|
||||
(head)->tqh_last = &TAILQ_FIRST((head)); \
|
||||
} while (0)
|
||||
|
||||
#define TAILQ_INSERT_AFTER(head, listelm, elm, field) do { \
|
||||
if ((TAILQ_NEXT((elm), field) = TAILQ_NEXT((listelm), field)) != NULL)\
|
||||
TAILQ_NEXT((elm), field)->field.tqe_prev = \
|
||||
&TAILQ_NEXT((elm), field); \
|
||||
else { \
|
||||
(head)->tqh_last = &TAILQ_NEXT((elm), field); \
|
||||
} \
|
||||
TAILQ_NEXT((listelm), field) = (elm); \
|
||||
(elm)->field.tqe_prev = &TAILQ_NEXT((listelm), field); \
|
||||
} while (0)
|
||||
|
||||
#define TAILQ_INSERT_BEFORE(listelm, elm, field) do { \
|
||||
(elm)->field.tqe_prev = (listelm)->field.tqe_prev; \
|
||||
TAILQ_NEXT((elm), field) = (listelm); \
|
||||
*(listelm)->field.tqe_prev = (elm); \
|
||||
(listelm)->field.tqe_prev = &TAILQ_NEXT((elm), field); \
|
||||
} while (0)
|
||||
|
||||
#define TAILQ_INSERT_HEAD(head, elm, field) do { \
|
||||
if ((TAILQ_NEXT((elm), field) = TAILQ_FIRST((head))) != NULL) \
|
||||
TAILQ_FIRST((head))->field.tqe_prev = \
|
||||
&TAILQ_NEXT((elm), field); \
|
||||
else \
|
||||
(head)->tqh_last = &TAILQ_NEXT((elm), field); \
|
||||
TAILQ_FIRST((head)) = (elm); \
|
||||
(elm)->field.tqe_prev = &TAILQ_FIRST((head)); \
|
||||
} while (0)
|
||||
|
||||
#define TAILQ_INSERT_TAIL(head, elm, field) do { \
|
||||
TAILQ_NEXT((elm), field) = NULL; \
|
||||
(elm)->field.tqe_prev = (head)->tqh_last; \
|
||||
*(head)->tqh_last = (elm); \
|
||||
(head)->tqh_last = &TAILQ_NEXT((elm), field); \
|
||||
} while (0)
|
||||
|
||||
#define TAILQ_LAST(head, headname) \
|
||||
(*(((struct headname *)((head)->tqh_last))->tqh_last))
|
||||
|
||||
#define TAILQ_NEXT(elm, field) ((elm)->field.tqe_next)
|
||||
|
||||
#define TAILQ_PREV(elm, headname, field) \
|
||||
(*(((struct headname *)((elm)->field.tqe_prev))->tqh_last))
|
||||
|
||||
#define TAILQ_REMOVE(head, elm, field) do { \
|
||||
if ((TAILQ_NEXT((elm), field)) != NULL) \
|
||||
TAILQ_NEXT((elm), field)->field.tqe_prev = \
|
||||
(elm)->field.tqe_prev; \
|
||||
else { \
|
||||
(head)->tqh_last = (elm)->field.tqe_prev; \
|
||||
} \
|
||||
*(elm)->field.tqe_prev = TAILQ_NEXT((elm), field); \
|
||||
} while (0)
|
||||
|
||||
#endif /* !SYS_QUEUE_H */
|
||||
@ -0,0 +1,393 @@
|
||||
/**
|
||||
* \file libyasm/coretype.h
|
||||
* \brief YASM core types and utility functions.
|
||||
*
|
||||
* \license
|
||||
* Copyright (C) 2001-2007 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_CORETYPE_H
|
||||
#define YASM_CORETYPE_H
|
||||
|
||||
#ifndef YASM_LIB_DECL
|
||||
#define YASM_LIB_DECL
|
||||
#endif
|
||||
|
||||
/** 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 instance (mostly opaque type). \see parser.h for details. */
|
||||
typedef struct yasm_parser yasm_parser;
|
||||
/** Object format interface. \see objfmt.h for details. */
|
||||
typedef struct yasm_objfmt yasm_objfmt;
|
||||
/** Debug format interface. \see dbgfmt.h for details. */
|
||||
typedef struct yasm_dbgfmt yasm_dbgfmt;
|
||||
/** List format interface. \see listfmt.h for details. */
|
||||
typedef struct yasm_listfmt yasm_listfmt;
|
||||
|
||||
/** Object format module interface. \see objfmt.h for details. */
|
||||
typedef struct yasm_objfmt_module yasm_objfmt_module;
|
||||
/** Debug format module interface. \see dbgfmt.h for details. */
|
||||
typedef struct yasm_dbgfmt_module yasm_dbgfmt_module;
|
||||
|
||||
/** Standard macro structure for modules that allows association of a set of
|
||||
* standard macros with a parser/preprocessor combination.
|
||||
* A NULL-terminated array of these structures is used in a number of module
|
||||
* interfaces.
|
||||
*/
|
||||
typedef struct yasm_stdmac {
|
||||
const char *parser; /**< Parser keyword */
|
||||
const char *preproc; /**< Preprocessor keyword */
|
||||
|
||||
/** NULL-terminated array of standard macros. May be NULL if no standard
|
||||
* macros should be added for this preprocessor.
|
||||
*/
|
||||
const char **macros;
|
||||
} yasm_stdmac;
|
||||
|
||||
/** YASM associated data callback structure. Many data structures can have
|
||||
* arbitrary data associated with them.
|
||||
*/
|
||||
typedef struct yasm_assoc_data_callback {
|
||||
/** Free memory allocated for associated data.
|
||||
* \param data associated data
|
||||
*/
|
||||
void (*destroy) (/*@only@*/ void *data);
|
||||
|
||||
/** Print a description of allocated data. For debugging purposes.
|
||||
* \param data associated data
|
||||
* \param f output file
|
||||
* \param indent_level indentation level
|
||||
*/
|
||||
void (*print) (void *data, FILE *f, int indent_level);
|
||||
} yasm_assoc_data_callback;
|
||||
|
||||
/** Set of collected error/warnings (opaque type).
|
||||
* \see errwarn.h for details.
|
||||
*/
|
||||
typedef struct yasm_errwarns yasm_errwarns;
|
||||
|
||||
/** Bytecode. \see bytecode.h for details and related functions. */
|
||||
typedef struct yasm_bytecode yasm_bytecode;
|
||||
|
||||
/** Object. \see section.h for details and related functions. */
|
||||
typedef struct yasm_object yasm_object;
|
||||
|
||||
/** Section (opaque type). \see section.h for related functions. */
|
||||
typedef struct yasm_section yasm_section;
|
||||
|
||||
/** 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;
|
||||
|
||||
/** Expression. \see expr.h for details and related functions. */
|
||||
typedef struct yasm_expr yasm_expr;
|
||||
/** Integer value (opaque type). \see intnum.h for related functions. */
|
||||
typedef struct yasm_intnum yasm_intnum;
|
||||
/** Floating point value (opaque type).
|
||||
* \see floatnum.h for related functions.
|
||||
*/
|
||||
typedef struct yasm_floatnum yasm_floatnum;
|
||||
|
||||
/** A value. May be absolute or relative. Outside the parser, yasm_expr
|
||||
* should only be used for absolute exprs. Anything that could contain
|
||||
* a relocatable value should use this structure instead.
|
||||
* \see value.h for related functions.
|
||||
*/
|
||||
typedef struct yasm_value {
|
||||
/** The absolute portion of the value. May contain *differences* between
|
||||
* symrecs but not standalone symrecs. May be NULL if there is no
|
||||
* absolute portion (e.g. the absolute portion is 0).
|
||||
*/
|
||||
/*@null@*/ /*@only@*/ yasm_expr *abs;
|
||||
|
||||
/** The relative portion of the value. This is the portion that may
|
||||
* need to generate a relocation. May be NULL if no relative portion.
|
||||
*/
|
||||
/*@null@*/ /*@dependent@*/ yasm_symrec *rel;
|
||||
|
||||
/** What the relative portion is in reference to. NULL if the default. */
|
||||
/*@null@*/ /*@dependent@*/ yasm_symrec *wrt;
|
||||
|
||||
/** If the segment of the relative portion should be used, not the
|
||||
* relative portion itself. Boolean.
|
||||
*/
|
||||
unsigned int seg_of : 1;
|
||||
|
||||
/** If the relative portion of the value should be shifted right
|
||||
* (supported only by a few object formats). If just the absolute portion
|
||||
* should be shifted, that must be in the abs expr, not here!
|
||||
*/
|
||||
unsigned int rshift : 7;
|
||||
|
||||
/** Indicates the relative portion of the value should be relocated
|
||||
* relative to the current assembly position rather than relative to the
|
||||
* section start. "Current assembly position" here refers to the starting
|
||||
* address of the bytecode containing this value. Boolean.
|
||||
*/
|
||||
unsigned int curpos_rel : 1;
|
||||
|
||||
/** Indicates that curpos_rel was set due to IP-relative relocation;
|
||||
* in some objfmt/arch combinations (e.g. win64/x86-amd64) this info
|
||||
* is needed to generate special relocations.
|
||||
*/
|
||||
unsigned int ip_rel : 1;
|
||||
|
||||
/** Indicates the value is a jump target address (rather than a simple
|
||||
* data address). In some objfmt/arch combinations (e.g. macho/amd64)
|
||||
* this info is needed to generate special relocations.
|
||||
*/
|
||||
unsigned int jump_target : 1;
|
||||
|
||||
/** Indicates the relative portion of the value should be relocated
|
||||
* relative to its own section start rather than relative to the
|
||||
* section start of the bytecode containing this value. E.g. the value
|
||||
* resulting from the relative portion should be the offset from its
|
||||
* section start. Boolean.
|
||||
*/
|
||||
unsigned int section_rel : 1;
|
||||
|
||||
/** Indicates overflow warnings have been disabled for this value. */
|
||||
unsigned int no_warn : 1;
|
||||
|
||||
/** Sign of the value. Nonzero if the final value should be treated as
|
||||
* signed, 0 if it should be treated as signed.
|
||||
*/
|
||||
unsigned int sign : 1;
|
||||
|
||||
/** Size of the value, in bits. */
|
||||
unsigned int size : 8;
|
||||
} yasm_value;
|
||||
|
||||
/** Maximum value of #yasm_value.rshift */
|
||||
#define YASM_VALUE_RSHIFT_MAX 127
|
||||
|
||||
/** Line number mapping repository (opaque type). \see linemap.h for related
|
||||
* functions.
|
||||
*/
|
||||
typedef struct yasm_linemap yasm_linemap;
|
||||
|
||||
/** Value/parameter pair (opaque type).
|
||||
* \see valparam.h for related functions.
|
||||
*/
|
||||
typedef struct yasm_valparam yasm_valparam;
|
||||
/** List of value/parameters (opaque type).
|
||||
* \see valparam.h for related functions.
|
||||
*/
|
||||
typedef struct yasm_valparamhead yasm_valparamhead;
|
||||
/** Directive list entry.
|
||||
* \see valparam.h for details and related functions.
|
||||
*/
|
||||
typedef struct yasm_directive yasm_directive;
|
||||
|
||||
/** An effective address.
|
||||
* \see insn.h for related functions.
|
||||
*/
|
||||
typedef struct yasm_effaddr yasm_effaddr;
|
||||
|
||||
/** An instruction.
|
||||
* \see insn.h for related functions.
|
||||
*/
|
||||
typedef struct yasm_insn yasm_insn;
|
||||
|
||||
/** Expression operators usable in #yasm_expr expressions. */
|
||||
typedef enum yasm_expr_op {
|
||||
YASM_EXPR_IDENT, /**< No operation, just a value. */
|
||||
YASM_EXPR_ADD, /**< Arithmetic addition (+). */
|
||||
YASM_EXPR_SUB, /**< Arithmetic subtraction (-). */
|
||||
YASM_EXPR_MUL, /**< Arithmetic multiplication (*). */
|
||||
YASM_EXPR_DIV, /**< Arithmetic unsigned division. */
|
||||
YASM_EXPR_SIGNDIV, /**< Arithmetic signed division. */
|
||||
YASM_EXPR_MOD, /**< Arithmetic unsigned modulus. */
|
||||
YASM_EXPR_SIGNMOD, /**< Arithmetic signed modulus. */
|
||||
YASM_EXPR_NEG, /**< Arithmetic negation (-). */
|
||||
YASM_EXPR_NOT, /**< Bitwise negation. */
|
||||
YASM_EXPR_OR, /**< Bitwise OR. */
|
||||
YASM_EXPR_AND, /**< Bitwise AND. */
|
||||
YASM_EXPR_XOR, /**< Bitwise XOR. */
|
||||
YASM_EXPR_XNOR, /**< Bitwise XNOR. */
|
||||
YASM_EXPR_NOR, /**< Bitwise NOR. */
|
||||
YASM_EXPR_SHL, /**< Shift left (logical). */
|
||||
YASM_EXPR_SHR, /**< Shift right (logical). */
|
||||
YASM_EXPR_LOR, /**< Logical OR. */
|
||||
YASM_EXPR_LAND, /**< Logical AND. */
|
||||
YASM_EXPR_LNOT, /**< Logical negation. */
|
||||
YASM_EXPR_LXOR, /**< Logical XOR. */
|
||||
YASM_EXPR_LXNOR, /**< Logical XNOR. */
|
||||
YASM_EXPR_LNOR, /**< Logical NOR. */
|
||||
YASM_EXPR_LT, /**< Less than comparison. */
|
||||
YASM_EXPR_GT, /**< Greater than comparison. */
|
||||
YASM_EXPR_EQ, /**< Equality comparison. */
|
||||
YASM_EXPR_LE, /**< Less than or equal to comparison. */
|
||||
YASM_EXPR_GE, /**< Greater than or equal to comparison. */
|
||||
YASM_EXPR_NE, /**< Not equal comparison. */
|
||||
YASM_EXPR_NONNUM, /**< Start of non-numeric operations (not an op). */
|
||||
YASM_EXPR_SEG, /**< SEG operator (gets segment portion of address). */
|
||||
YASM_EXPR_WRT, /**< WRT operator (gets offset of address relative to
|
||||
* some other segment). */
|
||||
YASM_EXPR_SEGOFF /**< The ':' in segment:offset. */
|
||||
} yasm_expr_op;
|
||||
|
||||
/** Convert yasm_value to its byte representation. Usually implemented by
|
||||
* object formats to keep track of relocations and verify legal expressions.
|
||||
* Must put the value into the least significant bits of the destination,
|
||||
* unless shifted into more significant bits by the shift parameter. The
|
||||
* destination bits must be cleared before being set.
|
||||
* \param value value
|
||||
* \param buf buffer for byte representation
|
||||
* \param destsize destination size (in bytes)
|
||||
* \param offset offset (in bytes) of the expr contents from the start
|
||||
* of the bytecode (needed for relative)
|
||||
* \param bc current bytecode (usually passed into higher-level
|
||||
* calling function)
|
||||
* \param warn enables standard warnings: zero for none;
|
||||
* nonzero for overflow/underflow floating point warnings
|
||||
* \param d objfmt-specific data (passed into higher-level calling
|
||||
* function)
|
||||
* \return Nonzero if an error occurred, 0 otherwise.
|
||||
*/
|
||||
typedef int (*yasm_output_value_func)
|
||||
(yasm_value *value, /*@out@*/ unsigned char *buf, unsigned int destsize,
|
||||
unsigned long offset, yasm_bytecode *bc, int warn, /*@null@*/ void *d);
|
||||
|
||||
/** Convert a symbol reference to its byte representation. Usually implemented
|
||||
* by object formats and debug formats to keep track of relocations generated
|
||||
* by themselves.
|
||||
* \param sym symbol
|
||||
* \param bc current bytecode (usually passed into higher-level
|
||||
* calling function)
|
||||
* \param buf buffer for byte representation
|
||||
* \param destsize destination size (in bytes)
|
||||
* \param valsize size (in bits)
|
||||
* \param warn enables standard warnings: zero for none;
|
||||
* nonzero for overflow/underflow floating point warnings;
|
||||
* negative for signed integer warnings,
|
||||
* positive for unsigned integer warnings
|
||||
* \param d objfmt-specific data (passed into higher-level calling
|
||||
* function)
|
||||
* \return Nonzero if an error occurred, 0 otherwise.
|
||||
*/
|
||||
typedef int (*yasm_output_reloc_func)
|
||||
(yasm_symrec *sym, yasm_bytecode *bc, unsigned char *buf,
|
||||
unsigned int destsize, unsigned int valsize, int warn, void *d);
|
||||
|
||||
/** Sort an array using merge sort algorithm.
|
||||
* \internal
|
||||
* \param base base of array
|
||||
* \param nmemb number of elements in array
|
||||
* \param size size of each array element
|
||||
* \param compar element comparison function
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
int yasm__mergesort(void *base, size_t nmemb, size_t size,
|
||||
int (*compar)(const void *, const void *));
|
||||
|
||||
/** Separate string by delimiters.
|
||||
* \internal
|
||||
* \param stringp string
|
||||
* \param delim set of 1 or more delimiters
|
||||
* \return First/next substring.
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
/*@null@*/ char *yasm__strsep(char **stringp, const char *delim);
|
||||
|
||||
/** Compare two strings, ignoring case differences.
|
||||
* \internal
|
||||
* \param s1 string 1
|
||||
* \param s2 string 2
|
||||
* \return 0 if strings are equal, -1 if s1<s2, 1 if s1>s2.
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
int yasm__strcasecmp(const char *s1, const char *s2);
|
||||
|
||||
/** Compare portion of two strings, ignoring case differences.
|
||||
* \internal
|
||||
* \param s1 string 1
|
||||
* \param s2 string 2
|
||||
* \param n maximum number of characters to compare
|
||||
* \return 0 if strings are equal, -1 if s1<s2, 1 if s1>s2.
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
int yasm__strncasecmp(const char *s1, const char *s2, size_t n);
|
||||
|
||||
/** strdup() implementation using yasm_xmalloc().
|
||||
* \internal
|
||||
* \param str string
|
||||
* \return Newly allocated duplicate string.
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
/*@only@*/ char *yasm__xstrdup(const char *str);
|
||||
|
||||
/** strndup() implementation using yasm_xmalloc().
|
||||
* \internal
|
||||
* \param str string
|
||||
* \param max maximum number of characters to copy
|
||||
* \return Newly allocated duplicate string.
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
/*@only@*/ char *yasm__xstrndup(const char *str, size_t max);
|
||||
|
||||
/** Error-checking memory allocation. A default implementation is provided
|
||||
* that calls yasm_fatal() on allocation errors.
|
||||
* A replacement should \em never return NULL.
|
||||
* \param size number of bytes to allocate
|
||||
* \return Allocated memory block.
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
extern /*@only@*/ /*@out@*/ void * (*yasm_xmalloc) (size_t size);
|
||||
|
||||
/** Error-checking memory allocation (with clear-to-0). A default
|
||||
* implementation is provided that calls yasm_fatal() on allocation errors.
|
||||
* A replacement should \em never return NULL.
|
||||
* \param size number of elements to allocate
|
||||
* \param elsize size (in bytes) of each element
|
||||
* \return Allocated and cleared memory block.
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
extern /*@only@*/ void * (*yasm_xcalloc) (size_t nelem, size_t elsize);
|
||||
|
||||
/** Error-checking memory reallocation. A default implementation is provided
|
||||
* that calls yasm_fatal() on allocation errors. A replacement should
|
||||
* \em never return NULL.
|
||||
* \param oldmem memory block to resize
|
||||
* \param elsize new size, in bytes
|
||||
* \return Re-allocated memory block.
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
extern /*@only@*/ void * (*yasm_xrealloc)
|
||||
(/*@only@*/ /*@out@*/ /*@returned@*/ /*@null@*/ void *oldmem, size_t size)
|
||||
/*@modifies oldmem@*/;
|
||||
|
||||
/** Error-checking memory deallocation. A default implementation is provided
|
||||
* that calls yasm_fatal() on allocation errors.
|
||||
* \param p memory block to free
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
extern void (*yasm_xfree) (/*@only@*/ /*@out@*/ /*@null@*/ void *p)
|
||||
/*@modifies p@*/;
|
||||
|
||||
#endif
|
||||
@ -0,0 +1,122 @@
|
||||
/**
|
||||
* \file libyasm/dbgfmt.h
|
||||
* \brief YASM debug format interface.
|
||||
*
|
||||
* \license
|
||||
* Copyright (C) 2002-2007 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_DBGFMT_H
|
||||
#define YASM_DBGFMT_H
|
||||
|
||||
#ifndef YASM_DOXYGEN
|
||||
/** Base #yasm_dbgfmt structure. Must be present as the first element in any
|
||||
* #yasm_dbgfmt implementation.
|
||||
*/
|
||||
typedef struct yasm_dbgfmt_base {
|
||||
/** #yasm_dbgfmt_module implementation for this debug format. */
|
||||
const struct yasm_dbgfmt_module *module;
|
||||
} yasm_dbgfmt_base;
|
||||
#endif
|
||||
|
||||
/** Debug format module interface. */
|
||||
struct yasm_dbgfmt_module {
|
||||
/** One-line description of the debug format. */
|
||||
const char *name;
|
||||
|
||||
/** Keyword used to select debug format. */
|
||||
const char *keyword;
|
||||
|
||||
/** NULL-terminated list of directives. NULL if none. */
|
||||
/*@null@*/ const yasm_directive *directives;
|
||||
|
||||
/** Create debug format.
|
||||
* Module-level implementation of yasm_dbgfmt_create().
|
||||
* The filenames are provided solely for informational purposes.
|
||||
* \param object object
|
||||
* \return NULL if object format does not provide needed support.
|
||||
*/
|
||||
/*@null@*/ /*@only@*/ yasm_dbgfmt * (*create) (yasm_object *object);
|
||||
|
||||
/** Module-level implementation of yasm_dbgfmt_destroy().
|
||||
* Call yasm_dbgfmt_destroy() instead of calling this function.
|
||||
*/
|
||||
void (*destroy) (/*@only@*/ yasm_dbgfmt *dbgfmt);
|
||||
|
||||
/** Module-level implementation of yasm_dbgfmt_generate().
|
||||
* Call yasm_dbgfmt_generate() instead of calling this function.
|
||||
*/
|
||||
void (*generate) (yasm_object *object, yasm_linemap *linemap,
|
||||
yasm_errwarns *errwarns);
|
||||
};
|
||||
|
||||
/** Get the keyword used to select a debug format.
|
||||
* \param dbgfmt debug format
|
||||
* \return keyword
|
||||
*/
|
||||
const char *yasm_dbgfmt_keyword(const yasm_dbgfmt *dbgfmt);
|
||||
|
||||
/** Initialize debug output for use. Must call before any other debug
|
||||
* format functions. The filenames are provided solely for informational
|
||||
* purposes.
|
||||
* \param module debug format module
|
||||
* \param object object to generate debugging information for
|
||||
* \return NULL if object format does not provide needed support.
|
||||
*/
|
||||
/*@null@*/ /*@only@*/ yasm_dbgfmt *yasm_dbgfmt_create
|
||||
(const yasm_dbgfmt_module *module, yasm_object *object);
|
||||
|
||||
/** Cleans up any allocated debug format memory.
|
||||
* \param dbgfmt debug format
|
||||
*/
|
||||
void yasm_dbgfmt_destroy(/*@only@*/ yasm_dbgfmt *dbgfmt);
|
||||
|
||||
/** Generate debugging information bytecodes.
|
||||
* \param object object
|
||||
* \param linemap virtual/physical line mapping
|
||||
* \param errwarns error/warning set
|
||||
* \note Errors and warnings are stored into errwarns.
|
||||
*/
|
||||
void yasm_dbgfmt_generate(yasm_object *object, yasm_linemap *linemap,
|
||||
yasm_errwarns *errwarns);
|
||||
|
||||
#ifndef YASM_DOXYGEN
|
||||
|
||||
/* Inline macro implementations for dbgfmt functions */
|
||||
|
||||
#define yasm_dbgfmt_keyword(dbgfmt) \
|
||||
(((yasm_dbgfmt_base *)dbgfmt)->module->keyword)
|
||||
|
||||
#define yasm_dbgfmt_create(module, object) \
|
||||
module->create(object)
|
||||
|
||||
#define yasm_dbgfmt_destroy(dbgfmt) \
|
||||
((yasm_dbgfmt_base *)dbgfmt)->module->destroy(dbgfmt)
|
||||
#define yasm_dbgfmt_generate(object, linemap, ews) \
|
||||
((yasm_dbgfmt_base *)((object)->dbgfmt))->module->generate \
|
||||
(object, linemap, ews)
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@ -0,0 +1,348 @@
|
||||
/**
|
||||
* \file libyasm/errwarn.h
|
||||
* \brief YASM error and warning reporting interface.
|
||||
*
|
||||
* \license
|
||||
* Copyright (C) 2001-2007 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_ERRWARN_H
|
||||
#define YASM_ERRWARN_H
|
||||
|
||||
#ifndef YASM_LIB_DECL
|
||||
#define YASM_LIB_DECL
|
||||
#endif
|
||||
|
||||
/** Warning classes (that may be enabled/disabled). */
|
||||
typedef enum yasm_warn_class {
|
||||
YASM_WARN_NONE = 0, /**< No warning */
|
||||
YASM_WARN_GENERAL, /**< Non-specific warnings */
|
||||
YASM_WARN_UNREC_CHAR, /**< Unrecognized characters (while tokenizing) */
|
||||
YASM_WARN_PREPROC, /**< Preprocessor warnings */
|
||||
YASM_WARN_ORPHAN_LABEL, /**< Label alone on a line without a colon */
|
||||
YASM_WARN_UNINIT_CONTENTS, /**< Uninitialized space in code/data section */
|
||||
YASM_WARN_SIZE_OVERRIDE,/**< Double size override */
|
||||
YASM_WARN_IMPLICIT_SIZE_OVERRIDE /**< Implicit size override */
|
||||
} yasm_warn_class;
|
||||
|
||||
/** Error classes. Bitmask-based to support limited subclassing. */
|
||||
typedef enum yasm_error_class {
|
||||
YASM_ERROR_NONE = 0x0000, /**< No error */
|
||||
YASM_ERROR_GENERAL = 0xFFFF, /**< Non-specific */
|
||||
YASM_ERROR_ARITHMETIC = 0x0001, /**< Arithmetic error (general) */
|
||||
YASM_ERROR_OVERFLOW = 0x8001, /**< Arithmetic overflow */
|
||||
YASM_ERROR_FLOATING_POINT = 0x4001, /**< Floating point error */
|
||||
YASM_ERROR_ZERO_DIVISION = 0x2001, /**< Divide-by-zero */
|
||||
YASM_ERROR_ASSERTION = 0x0002, /**< Assertion error */
|
||||
YASM_ERROR_VALUE = 0x0004, /**< Value inappropriate
|
||||
* (e.g. not in range) */
|
||||
YASM_ERROR_NOT_ABSOLUTE = 0x8004, /**< Absolute expression required */
|
||||
YASM_ERROR_TOO_COMPLEX = 0x4004, /**< Expression too complex */
|
||||
YASM_ERROR_NOT_CONSTANT = 0x2004, /**< Constant expression required */
|
||||
YASM_ERROR_IO = 0x0008, /**< I/O error */
|
||||
YASM_ERROR_NOT_IMPLEMENTED = 0x0010, /**< Not implemented error */
|
||||
YASM_ERROR_TYPE = 0x0020, /**< Type error */
|
||||
YASM_ERROR_SYNTAX = 0x0040, /**< Syntax error */
|
||||
YASM_ERROR_PARSE = 0x8040 /**< Parser error */
|
||||
} yasm_error_class;
|
||||
|
||||
/** Initialize any internal data structures. */
|
||||
YASM_LIB_DECL
|
||||
void yasm_errwarn_initialize(void);
|
||||
|
||||
/** Clean up any memory allocated by yasm_errwarn_initialize() or other
|
||||
* functions.
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
void yasm_errwarn_cleanup(void);
|
||||
|
||||
/** Reporting point of internal errors. These are usually due to sanity
|
||||
* check failures in the code.
|
||||
* \warning This function must NOT return to calling code; exit or longjmp
|
||||
* instead.
|
||||
* \param file source file (ala __FILE__)
|
||||
* \param line source line (ala __LINE__)
|
||||
* \param message internal error message
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
extern /*@exits@*/ void (*yasm_internal_error_)
|
||||
(const char *file, unsigned int line, const char *message);
|
||||
|
||||
/** Easily-callable version of yasm_internal_error_(). Automatically uses
|
||||
* __FILE__ and __LINE__ as the file and line.
|
||||
* \param message internal error message
|
||||
*/
|
||||
#define yasm_internal_error(message) \
|
||||
yasm_internal_error_(__FILE__, __LINE__, message)
|
||||
|
||||
/** Reporting point of fatal errors.
|
||||
* \warning This function must NOT return to calling code; exit or longjmp
|
||||
* instead.
|
||||
* \param message fatal error message
|
||||
* \param va va_list argument list for message
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
extern /*@exits@*/ void (*yasm_fatal) (const char *message, va_list va);
|
||||
|
||||
/** Reporting point of fatal errors, with variable arguments (internal only).
|
||||
* \warning This function calls #yasm_fatal, and thus does not return to the
|
||||
* calling code.
|
||||
* \param message fatal error message
|
||||
* \param ... argument list for message
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
/*@exits@*/ void yasm__fatal(const char *message, ...);
|
||||
|
||||
/** Unconditionally clear the error indicator, freeing any associated data.
|
||||
* Has no effect if the error indicator is not set.
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
void yasm_error_clear(void);
|
||||
|
||||
/** Get the error indicator. YASM_ERROR_NONE is returned if no error has
|
||||
* been set. Note that as YASM_ERROR_NONE is 0, the return value can also
|
||||
* be treated as a boolean value.
|
||||
* \return Current error indicator.
|
||||
*/
|
||||
yasm_error_class yasm_error_occurred(void);
|
||||
|
||||
/** Check the error indicator against an error class. To check if any error
|
||||
* has been set, check against the YASM_ERROR_GENERAL class. This function
|
||||
* properly checks error subclasses.
|
||||
* \param eclass base error class to check against
|
||||
* \return Nonzero if error indicator is set and a subclass of eclass, 0
|
||||
* otherwise.
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
int yasm_error_matches(yasm_error_class eclass);
|
||||
|
||||
#ifndef YASM_DOXYGEN
|
||||
YASM_LIB_DECL
|
||||
extern yasm_error_class yasm_eclass;
|
||||
#define yasm_error_occurred() yasm_eclass
|
||||
#endif
|
||||
|
||||
/** Set the error indicator (va_list version). Has no effect if the error
|
||||
* indicator is already set.
|
||||
* \param eclass error class
|
||||
* \param format printf format string
|
||||
* \param va argument list for format
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
void yasm_error_set_va(yasm_error_class eclass, const char *format, va_list va);
|
||||
|
||||
/** Set the error indicator. Has no effect if the error indicator is already
|
||||
* set.
|
||||
* \param eclass error class
|
||||
* \param format printf format string
|
||||
* \param ... argument list for format
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
void yasm_error_set(yasm_error_class eclass, const char *format, ...)
|
||||
/*@printflike@*/;
|
||||
|
||||
/** Set a cross-reference for a new error (va_list version). Has no effect
|
||||
* if the error indicator is already set (e.g. with yasm_error_set()). This
|
||||
* function must be called prior to its corresponding yasm_error_set() call.
|
||||
* \param xrefline virtual line to cross-reference to (should not be 0)
|
||||
* \param format printf format string
|
||||
* \param va argument list for format
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
void yasm_error_set_xref_va(unsigned long xrefline, const char *format,
|
||||
va_list va);
|
||||
|
||||
/** Set a cross-reference for a new error. Has no effect if the error
|
||||
* indicator is already set (e.g. with yasm_error_set()). This function
|
||||
* must be called prior to its corresponding yasm_error_set() call.
|
||||
* \param xrefline virtual line to cross-reference to (should not be 0)
|
||||
* \param format printf format string
|
||||
* \param ... argument list for format
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
void yasm_error_set_xref(unsigned long xrefline, const char *format, ...)
|
||||
/*@printflike@*/;
|
||||
|
||||
/** Fetch the error indicator and all associated data. If the error
|
||||
* indicator is set, the output pointers are set to the current error
|
||||
* indicator values, and the error indicator is cleared.
|
||||
* The code using this function is then responsible for yasm_xfree()'ing
|
||||
* str and xrefstr (if non-NULL). If the error indicator is not set,
|
||||
* all output values are set to 0 (including eclass, which is set to
|
||||
* YASM_ERROR_NONE).
|
||||
* \param eclass error class (output)
|
||||
* \param str error message
|
||||
* \param xrefline virtual line used for cross-referencing (0 if no xref)
|
||||
* \param xrefstr cross-reference error message (NULL if no xref)
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
void yasm_error_fetch(/*@out@*/ yasm_error_class *eclass,
|
||||
/*@out@*/ /*@only@*/ /*@null@*/ char **str,
|
||||
/*@out@*/ unsigned long *xrefline,
|
||||
/*@out@*/ /*@only@*/ /*@null@*/ char **xrefstr);
|
||||
|
||||
/** Unconditionally clear all warning indicators, freeing any associated data.
|
||||
* Has no effect if no warning indicators have been set.
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
void yasm_warn_clear(void);
|
||||
|
||||
/** Get the first warning indicator. YASM_WARN_NONE is returned if no warning
|
||||
* has been set. Note that as YASM_WARN_NONE is 0, the return value can also
|
||||
* be treated as a boolean value.
|
||||
* \return First warning indicator.
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
yasm_warn_class yasm_warn_occurred(void);
|
||||
|
||||
/** Add a warning indicator (va_list version).
|
||||
* \param wclass warning class
|
||||
* \param format printf format string
|
||||
* \param va argument list for format
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
void yasm_warn_set_va(yasm_warn_class wclass, const char *format, va_list va);
|
||||
|
||||
/** Add a warning indicator.
|
||||
* \param wclass warning class
|
||||
* \param format printf format string
|
||||
* \param ... argument list for format
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
void yasm_warn_set(yasm_warn_class wclass, const char *format, ...)
|
||||
/*@printflike@*/;
|
||||
|
||||
/** Fetch the first warning indicator and all associated data. If there
|
||||
* is at least one warning indicator, the output pointers are set to the
|
||||
* first warning indicator values, and first warning indicator is removed.
|
||||
* The code using this function is then responsible for yasm_xfree()'ing
|
||||
* str and xrefstr (if non-NULL). If there is no warning indicator set,
|
||||
* all output values are set to 0 (including wclass, which is set to
|
||||
* YASM_WARN_NONE).
|
||||
* \param wclass warning class (output)
|
||||
* \param str warning message
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
void yasm_warn_fetch(/*@out@*/ yasm_warn_class *wclass,
|
||||
/*@out@*/ /*@only@*/ char **str);
|
||||
|
||||
/** Enable a class of warnings.
|
||||
* \param wclass warning class
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
void yasm_warn_enable(yasm_warn_class wclass);
|
||||
|
||||
/** Disable a class of warnings.
|
||||
* \param wclass warning class
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
void yasm_warn_disable(yasm_warn_class wclass);
|
||||
|
||||
/** Disable all classes of warnings. */
|
||||
YASM_LIB_DECL
|
||||
void yasm_warn_disable_all(void);
|
||||
|
||||
/** Create an error/warning set for collection of multiple error/warnings.
|
||||
* \return Newly allocated set.
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
/*@only@*/ yasm_errwarns *yasm_errwarns_create(void);
|
||||
|
||||
/** Destroy an error/warning set.
|
||||
* \param errwarns error/warning set
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
void yasm_errwarns_destroy(/*@only@*/ yasm_errwarns *errwarns);
|
||||
|
||||
/** Propagate error indicator and warning indicator(s) to an error/warning set.
|
||||
* Has no effect if the error indicator and warning indicator are not set.
|
||||
* Does not print immediately; yasm_errwarn_output_all() outputs
|
||||
* accumulated errors and warnings.
|
||||
* Generally multiple errors on the same line will be reported, but errors
|
||||
* of class YASM_ERROR_PARSE will get overwritten by any other class on the
|
||||
* same line.
|
||||
* \param errwarns error/warning set
|
||||
* \param line virtual line
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
void yasm_errwarn_propagate(yasm_errwarns *errwarns, unsigned long line);
|
||||
|
||||
/** Get total number of errors logged.
|
||||
* \param errwarns error/warning set
|
||||
* \param warning_as_error if nonzero, warnings are treated as errors.
|
||||
* \return Number of errors.
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
unsigned int yasm_errwarns_num_errors(yasm_errwarns *errwarns,
|
||||
int warning_as_error);
|
||||
|
||||
/** Print out an error.
|
||||
* \param fn filename of source file
|
||||
* \param line line number
|
||||
* \param msg error message
|
||||
* \param xref_fn cross-referenced source filename
|
||||
* \param xref_line cross-referenced line number
|
||||
* \param xref_msg cross-referenced error message
|
||||
*/
|
||||
typedef void (*yasm_print_error_func)
|
||||
(const char *fn, unsigned long line, const char *msg,
|
||||
/*@null@*/ const char *xref_fn, unsigned long xref_line,
|
||||
/*@null@*/ const char *xref_msg);
|
||||
|
||||
/** Print out a warning.
|
||||
* \param fn filename of source file
|
||||
* \param line line number
|
||||
* \param msg warning message
|
||||
*/
|
||||
typedef void (*yasm_print_warning_func)
|
||||
(const char *fn, unsigned long line, const char *msg);
|
||||
|
||||
/** Outputs error/warning set in sorted order (sorted by virtual line number).
|
||||
* \param errwarns error/warning set
|
||||
* \param lm line map (to convert virtual lines into filename/line pairs)
|
||||
* \param warning_as_error if nonzero, treat warnings as errors.
|
||||
* \param print_error function called to print out errors
|
||||
* \param print_warning function called to print out warnings
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
void yasm_errwarns_output_all
|
||||
(yasm_errwarns *errwarns, yasm_linemap *lm, int warning_as_error,
|
||||
yasm_print_error_func print_error, yasm_print_warning_func print_warning);
|
||||
|
||||
/** Convert a possibly unprintable character into a printable string.
|
||||
* \internal
|
||||
* \param ch possibly unprintable character
|
||||
* \return Printable string representation (static buffer).
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
char *yasm__conv_unprint(int ch);
|
||||
|
||||
/** Hook for library users to map to gettext() if GNU gettext is being used.
|
||||
* \param msgid message catalog identifier
|
||||
* \return Translated message.
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
extern const char * (*yasm_gettext_hook) (const char *msgid);
|
||||
|
||||
#endif
|
||||
@ -0,0 +1,388 @@
|
||||
/**
|
||||
* \file libyasm/expr.h
|
||||
* \brief YASM expression interface.
|
||||
*
|
||||
* \license
|
||||
* Copyright (C) 2001-2007 Michael Urman, Peter Johnson
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* - 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_EXPR_H
|
||||
#define YASM_EXPR_H
|
||||
|
||||
#ifndef YASM_LIB_DECL
|
||||
#define YASM_LIB_DECL
|
||||
#endif
|
||||
|
||||
/** Type of an expression item. Types are listed in canonical sorting order.
|
||||
* See expr_order_terms().
|
||||
* Note #YASM_EXPR_PRECBC must be used carefully (in a-b pairs), as only
|
||||
* symrecs can become the relative term in a #yasm_value.
|
||||
*/
|
||||
typedef enum yasm_expr__type {
|
||||
YASM_EXPR_NONE = 0, /**< Nothing */
|
||||
YASM_EXPR_REG = 1<<0, /**< Register */
|
||||
YASM_EXPR_INT = 1<<1, /**< Integer value */
|
||||
YASM_EXPR_SUBST = 1<<2, /**< Substitution placeholder */
|
||||
YASM_EXPR_FLOAT = 1<<3, /**< Floating point value */
|
||||
YASM_EXPR_SYM = 1<<4, /**< Symbol */
|
||||
YASM_EXPR_PRECBC = 1<<5,/**< Direct bytecode ref (rather than via sym) */
|
||||
YASM_EXPR_EXPR = 1<<6 /**< Subexpression */
|
||||
} yasm_expr__type;
|
||||
|
||||
/** Expression item. */
|
||||
typedef struct yasm_expr__item {
|
||||
yasm_expr__type type; /**< Type */
|
||||
|
||||
/** Expression item data. Correct value depends on type. */
|
||||
union {
|
||||
yasm_bytecode *precbc; /**< Direct bytecode ref (YASM_EXPR_PRECBC) */
|
||||
yasm_symrec *sym; /**< Symbol (YASM_EXPR_SYM) */
|
||||
yasm_expr *expn; /**< Subexpression (YASM_EXPR_EXPR) */
|
||||
yasm_intnum *intn; /**< Integer value (YASM_EXPR_INT) */
|
||||
yasm_floatnum *flt; /**< Floating point value (YASM_EXPR_FLOAT) */
|
||||
uintptr_t reg; /**< Register (YASM_EXPR_REG) */
|
||||
unsigned int subst; /**< Subst placeholder (YASM_EXPR_SUBST) */
|
||||
} data;
|
||||
} yasm_expr__item;
|
||||
|
||||
/** Expression. */
|
||||
struct yasm_expr {
|
||||
yasm_expr_op op; /**< Operation. */
|
||||
unsigned long line; /**< Line number where expression was defined. */
|
||||
int numterms; /**< Number of terms in the expression. */
|
||||
|
||||
/** Terms of the expression. Structure may be extended to include more
|
||||
* terms, as some operations may allow more than two operand terms
|
||||
* (ADD, MUL, OR, AND, XOR).
|
||||
*/
|
||||
yasm_expr__item terms[2];
|
||||
};
|
||||
|
||||
/** 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 line virtual line (where expression defined)
|
||||
* \return Newly allocated expression.
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
/*@only@*/ yasm_expr *yasm_expr_create
|
||||
(yasm_expr_op op, /*@only@*/ yasm_expr__item *a,
|
||||
/*@only@*/ /*@null@*/ yasm_expr__item *b, unsigned long line);
|
||||
|
||||
/** Create a new preceding-bytecode expression item.
|
||||
* \param precbc preceding bytecode
|
||||
* \return Newly allocated expression item.
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
/*@only@*/ yasm_expr__item *yasm_expr_precbc(/*@keep@*/ yasm_bytecode *precbc);
|
||||
|
||||
/** Create a new symbol expression item.
|
||||
* \param sym symbol
|
||||
* \return Newly allocated expression item.
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
/*@only@*/ yasm_expr__item *yasm_expr_sym(/*@keep@*/ yasm_symrec *sym);
|
||||
|
||||
/** Create a new expression expression item.
|
||||
* \param e expression
|
||||
* \return Newly allocated expression item.
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
/*@only@*/ yasm_expr__item *yasm_expr_expr(/*@keep@*/ yasm_expr *e);
|
||||
|
||||
/** Create a new intnum expression item.
|
||||
* \param intn intnum
|
||||
* \return Newly allocated expression item.
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
/*@only@*/ yasm_expr__item *yasm_expr_int(/*@keep@*/ yasm_intnum *intn);
|
||||
|
||||
/** Create a new floatnum expression item.
|
||||
* \param flt floatnum
|
||||
* \return Newly allocated expression item.
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
/*@only@*/ yasm_expr__item *yasm_expr_float(/*@keep@*/ yasm_floatnum *flt);
|
||||
|
||||
/** Create a new register expression item.
|
||||
* \param reg register
|
||||
* \return Newly allocated expression item.
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
/*@only@*/ yasm_expr__item *yasm_expr_reg(uintptr_t reg);
|
||||
|
||||
/** Create a new expression tree e=l op r.
|
||||
* \param l expression for left side of new expression
|
||||
* \param o operation
|
||||
* \param r expression for right side of new expression
|
||||
* \param i line index
|
||||
* \return Newly allocated expression.
|
||||
*/
|
||||
#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 r expression for right side of new expression
|
||||
* \param i line index
|
||||
* \return Newly allocated expression.
|
||||
*/
|
||||
#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_create_ident(r,i) \
|
||||
yasm_expr_create (YASM_EXPR_IDENT, (r), (yasm_expr__item *)NULL, i)
|
||||
|
||||
/** Duplicate an expression.
|
||||
* \param e expression
|
||||
* \return Newly allocated expression identical to e.
|
||||
*/
|
||||
yasm_expr *yasm_expr_copy(const yasm_expr *e);
|
||||
#ifndef YASM_DOXYGEN
|
||||
#define yasm_expr_copy(e) yasm_expr__copy_except(e, -1)
|
||||
#endif
|
||||
|
||||
/** Destroy (free allocated memory for) an expression.
|
||||
* \param e expression
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
void yasm_expr_destroy(/*@only@*/ /*@null@*/ yasm_expr *e);
|
||||
|
||||
/** Determine if an expression is a specified operation (at the top level).
|
||||
* \param e expression
|
||||
* \param op operator
|
||||
* \return Nonzero if the expression was the specified operation at the top
|
||||
* level, zero otherwise.
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
int yasm_expr_is_op(const yasm_expr *e, yasm_expr_op op);
|
||||
|
||||
/** Extra transformation function for yasm_expr__level_tree().
|
||||
* \param e expression being simplified
|
||||
* \param d data provided as expr_xform_extra_data to
|
||||
* yasm_expr__level_tree()
|
||||
* \return Transformed e.
|
||||
*/
|
||||
typedef /*@only@*/ yasm_expr * (*yasm_expr_xform_func)
|
||||
(/*@returned@*/ /*@only@*/ yasm_expr *e, /*@null@*/ void *d);
|
||||
|
||||
/** Level an entire expression tree.
|
||||
* \internal
|
||||
* \param e expression
|
||||
* \param fold_const enable constant folding if nonzero
|
||||
* \param simplify_ident simplify identities
|
||||
* \param simplify_reg_mul simplify REG*1 identities
|
||||
* \param calc_bc_dist nonzero if distances between bytecodes should be
|
||||
* calculated, 0 if they should be left intact
|
||||
* \param expr_xform_extra extra transformation function
|
||||
* \param expr_xform_extra_data data to pass to expr_xform_extra
|
||||
* \return Leveled expression.
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
/*@only@*/ /*@null@*/ yasm_expr *yasm_expr__level_tree
|
||||
(/*@returned@*/ /*@only@*/ /*@null@*/ yasm_expr *e, int fold_const,
|
||||
int simplify_ident, int simplify_reg_mul, int calc_bc_dist,
|
||||
/*@null@*/ yasm_expr_xform_func expr_xform_extra,
|
||||
/*@null@*/ void *expr_xform_extra_data);
|
||||
|
||||
/** Simplify an expression as much as possible. Eliminates extraneous
|
||||
* branches and simplifies integer-only subexpressions. Simplified version
|
||||
* of yasm_expr__level_tree().
|
||||
* \param e expression
|
||||
* \param cbd if distance between bytecodes should be calculated
|
||||
* \return Simplified expression.
|
||||
*/
|
||||
#define yasm_expr_simplify(e, cbd) \
|
||||
yasm_expr__level_tree(e, 1, 1, 1, cbd, NULL, NULL)
|
||||
|
||||
/** Extract the segment portion of an expression containing SEG:OFF, leaving
|
||||
* the offset.
|
||||
* \param ep expression (pointer to)
|
||||
* \return NULL if unable to extract a segment (expr does not contain a
|
||||
* YASM_EXPR_SEGOFF operator), otherwise the segment expression.
|
||||
* The input expression is modified such that on return, it's the
|
||||
* offset expression.
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
/*@only@*/ /*@null@*/ yasm_expr *yasm_expr_extract_deep_segoff(yasm_expr **ep);
|
||||
|
||||
/** Extract the segment portion of a SEG:OFF expression, leaving the offset.
|
||||
* \param ep expression (pointer to)
|
||||
* \return NULL if unable to extract a segment (YASM_EXPR_SEGOFF not the
|
||||
* top-level operator), otherwise the segment expression. The input
|
||||
* expression is modified such that on return, it's the offset
|
||||
* expression.
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
/*@only@*/ /*@null@*/ yasm_expr *yasm_expr_extract_segoff(yasm_expr **ep);
|
||||
|
||||
/** Extract the right portion (y) of a x WRT y expression, leaving the left
|
||||
* portion (x).
|
||||
* \param ep expression (pointer to)
|
||||
* \return NULL if unable to extract (YASM_EXPR_WRT not the top-level
|
||||
* operator), otherwise the right side of the WRT expression. The
|
||||
* input expression is modified such that on return, it's the left side
|
||||
* of the WRT expression.
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
/*@only@*/ /*@null@*/ yasm_expr *yasm_expr_extract_wrt(yasm_expr **ep);
|
||||
|
||||
/** Get the integer value of an expression if it's just an integer.
|
||||
* \param ep expression (pointer to)
|
||||
* \param calc_bc_dist nonzero if distances between bytecodes should be
|
||||
* calculated, 0 if NULL should be returned in this case
|
||||
* \return NULL if the expression is too complex (contains anything other than
|
||||
* integers, ie floats, non-valued labels, registers); otherwise the
|
||||
* intnum value of the expression.
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
/*@dependent@*/ /*@null@*/ yasm_intnum *yasm_expr_get_intnum
|
||||
(yasm_expr **ep, int calc_bc_dist);
|
||||
|
||||
/** Get the symbol value of an expression if it's just a symbol.
|
||||
* \param ep expression (pointer to)
|
||||
* \param simplify if nonzero, simplify the expression first
|
||||
* \return NULL if the expression is too complex; otherwise the symbol value of
|
||||
* the expression.
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
/*@dependent@*/ /*@null@*/ const yasm_symrec *yasm_expr_get_symrec
|
||||
(yasm_expr **ep, int simplify);
|
||||
|
||||
/** Get the register value of an expression if it's just a register.
|
||||
* \param ep expression (pointer to)
|
||||
* \param simplify if nonzero, simplify the expression first
|
||||
* \return NULL if the expression is too complex; otherwise the register value
|
||||
* of the expression.
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
/*@dependent@*/ /*@null@*/ const uintptr_t *yasm_expr_get_reg
|
||||
(yasm_expr **ep, int simplify);
|
||||
|
||||
/** Print an expression. For debugging purposes.
|
||||
* \param e expression
|
||||
* \param f file
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
void yasm_expr_print(/*@null@*/ const yasm_expr *e, FILE *f);
|
||||
|
||||
/** Return the size of an expression, if the user provided it
|
||||
* \param e expression
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
unsigned int yasm_expr_size(const yasm_expr *e);
|
||||
|
||||
/** Return the segment of an expression, if the user provided it
|
||||
* \param e expression
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
const char *yasm_expr_segment(const yasm_expr *e);
|
||||
|
||||
/** Traverse over expression tree in order (const version).
|
||||
* Calls func for each leaf (non-operation).
|
||||
* \param e expression
|
||||
* \param d data passed to each call to func
|
||||
* \param func callback function
|
||||
* \return Stops early (and returns 1) if func returns 1.
|
||||
* Otherwise returns 0.
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
int yasm_expr__traverse_leaves_in_const
|
||||
(const yasm_expr *e, /*@null@*/ void *d,
|
||||
int (*func) (/*@null@*/ const yasm_expr__item *ei, /*@null@*/ void *d));
|
||||
|
||||
/** Traverse over expression tree in order.
|
||||
* Calls func for each leaf (non-operation).
|
||||
* \param e expression
|
||||
* \param d data passed to each call to func
|
||||
* \param func callback function
|
||||
* \return Stops early (and returns 1) if func returns 1.
|
||||
* Otherwise returns 0.
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
int yasm_expr__traverse_leaves_in
|
||||
(yasm_expr *e, /*@null@*/ void *d,
|
||||
int (*func) (/*@null@*/ yasm_expr__item *ei, /*@null@*/ void *d));
|
||||
|
||||
/** Reorder terms of e into canonical order. Only reorders if reordering
|
||||
* doesn't change meaning of expression. (eg, doesn't reorder SUB).
|
||||
* Canonical order: REG, INT, FLOAT, SYM, EXPR.
|
||||
* Multiple terms of a single type are kept in the same order as in
|
||||
* the original expression.
|
||||
* \param e expression
|
||||
* \note Only performs reordering on *one* level (no recursion).
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
void yasm_expr__order_terms(yasm_expr *e);
|
||||
|
||||
/** Copy entire expression EXCEPT for index "except" at *top level only*.
|
||||
* \param e expression
|
||||
* \param except term index not to copy; -1 to copy all terms
|
||||
* \return Newly allocated copy of expression.
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
yasm_expr *yasm_expr__copy_except(const yasm_expr *e, int except);
|
||||
|
||||
/** Test if expression contains an item. Searches recursively into
|
||||
* subexpressions.
|
||||
* \param e expression
|
||||
* \param t type of item to look for
|
||||
* \return Nonzero if expression contains an item of type t, zero if not.
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
int yasm_expr__contains(const yasm_expr *e, yasm_expr__type t);
|
||||
|
||||
/** Transform symrec-symrec terms in expression into #YASM_EXPR_SUBST items.
|
||||
* Calls the callback function for each symrec-symrec term.
|
||||
* \param ep expression (pointer to)
|
||||
* \param cbd callback data passed to callback function
|
||||
* \param callback callback function: given subst index for bytecode
|
||||
* pair, bytecode pair (bc2-bc1), and cbd (callback data)
|
||||
* \return Number of transformations made.
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
int yasm_expr__bc_dist_subst(yasm_expr **ep, void *cbd,
|
||||
void (*callback) (unsigned int subst,
|
||||
yasm_bytecode *precbc,
|
||||
yasm_bytecode *precbc2,
|
||||
void *cbd));
|
||||
|
||||
/** Substitute items into expr YASM_EXPR_SUBST items (by index). Items are
|
||||
* copied, so caller is responsible for freeing array of items.
|
||||
* \param e expression
|
||||
* \param num_items number of items in items array
|
||||
* \param items items array
|
||||
* \return 1 on error (index out of range).
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
int yasm_expr__subst(yasm_expr *e, unsigned int num_items,
|
||||
const yasm_expr__item *items);
|
||||
|
||||
#endif
|
||||
@ -0,0 +1,525 @@
|
||||
/**
|
||||
* \file libyasm/file.h
|
||||
* \brief YASM file helpers.
|
||||
*
|
||||
* \license
|
||||
* Copyright (C) 2001-2007 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_FILE_H
|
||||
#define YASM_FILE_H
|
||||
|
||||
#ifndef YASM_LIB_DECL
|
||||
#define YASM_LIB_DECL
|
||||
#endif
|
||||
|
||||
/** Re2c scanner state. */
|
||||
typedef struct yasm_scanner {
|
||||
unsigned char *bot; /**< Bottom of scan buffer */
|
||||
unsigned char *tok; /**< Start of token */
|
||||
unsigned char *ptr; /**< Scan marker */
|
||||
unsigned char *cur; /**< Cursor (1 past end of token) */
|
||||
unsigned char *lim; /**< Limit of good data */
|
||||
unsigned char *top; /**< Top of scan buffer */
|
||||
unsigned char *eof; /**< End of file */
|
||||
} yasm_scanner;
|
||||
|
||||
/** Initialize scanner state.
|
||||
* \param scanner Re2c scanner state
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
void yasm_scanner_initialize(yasm_scanner *scanner);
|
||||
|
||||
/** Frees any memory used by scanner state; does not free state itself.
|
||||
* \param scanner Re2c scanner state
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
void yasm_scanner_delete(yasm_scanner *scanner);
|
||||
|
||||
/** Fill a scanner state structure with data coming from an input function.
|
||||
* \param scanner Re2c scanner state
|
||||
* \param cursor Re2c scan cursor
|
||||
* \param input_func Input function to read data; takes buffer and maximum
|
||||
* number of bytes, returns number of bytes read.
|
||||
* \param input_func_data Data to pass as the first parameter to input_func
|
||||
* \return 1 if this was the first time this function was called on this
|
||||
* scanner state, 0 otherwise.
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
int yasm_fill_helper
|
||||
(yasm_scanner *scanner, unsigned char **cursor,
|
||||
size_t (*input_func) (void *d, unsigned char *buf, size_t max),
|
||||
void *input_func_data);
|
||||
|
||||
/** Unescape a string with C-style escapes. Handles b, f, n, r, t, and hex
|
||||
* and octal escapes. String is updated in-place.
|
||||
* Edge cases:
|
||||
* - hex escapes: reads as many hex digits as possible, takes last 2 as value.
|
||||
* - oct escapes: takes up to 3 digits 0-9 and scales appropriately, with
|
||||
* warning.
|
||||
* \param str C-style string (updated in place)
|
||||
* \param len length of string (updated with new length)
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
void yasm_unescape_cstring(unsigned char *str, size_t *len);
|
||||
|
||||
/** Split a UNIX pathname into head (directory) and tail (base filename)
|
||||
* portions.
|
||||
* \internal
|
||||
* \param path pathname
|
||||
* \param tail (returned) base filename
|
||||
* \return Length of head (directory).
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
size_t yasm__splitpath_unix(const char *path, /*@out@*/ const char **tail);
|
||||
|
||||
/** Split a Windows pathname into head (directory) and tail (base filename)
|
||||
* portions.
|
||||
* \internal
|
||||
* \param path pathname
|
||||
* \param tail (returned) base filename
|
||||
* \return Length of head (directory).
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
size_t yasm__splitpath_win(const char *path, /*@out@*/ const char **tail);
|
||||
|
||||
/** Split a pathname into head (directory) and tail (base filename) portions.
|
||||
* Unless otherwise defined, defaults to yasm__splitpath_unix().
|
||||
* \internal
|
||||
* \param path pathname
|
||||
* \param tail (returned) base filename
|
||||
* \return Length of head (directory).
|
||||
*/
|
||||
#ifndef yasm__splitpath
|
||||
# if defined (_WIN32) || defined (WIN32) || defined (__MSDOS__) || \
|
||||
defined (__DJGPP__) || defined (__OS2__)
|
||||
# define yasm__splitpath(path, tail) yasm__splitpath_win(path, tail)
|
||||
# else
|
||||
# define yasm__splitpath(path, tail) yasm__splitpath_unix(path, tail)
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/** Get the current working directory.
|
||||
* \internal
|
||||
* \return Current working directory pathname (newly allocated).
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
/*@only@*/ char *yasm__getcwd(void);
|
||||
|
||||
/** Convert a relative or absolute pathname into an absolute pathname.
|
||||
* \internal
|
||||
* \param path pathname
|
||||
* \return Absolute version of path (newly allocated).
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
/*@only@*/ char *yasm__abspath(const char *path);
|
||||
|
||||
/** Build a UNIX pathname that is equivalent to accessing the "to" pathname
|
||||
* when you're in the directory containing "from". Result is relative if both
|
||||
* from and to are relative.
|
||||
* \internal
|
||||
* \param from from pathname
|
||||
* \param to to pathname
|
||||
* \return Combined path (newly allocated).
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
char *yasm__combpath_unix(const char *from, const char *to);
|
||||
|
||||
/** Build a Windows pathname that is equivalent to accessing the "to" pathname
|
||||
* when you're in the directory containing "from". Result is relative if both
|
||||
* from and to are relative.
|
||||
* \internal
|
||||
* \param from from pathname
|
||||
* \param to to pathname
|
||||
* \return Combined path (newly allocated).
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
char *yasm__combpath_win(const char *from, const char *to);
|
||||
|
||||
/** Build a pathname that is equivalent to accessing the "to" pathname
|
||||
* when you're in the directory containing "from". Result is relative if both
|
||||
* from and to are relative.
|
||||
* Unless otherwise defined, defaults to yasm__combpath_unix().
|
||||
* \internal
|
||||
* \param from from pathname
|
||||
* \param to to pathname
|
||||
* \return Combined path (newly allocated).
|
||||
*/
|
||||
#ifndef yasm__combpath
|
||||
# if defined (_WIN32) || defined (WIN32) || defined (__MSDOS__) || \
|
||||
defined (__DJGPP__) || defined (__OS2__)
|
||||
# define yasm__combpath(from, to) yasm__combpath_win(from, to)
|
||||
# else
|
||||
# define yasm__combpath(from, to) yasm__combpath_unix(from, to)
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/** Recursively create tree of directories needed for pathname.
|
||||
* \internal
|
||||
* \param path pathname
|
||||
* \param win handle windows paths
|
||||
* \return Length of directory portion of pathname.
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
size_t yasm__createpath_common(const char *path, int win);
|
||||
|
||||
/** Recursively create tree of directories needed for pathname.
|
||||
* Unless otherwise defined, defaults to yasm__createpath_unix().
|
||||
* \internal
|
||||
* \param path pathname
|
||||
* \return Length of directory portion of pathname.
|
||||
*/
|
||||
#ifndef yasm__createpath
|
||||
# if defined (_WIN32) || defined (WIN32) || defined (__MSDOS__) || \
|
||||
defined (__DJGPP__) || defined (__OS2__)
|
||||
# define yasm__createpath(path) yasm__createpath_common(path, 1)
|
||||
# else
|
||||
# define yasm__createpath(path) yasm__createpath_common(path, 0)
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/** Try to find and open an include file, searching through include paths.
|
||||
* First iname is looked for relative to the directory containing "from", then
|
||||
* it's looked for relative to each of the include paths.
|
||||
*
|
||||
* All pathnames may be either absolute or relative; from, oname, and
|
||||
* include paths, if relative, are relative from the current working directory.
|
||||
*
|
||||
* First match wins; the full pathname (newly allocated) to the opened file
|
||||
* is saved into oname, and the fopen'ed FILE * is returned. If not found,
|
||||
* NULL is returned.
|
||||
*
|
||||
* \param iname file to include
|
||||
* \param from file doing the including
|
||||
* \param mode fopen mode string
|
||||
* \param oname full pathname of included file (may be relative). NULL
|
||||
* may be passed if this is unwanted.
|
||||
* \return fopen'ed include file, or NULL if not found.
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
/*@null@*/ FILE *yasm_fopen_include
|
||||
(const char *iname, const char *from, const char *mode,
|
||||
/*@null@*/ /*@out@*/ /*@only@*/ char **oname);
|
||||
|
||||
/** Delete any stored include paths added by yasm_add_include_path().
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
void yasm_delete_include_paths(void);
|
||||
|
||||
/** Iterate through include paths.
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
const char * yasm_get_include_dir(void **iter);
|
||||
|
||||
/** Add an include path for use by yasm_fopen_include().
|
||||
* If path is relative, it is treated by yasm_fopen_include() as relative to
|
||||
* the current working directory.
|
||||
*
|
||||
* \param path path to add
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
void yasm_add_include_path(const char *path);
|
||||
|
||||
/** Write an 8-bit value to a buffer, incrementing buffer pointer.
|
||||
* \note Only works properly if ptr is an (unsigned char *).
|
||||
* \param ptr buffer
|
||||
* \param val 8-bit value
|
||||
*/
|
||||
#define YASM_WRITE_8(ptr, val) \
|
||||
*((ptr)++) = (unsigned char)((val) & 0xFF)
|
||||
|
||||
/** Write a 16-bit value to a buffer in little endian, incrementing buffer
|
||||
* pointer.
|
||||
* \note Only works properly if ptr is an (unsigned char *).
|
||||
* \param ptr buffer
|
||||
* \param val 16-bit value
|
||||
*/
|
||||
#define YASM_WRITE_16_L(ptr, val) \
|
||||
do { \
|
||||
*((ptr)++) = (unsigned char)((val) & 0xFF); \
|
||||
*((ptr)++) = (unsigned char)(((val) >> 8) & 0xFF); \
|
||||
} while (0)
|
||||
|
||||
/** Write a 32-bit value to a buffer in little endian, incrementing buffer
|
||||
* pointer.
|
||||
* \note Only works properly if ptr is an (unsigned char *).
|
||||
* \param ptr buffer
|
||||
* \param val 32-bit value
|
||||
*/
|
||||
#define YASM_WRITE_32_L(ptr, val) \
|
||||
do { \
|
||||
*((ptr)++) = (unsigned char)((val) & 0xFF); \
|
||||
*((ptr)++) = (unsigned char)(((val) >> 8) & 0xFF); \
|
||||
*((ptr)++) = (unsigned char)(((val) >> 16) & 0xFF); \
|
||||
*((ptr)++) = (unsigned char)(((val) >> 24) & 0xFF); \
|
||||
} while (0)
|
||||
|
||||
/** Write a 16-bit value to a buffer in big endian, incrementing buffer
|
||||
* pointer.
|
||||
* \note Only works properly if ptr is an (unsigned char *).
|
||||
* \param ptr buffer
|
||||
* \param val 16-bit value
|
||||
*/
|
||||
#define YASM_WRITE_16_B(ptr, val) \
|
||||
do { \
|
||||
*((ptr)++) = (unsigned char)(((val) >> 8) & 0xFF); \
|
||||
*((ptr)++) = (unsigned char)((val) & 0xFF); \
|
||||
} while (0)
|
||||
|
||||
/** Write a 32-bit value to a buffer in big endian, incrementing buffer
|
||||
* pointer.
|
||||
* \note Only works properly if ptr is an (unsigned char *).
|
||||
* \param ptr buffer
|
||||
* \param val 32-bit value
|
||||
*/
|
||||
#define YASM_WRITE_32_B(ptr, val) \
|
||||
do { \
|
||||
*((ptr)++) = (unsigned char)(((val) >> 24) & 0xFF); \
|
||||
*((ptr)++) = (unsigned char)(((val) >> 16) & 0xFF); \
|
||||
*((ptr)++) = (unsigned char)(((val) >> 8) & 0xFF); \
|
||||
*((ptr)++) = (unsigned char)((val) & 0xFF); \
|
||||
} while (0)
|
||||
|
||||
|
||||
/** Write an 8-bit value to a buffer. Does not increment buffer pointer.
|
||||
* \note Only works properly if ptr is an (unsigned char *).
|
||||
* \param ptr buffer
|
||||
* \param val 8-bit value
|
||||
*/
|
||||
#define YASM_SAVE_8(ptr, val) \
|
||||
*(ptr) = (unsigned char)((val) & 0xFF)
|
||||
|
||||
/** Write a 16-bit value to a buffer in little endian. Does not increment
|
||||
* buffer pointer.
|
||||
* \note Only works properly if ptr is an (unsigned char *).
|
||||
* \param ptr buffer
|
||||
* \param val 16-bit value
|
||||
*/
|
||||
#define YASM_SAVE_16_L(ptr, val) \
|
||||
do { \
|
||||
*(ptr) = (unsigned char)((val) & 0xFF); \
|
||||
*((ptr)+1) = (unsigned char)(((val) >> 8) & 0xFF); \
|
||||
} while (0)
|
||||
|
||||
/** Write a 32-bit value to a buffer in little endian. Does not increment
|
||||
* buffer pointer.
|
||||
* \note Only works properly if ptr is an (unsigned char *).
|
||||
* \param ptr buffer
|
||||
* \param val 32-bit value
|
||||
*/
|
||||
#define YASM_SAVE_32_L(ptr, val) \
|
||||
do { \
|
||||
*(ptr) = (unsigned char)((val) & 0xFF); \
|
||||
*((ptr)+1) = (unsigned char)(((val) >> 8) & 0xFF); \
|
||||
*((ptr)+2) = (unsigned char)(((val) >> 16) & 0xFF); \
|
||||
*((ptr)+3) = (unsigned char)(((val) >> 24) & 0xFF); \
|
||||
} while (0)
|
||||
|
||||
/** Write a 16-bit value to a buffer in big endian. Does not increment buffer
|
||||
* pointer.
|
||||
* \note Only works properly if ptr is an (unsigned char *).
|
||||
* \param ptr buffer
|
||||
* \param val 16-bit value
|
||||
*/
|
||||
#define YASM_SAVE_16_B(ptr, val) \
|
||||
do { \
|
||||
*(ptr) = (unsigned char)(((val) >> 8) & 0xFF); \
|
||||
*((ptr)+1) = (unsigned char)((val) & 0xFF); \
|
||||
} while (0)
|
||||
|
||||
/** Write a 32-bit value to a buffer in big endian. Does not increment buffer
|
||||
* pointer.
|
||||
* \note Only works properly if ptr is an (unsigned char *).
|
||||
* \param ptr buffer
|
||||
* \param val 32-bit value
|
||||
*/
|
||||
#define YASM_SAVE_32_B(ptr, val) \
|
||||
do { \
|
||||
*(ptr) = (unsigned char)(((val) >> 24) & 0xFF); \
|
||||
*((ptr)+1) = (unsigned char)(((val) >> 16) & 0xFF); \
|
||||
*((ptr)+2) = (unsigned char)(((val) >> 8) & 0xFF); \
|
||||
*((ptr)+3) = (unsigned char)((val) & 0xFF); \
|
||||
} while (0)
|
||||
|
||||
/** Direct-to-file version of YASM_SAVE_16_L().
|
||||
* \note Using the macro multiple times with a single fwrite() call will
|
||||
* probably be faster than calling this function many times.
|
||||
* \param val 16-bit value
|
||||
* \param f file
|
||||
* \return 1 if the write was successful, 0 if not (just like fwrite()).
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
size_t yasm_fwrite_16_l(unsigned short val, FILE *f);
|
||||
|
||||
/** Direct-to-file version of YASM_SAVE_32_L().
|
||||
* \note Using the macro multiple times with a single fwrite() call will
|
||||
* probably be faster than calling this function many times.
|
||||
* \param val 32-bit value
|
||||
* \param f file
|
||||
* \return 1 if the write was successful, 0 if not (just like fwrite()).
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
size_t yasm_fwrite_32_l(unsigned long val, FILE *f);
|
||||
|
||||
/** Direct-to-file version of YASM_SAVE_16_B().
|
||||
* \note Using the macro multiple times with a single fwrite() call will
|
||||
* probably be faster than calling this function many times.
|
||||
* \param val 16-bit value
|
||||
* \param f file
|
||||
* \return 1 if the write was successful, 0 if not (just like fwrite()).
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
size_t yasm_fwrite_16_b(unsigned short val, FILE *f);
|
||||
|
||||
/** Direct-to-file version of YASM_SAVE_32_B().
|
||||
* \note Using the macro multiple times with a single fwrite() call will
|
||||
* probably be faster than calling this function many times.
|
||||
* \param val 32-bit value
|
||||
* \param f file
|
||||
* \return 1 if the write was successful, 0 if not (just like fwrite()).
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
size_t yasm_fwrite_32_b(unsigned long val, FILE *f);
|
||||
|
||||
/** Read an 8-bit value from a buffer, incrementing buffer pointer.
|
||||
* \note Only works properly if ptr is an (unsigned char *).
|
||||
* \param ptr buffer
|
||||
* \param val 8-bit value
|
||||
*/
|
||||
#define YASM_READ_8(val, ptr) \
|
||||
(val) = *((ptr)++) & 0xFF
|
||||
|
||||
/** Read a 16-bit value from a buffer in little endian, incrementing buffer
|
||||
* pointer.
|
||||
* \note Only works properly if ptr is an (unsigned char *).
|
||||
* \param ptr buffer
|
||||
* \param val 16-bit value
|
||||
*/
|
||||
#define YASM_READ_16_L(val, ptr) \
|
||||
do { \
|
||||
(val) = *((ptr)++) & 0xFF; \
|
||||
(val) |= (*((ptr)++) & 0xFF) << 8; \
|
||||
} while (0)
|
||||
|
||||
/** Read a 32-bit value from a buffer in little endian, incrementing buffer
|
||||
* pointer.
|
||||
* \note Only works properly if ptr is an (unsigned char *).
|
||||
* \param ptr buffer
|
||||
* \param val 32-bit value
|
||||
*/
|
||||
#define YASM_READ_32_L(val, ptr) \
|
||||
do { \
|
||||
(val) = *((ptr)++) & 0xFF; \
|
||||
(val) |= (*((ptr)++) & 0xFF) << 8; \
|
||||
(val) |= (*((ptr)++) & 0xFF) << 16; \
|
||||
(val) |= (*((ptr)++) & 0xFF) << 24; \
|
||||
} while (0)
|
||||
|
||||
/** Read a 16-bit value from a buffer in big endian, incrementing buffer
|
||||
* pointer.
|
||||
* \note Only works properly if ptr is an (unsigned char *).
|
||||
* \param ptr buffer
|
||||
* \param val 16-bit value
|
||||
*/
|
||||
#define YASM_READ_16_B(val, ptr) \
|
||||
do { \
|
||||
(val) = (*((ptr)++) & 0xFF) << 8; \
|
||||
(val) |= *((ptr)++) & 0xFF; \
|
||||
} while (0)
|
||||
|
||||
/** Read a 32-bit value from a buffer in big endian, incrementing buffer
|
||||
* pointer.
|
||||
* \note Only works properly if ptr is an (unsigned char *).
|
||||
* \param ptr buffer
|
||||
* \param val 32-bit value
|
||||
*/
|
||||
#define YASM_READ_32_B(val, ptr) \
|
||||
do { \
|
||||
(val) = (*((ptr)++) & 0xFF) << 24; \
|
||||
(val) |= (*((ptr)++) & 0xFF) << 16; \
|
||||
(val) |= (*((ptr)++) & 0xFF) << 8; \
|
||||
(val) |= *((ptr)++) & 0xFF; \
|
||||
} while (0)
|
||||
|
||||
/** Read an 8-bit value from a buffer. Does not increment buffer pointer.
|
||||
* \note Only works properly if ptr is an (unsigned char *).
|
||||
* \param ptr buffer
|
||||
* \param val 8-bit value
|
||||
*/
|
||||
#define YASM_LOAD_8(val, ptr) \
|
||||
(val) = *(ptr) & 0xFF
|
||||
|
||||
/** Read a 16-bit value from a buffer in little endian. Does not increment
|
||||
* buffer pointer.
|
||||
* \note Only works properly if ptr is an (unsigned char *).
|
||||
* \param ptr buffer
|
||||
* \param val 16-bit value
|
||||
*/
|
||||
#define YASM_LOAD_16_L(val, ptr) \
|
||||
do { \
|
||||
(val) = *(ptr) & 0xFF; \
|
||||
(val) |= (*((ptr)+1) & 0xFF) << 8; \
|
||||
} while (0)
|
||||
|
||||
/** Read a 32-bit value from a buffer in little endian. Does not increment
|
||||
* buffer pointer.
|
||||
* \note Only works properly if ptr is an (unsigned char *).
|
||||
* \param ptr buffer
|
||||
* \param val 32-bit value
|
||||
*/
|
||||
#define YASM_LOAD_32_L(val, ptr) \
|
||||
do { \
|
||||
(val) = (unsigned long)(*(ptr) & 0xFF); \
|
||||
(val) |= (unsigned long)((*((ptr)+1) & 0xFF) << 8); \
|
||||
(val) |= (unsigned long)((*((ptr)+2) & 0xFF) << 16); \
|
||||
(val) |= (unsigned long)((*((ptr)+3) & 0xFF) << 24); \
|
||||
} while (0)
|
||||
|
||||
/** Read a 16-bit value from a buffer in big endian. Does not increment buffer
|
||||
* pointer.
|
||||
* \note Only works properly if ptr is an (unsigned char *).
|
||||
* \param ptr buffer
|
||||
* \param val 16-bit value
|
||||
*/
|
||||
#define YASM_LOAD_16_B(val, ptr) \
|
||||
do { \
|
||||
(val) = (*(ptr) & 0xFF) << 8; \
|
||||
(val) |= *((ptr)+1) & 0xFF; \
|
||||
} while (0)
|
||||
|
||||
/** Read a 32-bit value from a buffer in big endian. Does not increment buffer
|
||||
* pointer.
|
||||
* \note Only works properly if ptr is an (unsigned char *).
|
||||
* \param ptr buffer
|
||||
* \param val 32-bit value
|
||||
*/
|
||||
#define YASM_LOAD_32_B(val, ptr) \
|
||||
do { \
|
||||
(val) = (unsigned long)((*(ptr) & 0xFF) << 24); \
|
||||
(val) |= (unsigned long)((*((ptr)+1) & 0xFF) << 16); \
|
||||
(val) |= (unsigned long)((*((ptr)+2) & 0xFF) << 8); \
|
||||
(val) |= (unsigned long)(*((ptr)+3) & 0xFF); \
|
||||
} while (0)
|
||||
|
||||
#endif
|
||||
@ -0,0 +1,131 @@
|
||||
/**
|
||||
* \file libyasm/floatnum.h
|
||||
* \brief YASM floating point (IEEE) interface.
|
||||
*
|
||||
* \license
|
||||
* Copyright (C) 2001-2007 Peter Johnson
|
||||
*
|
||||
* Based on public-domain x86 assembly code by Randall Hyde (8/28/91).
|
||||
*
|
||||
* 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_FLOATNUM_H
|
||||
#define YASM_FLOATNUM_H
|
||||
|
||||
#ifndef YASM_LIB_DECL
|
||||
#define YASM_LIB_DECL
|
||||
#endif
|
||||
|
||||
/** Initialize floatnum internal data structures. */
|
||||
YASM_LIB_DECL
|
||||
void yasm_floatnum_initialize(void);
|
||||
|
||||
/** Clean up internal floatnum allocations. */
|
||||
YASM_LIB_DECL
|
||||
void yasm_floatnum_cleanup(void);
|
||||
|
||||
/** Create a new floatnum from a decimal string. The input string must be in
|
||||
* standard C representation ([+-]123.456e[-+]789).
|
||||
* \param str floating point decimal string
|
||||
* \return Newly allocated floatnum.
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
/*@only@*/ yasm_floatnum *yasm_floatnum_create(const char *str);
|
||||
|
||||
/** Duplicate a floatnum.
|
||||
* \param flt floatnum
|
||||
* \return Newly allocated floatnum with the same value as flt.
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
/*@only@*/ yasm_floatnum *yasm_floatnum_copy(const yasm_floatnum *flt);
|
||||
|
||||
/** Destroy (free allocated memory for) a floatnum.
|
||||
* \param flt floatnum
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
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
|
||||
* operations will result in an error.
|
||||
* \param acc floatnum accumulator
|
||||
* \param op operation
|
||||
* \param operand floatnum operand
|
||||
* \return Nonzero on error.
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
int yasm_floatnum_calc(yasm_floatnum *acc, yasm_expr_op op,
|
||||
yasm_floatnum *operand);
|
||||
|
||||
/** Convert a floatnum to single-precision and return as 32-bit value.
|
||||
* The 32-bit value is a "standard" C value (eg, of unknown endian).
|
||||
* \param flt floatnum
|
||||
* \param ret_val pointer to storage for 32-bit output
|
||||
* \return Nonzero if flt can't fit into single precision: -1 if underflow
|
||||
* occurred, 1 if overflow occurred.
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
int yasm_floatnum_get_int(const yasm_floatnum *flt,
|
||||
/*@out@*/ unsigned long *ret_val);
|
||||
|
||||
/** Output a #yasm_floatnum to buffer in little-endian or big-endian. Puts the
|
||||
* value into the least significant bits of the destination, or may be shifted
|
||||
* into more significant bits by the shift parameter. The destination bits are
|
||||
* cleared before being set. [0] should be the first byte output to the file.
|
||||
* \note Not all sizes are valid. Currently, only 32 (single-precision), 64
|
||||
* (double-precision), and 80 (extended-precision) are valid sizes.
|
||||
* Use yasm_floatnum_check_size() to check for supported sizes.
|
||||
* \param flt floatnum
|
||||
* \param ptr pointer to storage for size bytes of output
|
||||
* \param destsize destination size (in bytes)
|
||||
* \param valsize size (in bits)
|
||||
* \param shift left shift (in bits)
|
||||
* \param bigendian endianness (nonzero=big, zero=little)
|
||||
* \param warn enables standard overflow/underflow warnings
|
||||
* \return Nonzero if flt can't fit into the specified precision: -1 if
|
||||
* underflow occurred, 1 if overflow occurred.
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
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);
|
||||
|
||||
/** Basic check to see if size is valid for flt conversion (using
|
||||
* yasm_floatnum_get_sized()). Doesn't actually check for underflow/overflow
|
||||
* but rather checks for size=32,64,80
|
||||
* (at present).
|
||||
* \param flt floatnum
|
||||
* \param size number of bits of output space
|
||||
* \return 1 if valid size, 0 if invalid size.
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
int yasm_floatnum_check_size(const yasm_floatnum *flt, size_t size);
|
||||
|
||||
/** Print various representations of a floatnum. For debugging purposes only.
|
||||
* \param f file
|
||||
* \param flt floatnum
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
void yasm_floatnum_print(const yasm_floatnum *flt, FILE *f);
|
||||
|
||||
#endif
|
||||
@ -0,0 +1,123 @@
|
||||
/**
|
||||
* \file libyasm/hamt.h
|
||||
* \brief Hash Array Mapped Trie (HAMT) functions.
|
||||
*
|
||||
* \license
|
||||
* Copyright (C) 2001-2007 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.
|
||||
* \endlicense
|
||||
*/
|
||||
#ifndef YASM_HAMT_H
|
||||
#define YASM_HAMT_H
|
||||
|
||||
#ifndef YASM_LIB_DECL
|
||||
#define YASM_LIB_DECL
|
||||
#endif
|
||||
|
||||
/** Hash array mapped trie data structure (opaque type). */
|
||||
typedef struct HAMT HAMT;
|
||||
/** Hash array mapped trie entry (opaque type). */
|
||||
typedef struct HAMTEntry HAMTEntry;
|
||||
|
||||
/** Create new, empty, HAMT. error_func() is called when an internal error is
|
||||
* encountered--it should NOT return to the calling function.
|
||||
* \param nocase nonzero if HAMT should be case-insensitive
|
||||
* \param error_func function called on internal error
|
||||
* \return New, empty, hash array mapped trie.
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
HAMT *HAMT_create(int nocase, /*@exits@*/ void (*error_func)
|
||||
(const char *file, unsigned int line, const char *message));
|
||||
|
||||
/** Delete HAMT and all data associated with it. Uses deletefunc() to delete
|
||||
* each data item.
|
||||
* \param hamt Hash array mapped trie
|
||||
* \param deletefunc Data deletion function
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
void HAMT_destroy(/*@only@*/ HAMT *hamt,
|
||||
void (*deletefunc) (/*@only@*/ void *data));
|
||||
|
||||
/** Insert key into HAMT, associating it with data.
|
||||
* If the key is not present in the HAMT, inserts it, sets *replace to 1, and
|
||||
* returns the data passed in.
|
||||
* If the key is already present and *replace is 0, deletes the data passed
|
||||
* in using deletefunc() and returns the data currently associated with the
|
||||
* key.
|
||||
* If the key is already present and *replace is 1, deletes the data currently
|
||||
* associated with the key using deletefunc() and replaces it with the data
|
||||
* passed in.
|
||||
* \param hamt Hash array mapped trie
|
||||
* \param str Key
|
||||
* \param data Data to associate with key
|
||||
* \param replace See above description
|
||||
* \param deletefunc Data deletion function if data is replaced
|
||||
* \return Data now associated with key.
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
/*@dependent@*/ void *HAMT_insert(HAMT *hamt, /*@dependent@*/ const char *str,
|
||||
/*@only@*/ void *data, int *replace,
|
||||
void (*deletefunc) (/*@only@*/ void *data));
|
||||
|
||||
/** Search for the data associated with a key in the HAMT.
|
||||
* \param hamt Hash array mapped trie
|
||||
* \param str Key
|
||||
* \return NULL if key/data not present in HAMT, otherwise associated data.
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
/*@dependent@*/ /*@null@*/ void *HAMT_search(HAMT *hamt, const char *str);
|
||||
|
||||
/** Traverse over all keys in HAMT, calling function on each data item.
|
||||
* \param hamt Hash array mapped trie
|
||||
* \param d Data to pass to each call to func.
|
||||
* \param func Function to call
|
||||
* \return Stops early (and returns func's return value) if func returns a
|
||||
* nonzero value; otherwise 0.
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
int HAMT_traverse(HAMT *hamt, /*@null@*/ void *d,
|
||||
int (*func) (/*@dependent@*/ /*@null@*/ void *node,
|
||||
/*@null@*/ void *d));
|
||||
|
||||
/** Get the first entry in a HAMT.
|
||||
* \param hamt Hash array mapped trie
|
||||
* \return First entry in HAMT, or NULL if HAMT is empty.
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
const HAMTEntry *HAMT_first(const HAMT *hamt);
|
||||
|
||||
/** Get the next entry in a HAMT.
|
||||
* \param prev Previous entry in HAMT
|
||||
* \return Next entry in HAMT, or NULL if no more entries.
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
/*@null@*/ const HAMTEntry *HAMT_next(const HAMTEntry *prev);
|
||||
|
||||
/** Get the corresponding data for a HAMT entry.
|
||||
* \param entry HAMT entry (as returned by HAMT_first() and HAMT_next())
|
||||
* \return Corresponding data item.
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
void *HAMTEntry_get_data(const HAMTEntry *entry);
|
||||
|
||||
#endif
|
||||
@ -0,0 +1,269 @@
|
||||
/**
|
||||
* \file libyasm/insn.h
|
||||
* \brief YASM mnenomic instruction.
|
||||
*
|
||||
* \license
|
||||
* Copyright (C) 2002-2007 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_INSN_H
|
||||
#define YASM_INSN_H
|
||||
|
||||
#ifndef YASM_LIB_DECL
|
||||
#define YASM_LIB_DECL
|
||||
#endif
|
||||
|
||||
/** Base structure for an effective address. As with all base
|
||||
* structures, must be present as the first element in any
|
||||
* #yasm_arch implementation of an effective address.
|
||||
*/
|
||||
struct yasm_effaddr {
|
||||
yasm_value disp; /**< address displacement */
|
||||
|
||||
/** Segment register override (0 if none). */
|
||||
uintptr_t segreg;
|
||||
|
||||
/** 1 if length of disp must be >0. */
|
||||
unsigned int need_nonzero_len:1;
|
||||
|
||||
/** 1 if a displacement should be present in the output. */
|
||||
unsigned int need_disp:1;
|
||||
|
||||
/** 1 if reg*2 should not be split into reg+reg. (0 if not).
|
||||
* This flag indicates (for architectures that support complex effective
|
||||
* addresses such as x86) if various types of complex effective addresses
|
||||
* can be split into different forms in order to minimize instruction
|
||||
* length.
|
||||
*/
|
||||
unsigned int nosplit:1;
|
||||
|
||||
/** 1 if effective address is /definitely/ an effective address.
|
||||
* This is used in e.g. the GAS parser to differentiate
|
||||
* between "expr" (which might or might not be an effective address) and
|
||||
* "expr(,1)" (which is definitely an effective address).
|
||||
*/
|
||||
unsigned int strong:1;
|
||||
|
||||
/** 1 if effective address is forced PC-relative. */
|
||||
unsigned int pc_rel:1;
|
||||
|
||||
/** 1 if effective address is forced non-PC-relative. */
|
||||
unsigned int not_pc_rel:1;
|
||||
|
||||
/** length of pointed data (in bytes), 0 if unknown. */
|
||||
unsigned int data_len;
|
||||
};
|
||||
|
||||
/** An instruction operand (opaque type). */
|
||||
typedef struct yasm_insn_operand yasm_insn_operand;
|
||||
|
||||
/** The type of an instruction operand. */
|
||||
typedef enum yasm_insn_operand_type {
|
||||
YASM_INSN__OPERAND_REG = 1, /**< A register. */
|
||||
YASM_INSN__OPERAND_SEGREG, /**< A segment register. */
|
||||
YASM_INSN__OPERAND_MEMORY, /**< An effective address
|
||||
* (memory reference). */
|
||||
YASM_INSN__OPERAND_IMM /**< An immediate or jump target. */
|
||||
} yasm_insn_operand_type;
|
||||
|
||||
/** An instruction operand. */
|
||||
struct yasm_insn_operand {
|
||||
/** Link for building linked list of operands. \internal */
|
||||
/*@reldef@*/ STAILQ_ENTRY(yasm_insn_operand) link;
|
||||
|
||||
/** Operand data. */
|
||||
union {
|
||||
uintptr_t reg; /**< Arch data for reg/segreg. */
|
||||
yasm_effaddr *ea; /**< Effective address for memory references. */
|
||||
yasm_expr *val; /**< Value of immediate or jump target. */
|
||||
} data;
|
||||
|
||||
yasm_expr *seg; /**< Segment expression */
|
||||
|
||||
uintptr_t targetmod; /**< Arch target modifier, 0 if none. */
|
||||
|
||||
/** Specified size of the operand, in bits. 0 if not user-specified. */
|
||||
unsigned int size:16;
|
||||
|
||||
/** Nonzero if dereference. Used for "*foo" in GAS.
|
||||
* The reason for this is that by default in GAS, an unprefixed value
|
||||
* is a memory address, except for jumps/calls, in which case it needs a
|
||||
* "*" prefix to become a memory address (otherwise it's an immediate).
|
||||
* This isn't knowable in the parser stage, so the parser sets this flag
|
||||
* to indicate the "*" prefix has been used, and the arch needs to adjust
|
||||
* the operand type appropriately depending on the instruction type.
|
||||
*/
|
||||
unsigned int deref:1;
|
||||
|
||||
/** Nonzero if strict. Used for "strict foo" in NASM.
|
||||
* This is used to inhibit optimization on otherwise "sized" values.
|
||||
* For example, the user may just want to be explicit with the size on
|
||||
* "push dword 4", but not actually want to force the immediate size to
|
||||
* 4 bytes (rather wanting the optimizer to optimize it down to 1 byte as
|
||||
* though "dword" was not specified). To indicate the immediate should
|
||||
* actually be forced to 4 bytes, the user needs to write
|
||||
* "push strict dword 4", which sets this flag.
|
||||
*/
|
||||
unsigned int strict:1;
|
||||
|
||||
/** Operand type. */
|
||||
unsigned int type:4;
|
||||
};
|
||||
|
||||
/** Base structure for "instruction" bytecodes. These are the mnenomic
|
||||
* (rather than raw) representation of instructions. As with all base
|
||||
* structures, must be present as the first element in any
|
||||
* #yasm_arch implementation of mnenomic instruction bytecodes.
|
||||
*/
|
||||
struct yasm_insn {
|
||||
/** Linked list of operands. */
|
||||
/*@reldef@*/ STAILQ_HEAD(yasm_insn_operands, yasm_insn_operand) operands;
|
||||
|
||||
/** Array of prefixes. */
|
||||
/*@null@*/ uintptr_t *prefixes;
|
||||
|
||||
/** Array of segment prefixes. */
|
||||
/*@null@*/ uintptr_t *segregs;
|
||||
|
||||
unsigned int num_operands; /**< Number of operands. */
|
||||
unsigned int num_prefixes; /**< Number of prefixes. */
|
||||
unsigned int num_segregs; /**< Number of segment prefixes. */
|
||||
};
|
||||
|
||||
/** Set segment override for an effective address.
|
||||
* Some architectures (such as x86) support segment overrides on effective
|
||||
* addresses. A override of an override will result in a warning.
|
||||
* \param ea effective address
|
||||
* \param segreg segment register (0 if none)
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
void yasm_ea_set_segreg(yasm_effaddr *ea, uintptr_t segreg);
|
||||
|
||||
/** Create an instruction operand from a register.
|
||||
* \param reg register
|
||||
* \return Newly allocated operand.
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
yasm_insn_operand *yasm_operand_create_reg(uintptr_t reg);
|
||||
|
||||
/** Create an instruction operand from a segment register.
|
||||
* \param segreg segment register
|
||||
* \return Newly allocated operand.
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
yasm_insn_operand *yasm_operand_create_segreg(uintptr_t segreg);
|
||||
|
||||
/** Create an instruction operand from an effective address.
|
||||
* \param ea effective address
|
||||
* \return Newly allocated operand.
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
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
|
||||
* #yasm_insn_operand.
|
||||
* \param val immediate expression
|
||||
* \return Newly allocated operand.
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
yasm_insn_operand *yasm_operand_create_imm(/*@only@*/ yasm_expr *val);
|
||||
|
||||
/** Get the first operand in an instruction.
|
||||
* \param insn instruction
|
||||
* \return First operand (NULL if no operands).
|
||||
*/
|
||||
yasm_insn_operand *yasm_insn_ops_first(yasm_insn *insn);
|
||||
#define yasm_insn_ops_first(insn) STAILQ_FIRST(&((insn)->operands))
|
||||
|
||||
/** Get the next operand in an instruction.
|
||||
* \param op previous operand
|
||||
* \return Next operand (NULL if op was the last operand).
|
||||
*/
|
||||
yasm_insn_operand *yasm_insn_op_next(yasm_insn_operand *op);
|
||||
#define yasm_insn_op_next(cur) STAILQ_NEXT(cur, link)
|
||||
|
||||
/** Add operand to the end of an instruction.
|
||||
* \note Does not make a copy of the operand; so don't pass this function
|
||||
* static or local variables, and discard the op pointer after calling
|
||||
* this function.
|
||||
* \param insn instruction
|
||||
* \param op operand (may be NULL)
|
||||
* \return If operand was actually appended (it wasn't NULL), the operand;
|
||||
* otherwise NULL.
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
/*@null@*/ yasm_insn_operand *yasm_insn_ops_append
|
||||
(yasm_insn *insn,
|
||||
/*@returned@*/ /*@null@*/ yasm_insn_operand *op);
|
||||
|
||||
/** Associate a prefix with an instruction.
|
||||
* \param insn instruction
|
||||
* \param prefix data that identifies the prefix
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
void yasm_insn_add_prefix(yasm_insn *insn, uintptr_t prefix);
|
||||
|
||||
/** Associate a segment prefix with an instruction.
|
||||
* \param insn instruction
|
||||
* \param segreg data that identifies the segment register
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
void yasm_insn_add_seg_prefix(yasm_insn *insn, uintptr_t segreg);
|
||||
|
||||
/** Initialize the common parts of an instruction.
|
||||
* \internal For use by yasm_arch implementations only.
|
||||
* \param insn instruction
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
void yasm_insn_initialize(/*@out@*/ yasm_insn *insn);
|
||||
|
||||
/** Delete the common parts of an instruction.
|
||||
* \internal For use by yasm_arch implementations only.
|
||||
* \param insn instruction
|
||||
* \param content if nonzero, deletes content of each operand
|
||||
* \param arch architecture
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
void yasm_insn_delete(yasm_insn *insn,
|
||||
void (*ea_destroy) (/*@only@*/ yasm_effaddr *));
|
||||
|
||||
/** Print a list of instruction operands. For debugging purposes.
|
||||
* \internal For use by yasm_arch implementations only.
|
||||
* \param insn instruction
|
||||
* \param f file
|
||||
* \param indent_level indentation level
|
||||
* \param arch architecture
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
void yasm_insn_print(const yasm_insn *insn, FILE *f, int indent_level);
|
||||
|
||||
/** Finalize the common parts of an instruction.
|
||||
* \internal For use by yasm_arch implementations only.
|
||||
* \param insn instruction
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
void yasm_insn_finalize(yasm_insn *insn);
|
||||
|
||||
#endif
|
||||
@ -0,0 +1,340 @@
|
||||
/**
|
||||
* \file libyasm/intnum.h
|
||||
* \brief YASM integer number interface.
|
||||
*
|
||||
* \license
|
||||
* Copyright (C) 2001-2007 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_INTNUM_H
|
||||
#define YASM_INTNUM_H
|
||||
|
||||
#ifndef YASM_LIB_DECL
|
||||
#define YASM_LIB_DECL
|
||||
#endif
|
||||
|
||||
/** Initialize intnum internal data structures. */
|
||||
YASM_LIB_DECL
|
||||
void yasm_intnum_initialize(void);
|
||||
|
||||
/** Clean up internal intnum allocations. */
|
||||
YASM_LIB_DECL
|
||||
void yasm_intnum_cleanup(void);
|
||||
|
||||
/** Create a new intnum from a decimal string.
|
||||
* \param str decimal string
|
||||
* \return Newly allocated intnum.
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
/*@only@*/ yasm_intnum *yasm_intnum_create_dec(char *str);
|
||||
|
||||
/** Create a new intnum from a binary string.
|
||||
* \param str binary string
|
||||
* \return Newly allocated intnum.
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
/*@only@*/ yasm_intnum *yasm_intnum_create_bin(char *str);
|
||||
|
||||
/** Create a new intnum from an octal string.
|
||||
* \param str octal string
|
||||
* \return Newly allocated intnum.
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
/*@only@*/ yasm_intnum *yasm_intnum_create_oct(char *str);
|
||||
|
||||
/** Create a new intnum from a hexidecimal string.
|
||||
* \param str hexidecimal string
|
||||
* \return Newly allocated intnum.
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
/*@only@*/ yasm_intnum *yasm_intnum_create_hex(char *str);
|
||||
|
||||
/** Convert character constant to integer value, using NASM rules. NASM syntax
|
||||
* supports automatic conversion from strings such as 'abcd' to a 32-bit
|
||||
* integer value (little endian order). This function performs those conversions.
|
||||
* \param str character constant string
|
||||
* \return Newly allocated intnum.
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
/*@only@*/ yasm_intnum *yasm_intnum_create_charconst_nasm(const char *str);
|
||||
|
||||
/** Convert character constant to integer value, using TASM rules. TASM syntax
|
||||
* supports automatic conversion from strings such as 'abcd' to a 32-bit
|
||||
* integer value (big endian order). This function performs those conversions.
|
||||
* \param str character constant string
|
||||
* \return Newly allocated intnum.
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
/*@only@*/ yasm_intnum *yasm_intnum_create_charconst_tasm(const char *str);
|
||||
|
||||
/** Create a new intnum from an unsigned integer value.
|
||||
* \param i unsigned integer value
|
||||
* \return Newly allocated intnum.
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
/*@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.
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
/*@only@*/ yasm_intnum *yasm_intnum_create_int(long i);
|
||||
|
||||
/** Create a new intnum from LEB128-encoded form.
|
||||
* \param ptr pointer to start of LEB128 encoded form
|
||||
* \param sign signed (1) or unsigned (0) LEB128 format
|
||||
* \param size number of bytes read from ptr (output)
|
||||
* \return Newly allocated intnum. Number of bytes read returned into
|
||||
* bytes_read parameter.
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
/*@only@*/ yasm_intnum *yasm_intnum_create_leb128
|
||||
(const unsigned char *ptr, int sign, /*@out@*/ unsigned long *size);
|
||||
|
||||
/** Create a new intnum from a little-endian or big-endian buffer.
|
||||
* In little endian, the LSB is in ptr[0].
|
||||
* \param ptr pointer to start of buffer
|
||||
* \param sign signed (1) or unsigned (0) source
|
||||
* \param srcsize source buffer size (in bytes)
|
||||
* \param bigendian endianness (nonzero=big, zero=little)
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
/*@only@*/ yasm_intnum *yasm_intnum_create_sized
|
||||
(unsigned char *ptr, int sign, size_t srcsize, int bigendian);
|
||||
|
||||
/** Duplicate an intnum.
|
||||
* \param intn intnum
|
||||
* \return Newly allocated intnum with the same value as intn.
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
/*@only@*/ yasm_intnum *yasm_intnum_copy(const yasm_intnum *intn);
|
||||
|
||||
/** Destroy (free allocated memory for) an intnum.
|
||||
* \param intn intnum
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
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
|
||||
* operations will result in an error.
|
||||
* \param acc intnum accumulator
|
||||
* \param op operation
|
||||
* \param operand intnum operand
|
||||
* \return Nonzero if error occurred.
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
int yasm_intnum_calc(yasm_intnum *acc, yasm_expr_op op, yasm_intnum *operand);
|
||||
|
||||
/** Compare two intnums.
|
||||
* \param intn1 first intnum
|
||||
* \param intn2 second intnum
|
||||
* \return -1 if intn1 < intn2, 0 if intn1 == intn2, 1 if intn1 > intn2.
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
int yasm_intnum_compare(const yasm_intnum *intn1, const yasm_intnum *intn2);
|
||||
|
||||
/** Zero an intnum.
|
||||
* \param intn intnum
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
void yasm_intnum_zero(yasm_intnum *intn);
|
||||
|
||||
/** Set an intnum to the value of another intnum.
|
||||
* \param intn intnum
|
||||
* \param val intnum to get value from
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
void yasm_intnum_set(yasm_intnum *intn, const yasm_intnum *val);
|
||||
|
||||
/** Set an intnum to an unsigned integer.
|
||||
* \param intn intnum
|
||||
* \param val integer value
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
void yasm_intnum_set_uint(yasm_intnum *intn, unsigned long val);
|
||||
|
||||
/** Set an intnum to an signed integer.
|
||||
* \param intn intnum
|
||||
* \param val integer value
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
void yasm_intnum_set_int(yasm_intnum *intn, long val);
|
||||
|
||||
/** Simple value check for 0.
|
||||
* \param acc intnum
|
||||
* \return Nonzero if acc==0.
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
int yasm_intnum_is_zero(const yasm_intnum *acc);
|
||||
|
||||
/** Simple value check for 1.
|
||||
* \param acc intnum
|
||||
* \return Nonzero if acc==1.
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
int yasm_intnum_is_pos1(const yasm_intnum *acc);
|
||||
|
||||
/** Simple value check for -1.
|
||||
* \param acc intnum
|
||||
* \return Nonzero if acc==-1.
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
int yasm_intnum_is_neg1(const yasm_intnum *acc);
|
||||
|
||||
/** Simple sign check.
|
||||
* \param acc intnum
|
||||
* \return -1 if negative, 0 if zero, +1 if positive
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
int yasm_intnum_sign(const yasm_intnum *acc);
|
||||
|
||||
/** Convert an intnum to an unsigned 32-bit value. The value is in "standard"
|
||||
* C format (eg, of unknown endian).
|
||||
* \note Parameter intnum is truncated to fit into 32 bits. Use
|
||||
* intnum_check_size() to check for overflow.
|
||||
* \param intn intnum
|
||||
* \return Unsigned 32-bit value of intn.
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
unsigned long yasm_intnum_get_uint(const yasm_intnum *intn);
|
||||
|
||||
/** Convert an intnum to a signed 32-bit value. The value is in "standard" C
|
||||
* format (eg, of unknown endian).
|
||||
* \note Parameter intnum is truncated to fit into 32 bits. Use
|
||||
* intnum_check_size() to check for overflow.
|
||||
* \param intn intnum
|
||||
* \return Signed 32-bit value of intn.
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
long yasm_intnum_get_int(const yasm_intnum *intn);
|
||||
|
||||
/** Output #yasm_intnum to buffer in little-endian or big-endian. Puts the
|
||||
* value into the least significant bits of the destination, or may be shifted
|
||||
* into more significant bits by the shift parameter. The destination bits are
|
||||
* cleared before being set. [0] should be the first byte output to the file.
|
||||
* \param intn intnum
|
||||
* \param ptr pointer to storage for size bytes of output
|
||||
* \param destsize destination size (in bytes)
|
||||
* \param valsize size (in bits)
|
||||
* \param shift left shift (in bits); may be negative to specify right
|
||||
* shift (standard warnings include truncation to boundary)
|
||||
* \param bigendian endianness (nonzero=big, zero=little)
|
||||
* \param warn enables standard warnings (value doesn't fit into valsize
|
||||
* bits): <0=signed warnings, >0=unsigned warnings, 0=no warn
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
void yasm_intnum_get_sized(const yasm_intnum *intn, unsigned char *ptr,
|
||||
size_t destsize, size_t valsize, int shift,
|
||||
int bigendian, int warn);
|
||||
|
||||
/** Check to see if intnum will fit without overflow into size bits.
|
||||
* \param intn intnum
|
||||
* \param size number of bits of output space
|
||||
* \param rshift right shift
|
||||
* \param rangetype signed/unsigned range selection:
|
||||
* 0 => (0, unsigned max);
|
||||
* 1 => (signed min, signed max);
|
||||
* 2 => (signed min, unsigned max)
|
||||
* \return Nonzero if intnum will fit.
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
int yasm_intnum_check_size(const yasm_intnum *intn, size_t size,
|
||||
size_t rshift, int rangetype);
|
||||
|
||||
/** Check to see if intnum will fit into a particular numeric range.
|
||||
* \param intn intnum
|
||||
* \param low low end of range (inclusive)
|
||||
* \param high high end of range (inclusive)
|
||||
* \return Nonzero if intnum is within range.
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
int yasm_intnum_in_range(const yasm_intnum *intn, long low, long high);
|
||||
|
||||
/** Output #yasm_intnum to buffer in LEB128-encoded form.
|
||||
* \param intn intnum
|
||||
* \param ptr pointer to storage for output bytes
|
||||
* \param sign signedness of LEB128 encoding (0=unsigned, 1=signed)
|
||||
* \return Number of bytes generated.
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
unsigned long yasm_intnum_get_leb128(const yasm_intnum *intn,
|
||||
unsigned char *ptr, int sign);
|
||||
|
||||
/** Calculate number of bytes LEB128-encoded form of #yasm_intnum will take.
|
||||
* \param intn intnum
|
||||
* \param sign signedness of LEB128 encoding (0=unsigned, 1=signed)
|
||||
* \return Number of bytes.
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
unsigned long yasm_intnum_size_leb128(const yasm_intnum *intn, int sign);
|
||||
|
||||
/** Output integer to buffer in signed LEB128-encoded form.
|
||||
* \param v integer
|
||||
* \param ptr pointer to storage for output bytes
|
||||
* \return Number of bytes generated.
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
unsigned long yasm_get_sleb128(long v, unsigned char *ptr);
|
||||
|
||||
/** Calculate number of bytes signed LEB128-encoded form of integer will take.
|
||||
* \param v integer
|
||||
* \return Number of bytes.
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
unsigned long yasm_size_sleb128(long v);
|
||||
|
||||
/** Output integer to buffer in unsigned LEB128-encoded form.
|
||||
* \param v integer
|
||||
* \param ptr pointer to storage for output bytes
|
||||
* \return Number of bytes generated.
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
unsigned long yasm_get_uleb128(unsigned long v, unsigned char *ptr);
|
||||
|
||||
/** Calculate number of bytes unsigned LEB128-encoded form of integer will take.
|
||||
* \param v integer
|
||||
* \return Number of bytes.
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
unsigned long yasm_size_uleb128(unsigned long v);
|
||||
|
||||
/** Get an intnum as a signed decimal string. The returned string will
|
||||
* contain a leading '-' if the intnum is negative.
|
||||
* \param intn intnum
|
||||
* \return Newly allocated string containing the decimal representation of
|
||||
* the intnum.
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
/*@only@*/ char *yasm_intnum_get_str(const yasm_intnum *intn);
|
||||
|
||||
/** Print an intnum. For debugging purposes.
|
||||
* \param f file
|
||||
* \param intn intnum
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
void yasm_intnum_print(const yasm_intnum *intn, FILE *f);
|
||||
|
||||
#endif
|
||||
@ -0,0 +1,70 @@
|
||||
#ifndef YASM_INTTREE_H
|
||||
#define YASM_INTTREE_H
|
||||
|
||||
#ifndef YASM_LIB_DECL
|
||||
#define YASM_LIB_DECL
|
||||
#endif
|
||||
|
||||
/* The interval_tree.h and interval_tree.cc files contain code for
|
||||
* interval trees implemented using red-black-trees as described in
|
||||
* the book _Introduction_To_Algorithms_ by Cormen, Leisserson,
|
||||
* and Rivest.
|
||||
*/
|
||||
|
||||
typedef struct IntervalTreeNode {
|
||||
struct IntervalTreeNode *left, *right, *parent;
|
||||
void *data;
|
||||
long low;
|
||||
long high;
|
||||
long maxHigh;
|
||||
int red; /* if red=0 then the node is black */
|
||||
} IntervalTreeNode;
|
||||
|
||||
typedef struct it_recursion_node {
|
||||
/* This structure stores the information needed when we take the
|
||||
* right branch in searching for intervals but possibly come back
|
||||
* and check the left branch as well.
|
||||
*/
|
||||
IntervalTreeNode *start_node;
|
||||
unsigned int parentIndex;
|
||||
int tryRightBranch;
|
||||
} it_recursion_node;
|
||||
|
||||
typedef struct IntervalTree {
|
||||
/* A sentinel is used for root and for nil. These sentinels are
|
||||
* created when ITTreeCreate is called. root->left should always
|
||||
* point to the node which is the root of the tree. nil points to a
|
||||
* node which should always be black but has aribtrary children and
|
||||
* parent and no key or info. The point of using these sentinels is so
|
||||
* that the root and nil nodes do not require special cases in the code
|
||||
*/
|
||||
IntervalTreeNode *root;
|
||||
IntervalTreeNode *nil;
|
||||
|
||||
/*private:*/
|
||||
unsigned int recursionNodeStackSize;
|
||||
it_recursion_node * recursionNodeStack;
|
||||
unsigned int currentParent;
|
||||
unsigned int recursionNodeStackTop;
|
||||
} IntervalTree;
|
||||
|
||||
YASM_LIB_DECL
|
||||
IntervalTree *IT_create(void);
|
||||
YASM_LIB_DECL
|
||||
void IT_destroy(IntervalTree *);
|
||||
YASM_LIB_DECL
|
||||
void IT_print(const IntervalTree *);
|
||||
YASM_LIB_DECL
|
||||
void *IT_delete_node(IntervalTree *, IntervalTreeNode *, long *low,
|
||||
long *high);
|
||||
YASM_LIB_DECL
|
||||
IntervalTreeNode *IT_insert(IntervalTree *, long low, long high, void *data);
|
||||
YASM_LIB_DECL
|
||||
IntervalTreeNode *IT_get_predecessor(const IntervalTree *, IntervalTreeNode *);
|
||||
YASM_LIB_DECL
|
||||
IntervalTreeNode *IT_get_successor(const IntervalTree *, IntervalTreeNode *);
|
||||
YASM_LIB_DECL
|
||||
void IT_enumerate(IntervalTree *, long low, long high, void *cbd,
|
||||
void (*callback) (IntervalTreeNode *node, void *cbd));
|
||||
|
||||
#endif
|
||||
@ -0,0 +1,141 @@
|
||||
/**
|
||||
* \file libyasm/linemap.h
|
||||
* \brief YASM virtual line mapping interface.
|
||||
*
|
||||
* \license
|
||||
* Copyright (C) 2002-2007 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.
|
||||
* \endlicense
|
||||
*/
|
||||
#ifndef YASM_LINEMAP_H
|
||||
#define YASM_LINEMAP_H
|
||||
|
||||
#ifndef YASM_LIB_DECL
|
||||
#define YASM_LIB_DECL
|
||||
#endif
|
||||
|
||||
/** Create a new line mapping repository.
|
||||
* \return New repository.
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
yasm_linemap *yasm_linemap_create(void);
|
||||
|
||||
/** Clean up any memory allocated for a repository.
|
||||
* \param linemap line mapping repository
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
void yasm_linemap_destroy(yasm_linemap *linemap);
|
||||
|
||||
/** Get the current line position in a repository.
|
||||
* \param linemap line mapping repository
|
||||
* \return Current virtual line.
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
unsigned long yasm_linemap_get_current(yasm_linemap *linemap);
|
||||
|
||||
/** Get bytecode and source line information, if any, for a virtual line.
|
||||
* \param linemap line mapping repository
|
||||
* \param line virtual line
|
||||
* \param bcp pointer to return bytecode into
|
||||
* \param sourcep pointer to return source code line pointer into
|
||||
* \return Zero if source line information available for line, nonzero if not.
|
||||
* \note If source line information is not available, bcp and sourcep targets
|
||||
* are set to NULL.
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
int yasm_linemap_get_source(yasm_linemap *linemap, unsigned long line,
|
||||
/*@null@*/ yasm_bytecode **bcp,
|
||||
const char **sourcep);
|
||||
|
||||
/** Add bytecode and source line information to the current virtual line.
|
||||
* \attention Deletes any existing bytecode and source line information for
|
||||
* the current virtual line.
|
||||
* \param linemap line mapping repository
|
||||
* \param bc bytecode (if any)
|
||||
* \param source source code line
|
||||
* \note The source code line pointer is NOT kept, it is strdup'ed.
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
void yasm_linemap_add_source(yasm_linemap *linemap,
|
||||
/*@null@*/ yasm_bytecode *bc,
|
||||
const char *source);
|
||||
|
||||
/** Go to the next line (increments the current virtual line).
|
||||
* \param linemap line mapping repository
|
||||
* \return The current (new) virtual line.
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
unsigned long yasm_linemap_goto_next(yasm_linemap *linemap);
|
||||
|
||||
/** Set a new file/line physical association starting point at the specified
|
||||
* virtual line. line_inc indicates how much the "real" line is incremented
|
||||
* by for each virtual line increment (0 is perfectly legal).
|
||||
* \param linemap line mapping repository
|
||||
* \param filename physical file name (if NULL, not changed)
|
||||
* \param virtual_line virtual line number (if 0, linemap->current is used)
|
||||
* \param file_line physical line number
|
||||
* \param line_inc line increment
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
void yasm_linemap_set(yasm_linemap *linemap, /*@null@*/ const char *filename,
|
||||
unsigned long virtual_line, unsigned long file_line,
|
||||
unsigned long line_inc);
|
||||
|
||||
/** Poke a single file/line association, restoring the original physical
|
||||
* association starting point. Caution: increments the current virtual line
|
||||
* twice.
|
||||
* \param linemap line mapping repository
|
||||
* \param filename physical file name (if NULL, not changed)
|
||||
* \param file_line physical line number
|
||||
* \return The virtual line number of the poked association.
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
unsigned long yasm_linemap_poke(yasm_linemap *linemap,
|
||||
/*@null@*/ const char *filename,
|
||||
unsigned long file_line);
|
||||
|
||||
/** Look up the associated physical file and line for a virtual line.
|
||||
* \param linemap line mapping repository
|
||||
* \param line virtual line
|
||||
* \param filename physical file name (output)
|
||||
* \param file_line physical line number (output)
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
void yasm_linemap_lookup(yasm_linemap *linemap, unsigned long line,
|
||||
/*@out@*/ const char **filename,
|
||||
/*@out@*/ unsigned long *file_line);
|
||||
|
||||
/** Traverses all filenames used in a linemap, calling a function on each
|
||||
* filename.
|
||||
* \param linemap line mapping repository
|
||||
* \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.
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
int yasm_linemap_traverse_filenames
|
||||
(yasm_linemap *linemap, /*@null@*/ void *d,
|
||||
int (*func) (const char *filename, void *d));
|
||||
|
||||
#endif
|
||||
@ -0,0 +1,124 @@
|
||||
/**
|
||||
* \file libyasm/listfmt.h
|
||||
* \brief YASM list format interface.
|
||||
*
|
||||
* \license
|
||||
* Copyright (C) 2004-2007 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_LISTFMT_H
|
||||
#define YASM_LISTFMT_H
|
||||
|
||||
#ifndef YASM_DOXYGEN
|
||||
/** Base #yasm_listfmt structure. Must be present as the first element in any
|
||||
* #yasm_listfmt implementation.
|
||||
*/
|
||||
typedef struct yasm_listfmt_base {
|
||||
/** #yasm_listfmt_module implementation for this list format. */
|
||||
const struct yasm_listfmt_module *module;
|
||||
} yasm_listfmt_base;
|
||||
#endif
|
||||
|
||||
/** YASM list format module interface. */
|
||||
typedef struct yasm_listfmt_module {
|
||||
/** One-line description of the list format. */
|
||||
const char *name;
|
||||
|
||||
/** Keyword used to select list format. */
|
||||
const char *keyword;
|
||||
|
||||
/** Create list format.
|
||||
* Module-level implementation of yasm_listfmt_create().
|
||||
* The filenames are provided solely for informational purposes.
|
||||
* \param in_filename primary input filename
|
||||
* \param obj_filename object filename
|
||||
* \return NULL if unable to initialize.
|
||||
*/
|
||||
/*@null@*/ /*@only@*/ yasm_listfmt * (*create)
|
||||
(const char *in_filename, const char *obj_filename);
|
||||
|
||||
/** Module-level implementation of yasm_listfmt_destroy().
|
||||
* Call yasm_listfmt_destroy() instead of calling this function.
|
||||
*/
|
||||
void (*destroy) (/*@only@*/ yasm_listfmt *listfmt);
|
||||
|
||||
/** Module-level implementation of yasm_listfmt_output().
|
||||
* Call yasm_listfmt_output() instead of calling this function.
|
||||
*/
|
||||
void (*output) (yasm_listfmt *listfmt, FILE *f, yasm_linemap *linemap,
|
||||
yasm_arch *arch);
|
||||
} yasm_listfmt_module;
|
||||
|
||||
/** Get the keyword used to select a list format.
|
||||
* \param listfmt list format
|
||||
* \return keyword
|
||||
*/
|
||||
const char *yasm_listfmt_keyword(const yasm_listfmt *listfmt);
|
||||
|
||||
/** Initialize list format for use. Must call before any other list
|
||||
* format functions. The filenames are provided solely for informational
|
||||
* purposes.
|
||||
* \param module list format module
|
||||
* \param in_filename primary input filename
|
||||
* \param obj_filename object filename
|
||||
* \return NULL if object format does not provide needed support.
|
||||
*/
|
||||
/*@null@*/ /*@only@*/ yasm_listfmt *yasm_listfmt_create
|
||||
(const yasm_listfmt_module *module, const char *in_filename,
|
||||
const char *obj_filename);
|
||||
|
||||
/** Cleans up any allocated list format memory.
|
||||
* \param listfmt list format
|
||||
*/
|
||||
void yasm_listfmt_destroy(/*@only@*/ yasm_listfmt *listfmt);
|
||||
|
||||
/** Write out list to the list file.
|
||||
* This function may call all read-only yasm_* functions as necessary.
|
||||
* \param listfmt list format
|
||||
* \param f output list file
|
||||
* \param linemap line mapping repository
|
||||
* \param arch architecture
|
||||
*/
|
||||
void yasm_listfmt_output(yasm_listfmt *listfmt, FILE *f,
|
||||
yasm_linemap *linemap, yasm_arch *arch);
|
||||
|
||||
#ifndef YASM_DOXYGEN
|
||||
|
||||
/* Inline macro implementations for listfmt functions */
|
||||
|
||||
#define yasm_listfmt_keyword(listfmt) \
|
||||
(((yasm_listfmt_base *)listfmt)->module->keyword)
|
||||
|
||||
#define yasm_listfmt_create(module, in_filename, obj_filename) \
|
||||
module->create(in_filename, obj_filename)
|
||||
|
||||
#define yasm_listfmt_destroy(listfmt) \
|
||||
((yasm_listfmt_base *)listfmt)->module->destroy(listfmt)
|
||||
|
||||
#define yasm_listfmt_output(listfmt, f, linemap, a) \
|
||||
((yasm_listfmt_base *)listfmt)->module->output(listfmt, f, linemap, a)
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@ -0,0 +1,32 @@
|
||||
/* See md5.c for explanation and copyright information. */
|
||||
|
||||
#ifndef YASM_MD5_H
|
||||
#define YASM_MD5_H
|
||||
|
||||
#ifndef YASM_LIB_DECL
|
||||
#define YASM_LIB_DECL
|
||||
#endif
|
||||
|
||||
/* Unlike previous versions of this code, uint32 need not be exactly
|
||||
32 bits, merely 32 bits or more. Choosing a data type which is 32
|
||||
bits instead of 64 is not important; speed is considerably more
|
||||
important. ANSI guarantees that "unsigned long" will be big enough,
|
||||
and always using it seems to have few disadvantages. */
|
||||
|
||||
typedef struct yasm_md5_context {
|
||||
unsigned long buf[4];
|
||||
unsigned long bits[2];
|
||||
unsigned char in[64];
|
||||
} yasm_md5_context;
|
||||
|
||||
YASM_LIB_DECL
|
||||
void yasm_md5_init(yasm_md5_context *context);
|
||||
YASM_LIB_DECL
|
||||
void yasm_md5_update(yasm_md5_context *context, unsigned char const *buf,
|
||||
unsigned long len);
|
||||
YASM_LIB_DECL
|
||||
void yasm_md5_final(unsigned char digest[16], yasm_md5_context *context);
|
||||
YASM_LIB_DECL
|
||||
void yasm_md5_transform(unsigned long buf[4], const unsigned char in[64]);
|
||||
|
||||
#endif /* !YASM_MD5_H */
|
||||
@ -0,0 +1,82 @@
|
||||
/*
|
||||
* YASM module loader header file
|
||||
*
|
||||
* Copyright (C) 2002-2007 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.
|
||||
*/
|
||||
#ifndef YASM_MODULE_H
|
||||
#define YASM_MODULE_H
|
||||
|
||||
#ifndef YASM_LIB_DECL
|
||||
#define YASM_LIB_DECL
|
||||
#endif
|
||||
|
||||
typedef enum yasm_module_type {
|
||||
YASM_MODULE_ARCH = 0,
|
||||
YASM_MODULE_DBGFMT,
|
||||
YASM_MODULE_OBJFMT,
|
||||
YASM_MODULE_LISTFMT,
|
||||
YASM_MODULE_PARSER,
|
||||
YASM_MODULE_PREPROC
|
||||
} yasm_module_type;
|
||||
|
||||
YASM_LIB_DECL
|
||||
/*@dependent@*/ /*@null@*/ void *yasm_load_module
|
||||
(yasm_module_type type, const char *keyword);
|
||||
|
||||
#define yasm_load_arch(keyword) \
|
||||
yasm_load_module(YASM_MODULE_ARCH, keyword)
|
||||
#define yasm_load_dbgfmt(keyword) \
|
||||
yasm_load_module(YASM_MODULE_DBGFMT, keyword)
|
||||
#define yasm_load_objfmt(keyword) \
|
||||
yasm_load_module(YASM_MODULE_OBJFMT, keyword)
|
||||
#define yasm_load_listfmt(keyword) \
|
||||
yasm_load_module(YASM_MODULE_LISTFMT, keyword)
|
||||
#define yasm_load_parser(keyword) \
|
||||
yasm_load_module(YASM_MODULE_PARSER, keyword)
|
||||
#define yasm_load_preproc(keyword) \
|
||||
yasm_load_module(YASM_MODULE_PREPROC, keyword)
|
||||
|
||||
YASM_LIB_DECL
|
||||
void yasm_list_modules
|
||||
(yasm_module_type type,
|
||||
void (*printfunc) (const char *name, const char *keyword));
|
||||
|
||||
#define yasm_list_arch(func) \
|
||||
yasm_list_modules(YASM_MODULE_ARCH, func)
|
||||
#define yasm_list_dbgfmt(func) \
|
||||
yasm_list_modules(YASM_MODULE_DBGFMT, func)
|
||||
#define yasm_list_objfmt(func) \
|
||||
yasm_list_modules(YASM_MODULE_OBJFMT, func)
|
||||
#define yasm_list_listfmt(func) \
|
||||
yasm_list_modules(YASM_MODULE_LISTFMT, func)
|
||||
#define yasm_list_parser(func) \
|
||||
yasm_list_modules(YASM_MODULE_PARSER, func)
|
||||
#define yasm_list_preproc(func) \
|
||||
yasm_list_modules(YASM_MODULE_PREPROC, func)
|
||||
|
||||
YASM_LIB_DECL
|
||||
void yasm_register_module(yasm_module_type type, const char *keyword,
|
||||
void *data);
|
||||
|
||||
#endif
|
||||
@ -0,0 +1,216 @@
|
||||
/**
|
||||
* \file libyasm/objfmt.h
|
||||
* \brief YASM object format module interface.
|
||||
*
|
||||
* \license
|
||||
* Copyright (C) 2001-2007 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_OBJFMT_H
|
||||
#define YASM_OBJFMT_H
|
||||
|
||||
#ifndef YASM_DOXYGEN
|
||||
/** Base #yasm_objfmt structure. Must be present as the first element in any
|
||||
* #yasm_objfmt implementation.
|
||||
*/
|
||||
typedef struct yasm_objfmt_base {
|
||||
/** #yasm_objfmt_module implementation for this object format. */
|
||||
const struct yasm_objfmt_module *module;
|
||||
} yasm_objfmt_base;
|
||||
#endif
|
||||
|
||||
/** Object format module interface. */
|
||||
struct yasm_objfmt_module {
|
||||
/** One-line description of the object format. */
|
||||
const char *name;
|
||||
|
||||
/** Keyword used to select object format. */
|
||||
const char *keyword;
|
||||
|
||||
/** Default output file extension (without the '.').
|
||||
* NULL means no extension, with no '.', while "" includes the '.'.
|
||||
*/
|
||||
/*@null@*/ const char *extension;
|
||||
|
||||
/** Default (starting) x86 BITS setting. This only appies to the x86
|
||||
* architecture; other architectures ignore this setting.
|
||||
*/
|
||||
const unsigned char default_x86_mode_bits;
|
||||
|
||||
/** If @ signs should be legal in identifiers. */
|
||||
const unsigned char id_at_ok;
|
||||
|
||||
/** NULL-terminated list of debug format (yasm_dbgfmt) keywords that are
|
||||
* valid to use with this object format. The null debug format
|
||||
* (null_dbgfmt, "null") should always be in this list so it's possible to
|
||||
* have no debug output.
|
||||
*/
|
||||
const char **dbgfmt_keywords;
|
||||
|
||||
/** Default debug format keyword (set even if there's only one available to
|
||||
* use).
|
||||
*/
|
||||
const char *default_dbgfmt_keyword;
|
||||
|
||||
/** NULL-terminated list of directives. NULL if none. */
|
||||
/*@null@*/ const yasm_directive *directives;
|
||||
|
||||
/** NULL-terminated list of standard macro lookups. NULL if none. */
|
||||
const yasm_stdmac *stdmacs;
|
||||
|
||||
/** Create object format.
|
||||
* Module-level implementation of yasm_objfmt_create().
|
||||
* Call yasm_objfmt_create() instead of calling this function.
|
||||
* \param object object
|
||||
* \param a architecture in use
|
||||
* \return NULL if architecture/machine combination not supported.
|
||||
*/
|
||||
/*@null@*/ /*@only@*/ yasm_objfmt * (*create) (yasm_object *object);
|
||||
|
||||
/** Module-level implementation of yasm_objfmt_output().
|
||||
* Call yasm_objfmt_output() instead of calling this function.
|
||||
*/
|
||||
void (*output) (yasm_object *o, FILE *f, int all_syms,
|
||||
yasm_errwarns *errwarns);
|
||||
|
||||
/** Module-level implementation of yasm_objfmt_destroy().
|
||||
* Call yasm_objfmt_destroy() instead of calling this function.
|
||||
*/
|
||||
void (*destroy) (/*@only@*/ yasm_objfmt *objfmt);
|
||||
|
||||
/** Module-level implementation of yasm_objfmt_add_default_section().
|
||||
* Call yasm_objfmt_add_default_section() instead of calling this function.
|
||||
*/
|
||||
yasm_section * (*add_default_section) (yasm_object *object);
|
||||
|
||||
/** Module-level implementation of yasm_objfmt_init_new_section().
|
||||
* Call yasm_objfmt_init_new_section() instead of calling this function.
|
||||
*/
|
||||
void (*init_new_section) (yasm_section *section, unsigned long line);
|
||||
|
||||
/** Module-level implementation of yasm_objfmt_section_switch().
|
||||
* Call yasm_objfmt_section_switch() instead of calling this function.
|
||||
*/
|
||||
/*@observer@*/ /*@null@*/ yasm_section *
|
||||
(*section_switch)(yasm_object *object, yasm_valparamhead *valparams,
|
||||
/*@null@*/ yasm_valparamhead *objext_valparams,
|
||||
unsigned long line);
|
||||
|
||||
/** Module-level implementation of yasm_objfmt_get_special_sym().
|
||||
* Call yasm_objfmt_get_special_sym() instead of calling this function.
|
||||
*/
|
||||
/*@observer@*/ /*@null@*/ yasm_symrec *
|
||||
(*get_special_sym)(yasm_object *object, const char *name,
|
||||
const char *parser);
|
||||
};
|
||||
|
||||
/** Create object format.
|
||||
* \param module object format module
|
||||
* \param object object
|
||||
* \return NULL if architecture/machine combination not supported.
|
||||
*/
|
||||
/*@null@*/ /*@only@*/ yasm_objfmt *yasm_objfmt_create
|
||||
(const yasm_objfmt_module *module, yasm_object *object);
|
||||
|
||||
/** 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 object object
|
||||
* \param f output object file
|
||||
* \param all_syms if nonzero, all symbols should be included in
|
||||
* the object file
|
||||
* \param errwarns error/warning set
|
||||
* \note Errors and warnings are stored into errwarns.
|
||||
*/
|
||||
void yasm_objfmt_output(yasm_object *object, FILE *f, int all_syms,
|
||||
yasm_errwarns *errwarns);
|
||||
|
||||
/** Cleans up any allocated object format memory.
|
||||
* \param objfmt object format
|
||||
*/
|
||||
void yasm_objfmt_destroy(/*@only@*/ yasm_objfmt *objfmt);
|
||||
|
||||
/** Add a default section to an object.
|
||||
* \param object object
|
||||
* \return Default section.
|
||||
*/
|
||||
yasm_section *yasm_objfmt_add_default_section(yasm_object *object);
|
||||
|
||||
/** Initialize the object-format specific portion of a section. Called
|
||||
* by yasm_object_get_general(); in general should not be directly called.
|
||||
* \param section section
|
||||
* \param line virtual line (from yasm_linemap)
|
||||
*/
|
||||
void yasm_objfmt_init_new_section(yasm_object *object, unsigned long line);
|
||||
|
||||
/** Switch object file sections. The first val of the valparams should
|
||||
* 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 line virtual line (from yasm_linemap)
|
||||
* \return NULL on error, otherwise new section.
|
||||
*/
|
||||
/*@observer@*/ /*@null@*/ yasm_section *yasm_objfmt_section_switch
|
||||
(yasm_object *object, yasm_valparamhead *valparams,
|
||||
/*@null@*/ yasm_valparamhead *objext_valparams, unsigned long line);
|
||||
|
||||
/** Get a special symbol. Special symbols are generally used to generate
|
||||
* special relocation types via the WRT mechanism.
|
||||
* \param object object
|
||||
* \param name symbol name (not including any parser-specific prefix)
|
||||
* \param parser parser keyword
|
||||
* \return NULL if unrecognized, otherwise special symbol.
|
||||
*/
|
||||
/*@observer@*/ /*@null@*/ yasm_symrec *yasm_objfmt_get_special_sym
|
||||
(yasm_object *object, const char *name, const char *parser);
|
||||
|
||||
#ifndef YASM_DOXYGEN
|
||||
|
||||
/* Inline macro implementations for objfmt functions */
|
||||
|
||||
#define yasm_objfmt_create(module, object) module->create(object)
|
||||
|
||||
#define yasm_objfmt_output(object, f, all_syms, ews) \
|
||||
((yasm_objfmt_base *)((object)->objfmt))->module->output \
|
||||
(object, f, all_syms, ews)
|
||||
#define yasm_objfmt_destroy(objfmt) \
|
||||
((yasm_objfmt_base *)objfmt)->module->destroy(objfmt)
|
||||
#define yasm_objfmt_section_switch(object, vpms, oe_vpms, line) \
|
||||
((yasm_objfmt_base *)((object)->objfmt))->module->section_switch \
|
||||
(object, vpms, oe_vpms, line)
|
||||
#define yasm_objfmt_add_default_section(object) \
|
||||
((yasm_objfmt_base *)((object)->objfmt))->module->add_default_section \
|
||||
(object)
|
||||
#define yasm_objfmt_init_new_section(section, line) \
|
||||
((yasm_objfmt_base *)((object)->objfmt))->module->init_new_section \
|
||||
(section, line)
|
||||
#define yasm_objfmt_get_special_sym(object, name, parser) \
|
||||
((yasm_objfmt_base *)((object)->objfmt))->module->get_special_sym \
|
||||
(object, name, parser)
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@ -0,0 +1,67 @@
|
||||
/**
|
||||
* \file libyasm/parser.h
|
||||
* \brief YASM parser module interface.
|
||||
*
|
||||
* \license
|
||||
* Copyright (C) 2001-2007 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.
|
||||
* \endlicense
|
||||
*/
|
||||
#ifndef YASM_PARSER_H
|
||||
#define YASM_PARSER_H
|
||||
|
||||
/** YASM parser module interface. The "front end" of the assembler. */
|
||||
typedef struct yasm_parser_module {
|
||||
/** One-line description of the parser */
|
||||
const char *name;
|
||||
|
||||
/** Keyword used to select parser on the command line */
|
||||
const char *keyword;
|
||||
|
||||
/** NULL-terminated list of preprocessors that are valid to use with this
|
||||
* parser. The raw preprocessor (raw_preproc) should always be in this
|
||||
* list so it's always possible to have no preprocessing done.
|
||||
*/
|
||||
const char **preproc_keywords;
|
||||
|
||||
/** Default preprocessor. */
|
||||
const char *default_preproc_keyword;
|
||||
|
||||
/** NULL-terminated list of standard macro lookups. NULL if none. */
|
||||
const yasm_stdmac *stdmacs;
|
||||
|
||||
/** Parse a source file into an object.
|
||||
* \param object object to parse into (already created)
|
||||
* \param pp preprocessor
|
||||
* \param save_input nonzero if the parser should save the original
|
||||
* lines of source into the object's linemap (via
|
||||
* yasm_linemap_add_data()).
|
||||
* \param errwarns error/warning set
|
||||
* \note Parse errors and warnings are stored into errwarns.
|
||||
*/
|
||||
void (*do_parse)
|
||||
(yasm_object *object, yasm_preproc *pp, int save_input,
|
||||
yasm_linemap *linemap, yasm_errwarns *errwarns);
|
||||
} yasm_parser_module;
|
||||
|
||||
#endif
|
||||
@ -0,0 +1,19 @@
|
||||
/* Modified for use with yasm by Peter Johnson. */
|
||||
/*
|
||||
------------------------------------------------------------------------------
|
||||
By Bob Jenkins, September 1996.
|
||||
lookupa.h, a hash function for table lookup, same function as lookup.c.
|
||||
Use this code in any way you wish. Public Domain. It has no warranty.
|
||||
Source is http://burtleburtle.net/bob/c/lookupa.h
|
||||
------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#ifndef YASM_LIB_DECL
|
||||
#define YASM_LIB_DECL
|
||||
#endif
|
||||
|
||||
YASM_LIB_DECL
|
||||
unsigned long phash_lookup(const char *k, size_t length,
|
||||
unsigned long level);
|
||||
YASM_LIB_DECL
|
||||
void phash_checksum(const char *k, size_t length, unsigned long *state);
|
||||
@ -0,0 +1,210 @@
|
||||
/**
|
||||
* \file libyasm/preproc.h
|
||||
* \brief YASM preprocessor module interface.
|
||||
*
|
||||
* \license
|
||||
* Copyright (C) 2001-2007 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.
|
||||
* \endlicense
|
||||
*/
|
||||
#ifndef YASM_PREPROC_H
|
||||
#define YASM_PREPROC_H
|
||||
|
||||
#ifndef YASM_DOXYGEN
|
||||
/** Base #yasm_preproc structure. Must be present as the first element in any
|
||||
* #yasm_preproc implementation.
|
||||
*/
|
||||
typedef struct yasm_preproc_base {
|
||||
/** #yasm_preproc_module implementation for this preprocessor. */
|
||||
const struct yasm_preproc_module *module;
|
||||
} yasm_preproc_base;
|
||||
#endif
|
||||
|
||||
/** YASM preprocesor module interface. */
|
||||
typedef struct yasm_preproc_module {
|
||||
/** One-line description of the preprocessor. */
|
||||
const char *name;
|
||||
|
||||
/** Keyword used to select preprocessor on the command line. */
|
||||
const char *keyword;
|
||||
|
||||
/** Create preprocessor.
|
||||
* Module-level implementation of yasm_preproc_create().
|
||||
* Call yasm_preproc_create() instead of calling this function.
|
||||
*
|
||||
* \param in_filename initial starting filename, or "-" to read from
|
||||
* stdin
|
||||
* \param symtab symbol table (may be NULL if none)
|
||||
* \param lm line mapping repository
|
||||
* \param errwarns error/warnning set.
|
||||
* \return New preprocessor.
|
||||
*
|
||||
* \note Any preprocessor errors and warnings are stored into errwarns.
|
||||
*/
|
||||
/*@only@*/ yasm_preproc * (*create) (const char *in_filename,
|
||||
yasm_symtab *symtab,
|
||||
yasm_linemap *lm,
|
||||
yasm_errwarns *errwarns);
|
||||
|
||||
/** Module-level implementation of yasm_preproc_destroy().
|
||||
* Call yasm_preproc_destroy() instead of calling this function.
|
||||
*/
|
||||
void (*destroy) (/*@only@*/ yasm_preproc *preproc);
|
||||
|
||||
/** Module-level implementation of yasm_preproc_get_line().
|
||||
* Call yasm_preproc_get_line() instead of calling this function.
|
||||
*/
|
||||
char * (*get_line) (yasm_preproc *preproc);
|
||||
|
||||
/** Module-level implementation of yasm_preproc_get_included_file().
|
||||
* Call yasm_preproc_get_included_file() instead of calling this function.
|
||||
*/
|
||||
size_t (*get_included_file) (yasm_preproc *preproc, /*@out@*/ char *buf,
|
||||
size_t max_size);
|
||||
|
||||
/** Module-level implementation of yasm_preproc_add_include_file().
|
||||
* Call yasm_preproc_add_include_file() instead of calling this function.
|
||||
*/
|
||||
void (*add_include_file) (yasm_preproc *preproc, const char *filename);
|
||||
|
||||
/** Module-level implementation of yasm_preproc_predefine_macro().
|
||||
* Call yasm_preproc_predefine_macro() instead of calling this function.
|
||||
*/
|
||||
void (*predefine_macro) (yasm_preproc *preproc, const char *macronameval);
|
||||
|
||||
/** Module-level implementation of yasm_preproc_undefine_macro().
|
||||
* Call yasm_preproc_undefine_macro() instead of calling this function.
|
||||
*/
|
||||
void (*undefine_macro) (yasm_preproc *preproc, const char *macroname);
|
||||
|
||||
/** Module-level implementation of yasm_preproc_builtin_define().
|
||||
* Call yasm_preproc_builtin_define() instead of calling this function.
|
||||
*/
|
||||
void (*define_builtin) (yasm_preproc *preproc, const char *macronameval);
|
||||
|
||||
/** Module-level implementation of yasm_preproc_add_standard().
|
||||
* Call yasm_preproc_add_standard() instead of calling this function.
|
||||
*/
|
||||
void (*add_standard) (yasm_preproc *preproc, const char **macros);
|
||||
} yasm_preproc_module;
|
||||
|
||||
/** Initialize preprocessor.
|
||||
* The preprocessor needs access to the object format module to find out
|
||||
* any output format specific macros.
|
||||
* \param module preprocessor module
|
||||
* \param in_filename initial starting filename, or "-" to read from stdin
|
||||
* \param symtab symbol table (may be NULL if none)
|
||||
* \param lm line mapping repository
|
||||
* \param errwarns error/warning set
|
||||
* \return New preprocessor.
|
||||
* \note Errors/warnings are stored into errwarns.
|
||||
*/
|
||||
/*@only@*/ yasm_preproc *yasm_preproc_create
|
||||
(yasm_preproc_module *module, const char *in_filename,
|
||||
yasm_symtab *symtab, yasm_linemap *lm, yasm_errwarns *errwarns);
|
||||
|
||||
/** Cleans up any allocated preproc memory.
|
||||
* \param preproc preprocessor
|
||||
*/
|
||||
void yasm_preproc_destroy(/*@only@*/ yasm_preproc *preproc);
|
||||
|
||||
/** Gets a single line of preprocessed source code.
|
||||
* \param preproc preprocessor
|
||||
* \return Allocated line of code, without the trailing \n.
|
||||
*/
|
||||
char *yasm_preproc_get_line(yasm_preproc *preproc);
|
||||
|
||||
/** Get the next filename included by the source code.
|
||||
* \param preproc preprocessor
|
||||
* \param buf destination buffer for filename
|
||||
* \param max_size maximum number of bytes that can be returned in buf
|
||||
* \return Actual number of bytes returned in buf.
|
||||
*/
|
||||
size_t yasm_preproc_get_included_file(yasm_preproc *preproc,
|
||||
/*@out@*/ char *buf, size_t max_size);
|
||||
|
||||
/** Pre-include a file.
|
||||
* \param preproc preprocessor
|
||||
* \param filename filename
|
||||
*/
|
||||
void yasm_preproc_add_include_file(yasm_preproc *preproc,
|
||||
const char *filename);
|
||||
|
||||
/** Pre-define a macro.
|
||||
* \param preproc preprocessor
|
||||
* \param macronameval "name=value" string
|
||||
*/
|
||||
void yasm_preproc_predefine_macro(yasm_preproc *preproc,
|
||||
const char *macronameval);
|
||||
|
||||
/** Un-define a macro.
|
||||
* \param preproc preprocessor
|
||||
* \param macroname macro name
|
||||
*/
|
||||
void yasm_preproc_undefine_macro(yasm_preproc *preproc, const char *macroname);
|
||||
|
||||
/** Define a builtin macro, preprocessed before the "standard" macros.
|
||||
* \param preproc preprocessor
|
||||
* \param macronameval "name=value" string
|
||||
*/
|
||||
void yasm_preproc_define_builtin(yasm_preproc *preproc,
|
||||
const char *macronameval);
|
||||
|
||||
/** Define additional standard macros, preprocessed after the builtins but
|
||||
* prior to any user-defined macros.
|
||||
* \param preproc preprocessor
|
||||
* \param macros NULL-terminated array of macro strings
|
||||
*/
|
||||
void yasm_preproc_add_standard(yasm_preproc *preproc,
|
||||
const char **macros);
|
||||
|
||||
#ifndef YASM_DOXYGEN
|
||||
|
||||
/* Inline macro implementations for preproc functions */
|
||||
|
||||
#define yasm_preproc_create(module, in_filename, symtab, lm, ews) \
|
||||
module->create(in_filename, symtab, lm, ews)
|
||||
|
||||
#define yasm_preproc_destroy(preproc) \
|
||||
((yasm_preproc_base *)preproc)->module->destroy(preproc)
|
||||
#define yasm_preproc_get_line(preproc) \
|
||||
((yasm_preproc_base *)preproc)->module->get_line(preproc)
|
||||
#define yasm_preproc_get_included_file(preproc, buf, max_size) \
|
||||
((yasm_preproc_base *)preproc)->module->get_included_file(preproc, buf, max_size)
|
||||
#define yasm_preproc_add_include_file(preproc, filename) \
|
||||
((yasm_preproc_base *)preproc)->module->add_include_file(preproc, filename)
|
||||
#define yasm_preproc_predefine_macro(preproc, macronameval) \
|
||||
((yasm_preproc_base *)preproc)->module->predefine_macro(preproc, \
|
||||
macronameval)
|
||||
#define yasm_preproc_undefine_macro(preproc, macroname) \
|
||||
((yasm_preproc_base *)preproc)->module->undefine_macro(preproc, macroname)
|
||||
#define yasm_preproc_define_builtin(preproc, macronameval) \
|
||||
((yasm_preproc_base *)preproc)->module->define_builtin(preproc, \
|
||||
macronameval)
|
||||
#define yasm_preproc_add_standard(preproc, macros) \
|
||||
((yasm_preproc_base *)preproc)->module->add_standard(preproc, \
|
||||
macros)
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@ -0,0 +1,383 @@
|
||||
/**
|
||||
* \file libyasm/section.h
|
||||
* \brief YASM section interface.
|
||||
*
|
||||
* \license
|
||||
* Copyright (C) 2001-2007 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_SECTION_H
|
||||
#define YASM_SECTION_H
|
||||
|
||||
#ifndef YASM_LIB_DECL
|
||||
#define YASM_LIB_DECL
|
||||
#endif
|
||||
|
||||
/** Basic YASM relocation. Object formats will need to extend this
|
||||
* structure with additional fields for relocation type, etc.
|
||||
*/
|
||||
typedef struct yasm_reloc yasm_reloc;
|
||||
|
||||
struct yasm_reloc {
|
||||
/*@reldef@*/ STAILQ_ENTRY(yasm_reloc) link; /**< Link to next reloc */
|
||||
yasm_intnum *addr; /**< Offset (address) within section */
|
||||
/*@dependent@*/ yasm_symrec *sym; /**< Relocated symbol */
|
||||
};
|
||||
|
||||
/** An object. This is the internal representation of an object file. */
|
||||
struct yasm_object {
|
||||
/*@owned@*/ char *src_filename; /**< Source filename */
|
||||
/*@owned@*/ char *obj_filename; /**< Object filename */
|
||||
|
||||
/*@owned@*/ yasm_symtab *symtab; /**< Symbol table */
|
||||
/*@owned@*/ yasm_arch *arch; /**< Target architecture */
|
||||
/*@owned@*/ yasm_objfmt *objfmt; /**< Object format */
|
||||
/*@owned@*/ yasm_dbgfmt *dbgfmt; /**< Debug format */
|
||||
|
||||
/** Currently active section. Used by some directives. NULL if no
|
||||
* section active.
|
||||
*/
|
||||
/*@dependent@*/ /*@null@*/ yasm_section *cur_section;
|
||||
|
||||
/** Linked list of sections. */
|
||||
/*@reldef@*/ STAILQ_HEAD(yasm_sectionhead, yasm_section) sections;
|
||||
|
||||
/** Directives, organized as two level HAMT; first level is parser,
|
||||
* second level is directive name.
|
||||
*/
|
||||
/*@owned@*/ struct HAMT *directives;
|
||||
|
||||
/** Prefix prepended to externally-visible symbols (empty string if none) */
|
||||
/*@owned@*/ char *global_prefix;
|
||||
|
||||
/** Suffix appended to externally-visible symbols (empty string if none) */
|
||||
/*@owned@*/ char *global_suffix;
|
||||
};
|
||||
|
||||
/** 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.
|
||||
* \param src_filename source filename (e.g. "file.asm")
|
||||
* \param obj_filename object filename (e.g. "file.o")
|
||||
* \param arch architecture
|
||||
* \param objfmt_module object format module
|
||||
* \param dbgfmt_module debug format module
|
||||
* \return Newly allocated object, or NULL on error.
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
/*@null@*/ /*@only@*/ yasm_object *yasm_object_create
|
||||
(const char *src_filename, const char *obj_filename,
|
||||
/*@kept@*/ yasm_arch *arch,
|
||||
const yasm_objfmt_module *objfmt_module,
|
||||
const yasm_dbgfmt_module *dbgfmt_module);
|
||||
|
||||
/** Create a new, or continue an existing, general section. The section is
|
||||
* added to the object if there's not already a section by that name.
|
||||
* \param object object
|
||||
* \param name section name
|
||||
* \param align alignment in bytes (0 if none)
|
||||
* \param code if nonzero, section is intended to contain code
|
||||
* (e.g. alignment should be made with NOP instructions, not 0)
|
||||
* \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 line virtual line of section declaration (ignored if section
|
||||
* already exists)
|
||||
* \return New section.
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
/*@dependent@*/ yasm_section *yasm_object_get_general
|
||||
(yasm_object *object, const char *name, unsigned long align, int code,
|
||||
int res_only, /*@out@*/ int *isnew, unsigned long line);
|
||||
|
||||
/** Handle a directive. Passed down to object format, debug format, or
|
||||
* architecture as appropriate.
|
||||
* \param object object
|
||||
* \param name directive name
|
||||
* \param parser parser keyword
|
||||
* \param valparams value/parameters
|
||||
* \param objext_valparams "object format-specific" value/parameters
|
||||
* \param line virtual line (from yasm_linemap)
|
||||
* \return 0 if directive recognized, nonzero if unrecognized.
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
int yasm_object_directive(yasm_object *object, const char *name,
|
||||
const char *parser, yasm_valparamhead *valparams,
|
||||
yasm_valparamhead *objext_valparams,
|
||||
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
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
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
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
void yasm_object_print(const yasm_object *object, FILE *f, int indent_level);
|
||||
|
||||
/** Finalize an object after parsing.
|
||||
* \param object object
|
||||
* \param errwarns error/warning set
|
||||
* \note Errors/warnings are stored into errwarns.
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
void yasm_object_finalize(yasm_object *object, yasm_errwarns *errwarns);
|
||||
|
||||
/** Traverses all sections in an object, calling a function on each section.
|
||||
* \param object object
|
||||
* \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.
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
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.
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
/*@dependent@*/ /*@null@*/ yasm_section *yasm_object_find_general
|
||||
(yasm_object *object, const char *name);
|
||||
|
||||
/** Change the source filename for an object.
|
||||
* \param object object
|
||||
* \param src_filename new source filename (e.g. "file.asm")
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
void yasm_object_set_source_fn(yasm_object *object, const char *src_filename);
|
||||
|
||||
/** Change the prefix used for externally-visible symbols.
|
||||
* \param object object
|
||||
* \param prefix new prefix
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
void yasm_object_set_global_prefix(yasm_object *object, const char *prefix);
|
||||
|
||||
/** Change the suffix used for externally-visible symbols.
|
||||
* \param object object
|
||||
* \param suffix new suffix
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
void yasm_object_set_global_suffix(yasm_object *object, const char *suffix);
|
||||
|
||||
/** Optimize an object. Takes the unoptimized object and optimizes it.
|
||||
* If successful, the object is ready for output to an object file.
|
||||
* \param object object
|
||||
* \param errwarns error/warning set
|
||||
* \note Optimization failures are stored into errwarns.
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
void yasm_object_optimize(yasm_object *object, yasm_errwarns *errwarns);
|
||||
|
||||
/** Determine if a section is flagged to contain code.
|
||||
* \param sect section
|
||||
* \return Nonzero if section is flagged to contain code.
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
int yasm_section_is_code(yasm_section *sect);
|
||||
|
||||
/** Get yasm_optimizer-specific flags. For yasm_optimizer use only.
|
||||
* \param sect section
|
||||
* \return Optimizer-specific flags.
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
unsigned long yasm_section_get_opt_flags(const yasm_section *sect);
|
||||
|
||||
/** Set yasm_optimizer-specific flags. For yasm_optimizer use only.
|
||||
* \param sect section
|
||||
* \param opt_flags optimizer-specific flags.
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
void yasm_section_set_opt_flags(yasm_section *sect, unsigned long opt_flags);
|
||||
|
||||
/** Determine if a section was declared as the "default" section (e.g. not
|
||||
* created through a section directive).
|
||||
* \param sect section
|
||||
* \return Nonzero if section was declared as default.
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
int yasm_section_is_default(const yasm_section *sect);
|
||||
|
||||
/** Set section "default" flag to a new value.
|
||||
* \param sect section
|
||||
* \param def new value of default flag
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
void yasm_section_set_default(yasm_section *sect, int def);
|
||||
|
||||
/** Get object owner of a section.
|
||||
* \param sect section
|
||||
* \return Object this section is a part of.
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
yasm_object *yasm_section_get_object(const yasm_section *sect);
|
||||
|
||||
/** Get assocated data for a section and data callback.
|
||||
* \param sect section
|
||||
* \param callback callback used when adding data
|
||||
* \return Associated data (NULL if none).
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
/*@dependent@*/ /*@null@*/ void *yasm_section_get_data
|
||||
(yasm_section *sect, const yasm_assoc_data_callback *callback);
|
||||
|
||||
/** 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
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
void yasm_section_add_data(yasm_section *sect,
|
||||
const yasm_assoc_data_callback *callback,
|
||||
/*@null@*/ /*@only@*/ void *data);
|
||||
|
||||
/** Add a relocation to a section.
|
||||
* \param sect section
|
||||
* \param reloc relocation
|
||||
* \param destroy_func function that can destroy the relocation
|
||||
* \note Does not make a copy of reloc. The same destroy_func must be
|
||||
* used for all relocations in a section or an internal error will occur.
|
||||
* The section will destroy the relocation address; it is the caller's
|
||||
* responsibility to destroy any other allocated data.
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
void yasm_section_add_reloc(yasm_section *sect, yasm_reloc *reloc,
|
||||
void (*destroy_func) (/*@only@*/ void *reloc));
|
||||
|
||||
/** Get the first relocation for a section.
|
||||
* \param sect section
|
||||
* \return First relocation for section. NULL if no relocations.
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
/*@null@*/ yasm_reloc *yasm_section_relocs_first(yasm_section *sect);
|
||||
|
||||
/** Get the next relocation for a section.
|
||||
* \param reloc previous relocation
|
||||
* \return Next relocation for section. NULL if no more relocations.
|
||||
*/
|
||||
/*@null@*/ yasm_reloc *yasm_section_reloc_next(yasm_reloc *reloc);
|
||||
#ifndef YASM_DOXYGEN
|
||||
#define yasm_section_reloc_next(x) STAILQ_NEXT((x), link)
|
||||
#endif
|
||||
|
||||
/** Get the basic relocation information for a relocation.
|
||||
* \param reloc relocation
|
||||
* \param addrp address of relocation within section (returned)
|
||||
* \param symp relocated symbol (returned)
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
void yasm_reloc_get(yasm_reloc *reloc, yasm_intnum **addrp,
|
||||
/*@dependent@*/ yasm_symrec **symp);
|
||||
|
||||
/** Get the first bytecode in a section.
|
||||
* \param sect section
|
||||
* \return First bytecode in section (at least one empty bytecode is always
|
||||
* present).
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
yasm_bytecode *yasm_section_bcs_first(yasm_section *sect);
|
||||
|
||||
/** Get the last bytecode in a section.
|
||||
* \param sect section
|
||||
* \return Last bytecode in section (at least one empty bytecode is always
|
||||
* present).
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
yasm_bytecode *yasm_section_bcs_last(yasm_section *sect);
|
||||
|
||||
/** 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.
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
/*@only@*/ /*@null@*/ yasm_bytecode *yasm_section_bcs_append
|
||||
(yasm_section *sect,
|
||||
/*@returned@*/ /*@only@*/ /*@null@*/ yasm_bytecode *bc);
|
||||
|
||||
/** Traverses all bytecodes in a section, calling a function on each bytecode.
|
||||
* \param sect section
|
||||
* \param errwarns error/warning set (may be NULL)
|
||||
* \param d data pointer passed to func on each call (may be NULL)
|
||||
* \param func function
|
||||
* \return Stops early (and returns func's return value) if func returns a
|
||||
* nonzero value; otherwise 0.
|
||||
* \note If errwarns is non-NULL, yasm_errwarn_propagate() is called after
|
||||
* each call to func (with the bytecode's line number).
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
int yasm_section_bcs_traverse
|
||||
(yasm_section *sect, /*@null@*/ yasm_errwarns *errwarns,
|
||||
/*@null@*/ void *d, int (*func) (yasm_bytecode *bc, /*@null@*/ void *d));
|
||||
|
||||
/** Get name of a section.
|
||||
* \param sect section
|
||||
* \return Section name.
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
/*@observer@*/ const char *yasm_section_get_name(const yasm_section *sect);
|
||||
|
||||
/** Change alignment of a section.
|
||||
* \param sect section
|
||||
* \param align alignment in bytes
|
||||
* \param line virtual line
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
void yasm_section_set_align(yasm_section *sect, unsigned long align,
|
||||
unsigned long line);
|
||||
|
||||
/** Get alignment of a section.
|
||||
* \param sect section
|
||||
* \return Alignment in bytes (0 if none).
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
unsigned long yasm_section_get_align(const yasm_section *sect);
|
||||
|
||||
/** Print a section. For debugging purposes.
|
||||
* \param f file
|
||||
* \param indent_level indentation level
|
||||
* \param sect section
|
||||
* \param print_bcs if nonzero, print bytecodes within section
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
void yasm_section_print(/*@null@*/ const yasm_section *sect, FILE *f,
|
||||
int indent_level, int print_bcs);
|
||||
|
||||
#endif
|
||||
@ -0,0 +1,437 @@
|
||||
/**
|
||||
* \file libyasm/symrec.h
|
||||
* \brief YASM symbol table interface.
|
||||
*
|
||||
* \license
|
||||
* Copyright (C) 2001-2007 Michael Urman, Peter Johnson
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* - 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_SYMREC_H
|
||||
#define YASM_SYMREC_H
|
||||
|
||||
#ifndef YASM_LIB_DECL
|
||||
#define YASM_LIB_DECL
|
||||
#endif
|
||||
|
||||
/** Symbol status. YASM_SYM_DEFINED is set by yasm_symtab_define_label(),
|
||||
* yasm_symtab_define_equ(), or yasm_symtab_declare()/yasm_symrec_declare()
|
||||
* with a visibility of #YASM_SYM_EXTERN or #YASM_SYM_COMMON.
|
||||
*/
|
||||
typedef enum yasm_sym_status {
|
||||
YASM_SYM_NOSTATUS = 0, /**< no status */
|
||||
YASM_SYM_USED = 1 << 0, /**< for use before definition */
|
||||
YASM_SYM_DEFINED = 1 << 1, /**< once it's been defined in the file */
|
||||
YASM_SYM_VALUED = 1 << 2, /**< once its value has been determined */
|
||||
YASM_SYM_NOTINTABLE = 1 << 3 /**< if it's not in sym_table (ex. '$') */
|
||||
} yasm_sym_status;
|
||||
|
||||
/** Symbol record visibility.
|
||||
* \note YASM_SYM_EXTERN and YASM_SYM_COMMON are mutually exclusive.
|
||||
*/
|
||||
typedef enum yasm_sym_vis {
|
||||
YASM_SYM_LOCAL = 0, /**< Default, local only */
|
||||
YASM_SYM_GLOBAL = 1 << 0, /**< If symbol is declared GLOBAL */
|
||||
YASM_SYM_COMMON = 1 << 1, /**< If symbol is declared COMMON */
|
||||
YASM_SYM_EXTERN = 1 << 2, /**< If symbol is declared EXTERN */
|
||||
YASM_SYM_DLOCAL = 1 << 3 /**< If symbol is explicitly declared LOCAL */
|
||||
} yasm_sym_vis;
|
||||
|
||||
/** Create a new symbol table. */
|
||||
YASM_LIB_DECL
|
||||
yasm_symtab *yasm_symtab_create(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!
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
void yasm_symtab_destroy(/*@only@*/ yasm_symtab *symtab);
|
||||
|
||||
/** Set the symbol table to be case sensitive or not.
|
||||
* Should be called before adding any symbol.
|
||||
* \param symtab symbol table
|
||||
* \param sensitive whether the symbol table should be case sensitive.
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
void yasm_symtab_set_case_sensitive(yasm_symtab *symtab, int sensitive);
|
||||
|
||||
/** Get a reference to the symbol table's "absolute" symbol. This is
|
||||
* essentially an EQU with no name and value 0, and is used for relocating
|
||||
* absolute current-position-relative values.
|
||||
* \see yasm_value_set_curpos_rel().
|
||||
* \param symtab symbol table
|
||||
* \return Absolute symbol (dependent pointer, do not free).
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
/*@dependent@*/ yasm_symrec *yasm_symtab_abs_sym(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 line virtual line where referenced
|
||||
* \return Symbol (dependent pointer, do not free).
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
/*@dependent@*/ yasm_symrec *yasm_symtab_use
|
||||
(yasm_symtab *symtab, const char *name, unsigned long line);
|
||||
|
||||
/** Get a reference to a symbol, without "using" it. Should be used for cases
|
||||
* when an internal assembler usage of a symbol shouldn't be treated like a
|
||||
* normal user symbol usage.
|
||||
* \param symtab symbol table
|
||||
* \param name symbol name
|
||||
* \return Symbol (dependent pointer, do not free). May be NULL if symbol
|
||||
* doesn't exist.
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
/*@null@*/ /*@dependent@*/ yasm_symrec *yasm_symtab_get
|
||||
(yasm_symtab *symtab, const char *name);
|
||||
|
||||
/** Define a symbol as an EQU value.
|
||||
* \param symtab symbol table
|
||||
* \param name symbol (EQU) name
|
||||
* \param e EQU value (expression)
|
||||
* \param line virtual line of EQU
|
||||
* \return Symbol (dependent pointer, do not free).
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
/*@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).
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
/*@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 representing the current assembly position.
|
||||
* This should be used for this purpose instead of yasm_symtab_define_label()
|
||||
* as value_finalize_scan() looks for usage of this symbol type for special
|
||||
* handling. The symbol created is not inserted into the symbol table.
|
||||
* \param symtab symbol table
|
||||
* \param name symbol (label) name
|
||||
* \param precbc bytecode preceding label
|
||||
* \param line virtual line of label
|
||||
* \return Symbol (dependent pointer, do not free).
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
/*@dependent@*/ yasm_symrec *yasm_symtab_define_curpos
|
||||
(yasm_symtab *symtab, const char *name,
|
||||
/*@dependent@*/ yasm_bytecode *precbc, unsigned long line);
|
||||
|
||||
/** Define a special symbol that will appear in the symbol table and have a
|
||||
* defined name, but have no other data associated with it within the
|
||||
* standard symrec.
|
||||
* \param symtab symbol table
|
||||
* \param name symbol name
|
||||
* \param vis symbol visibility
|
||||
* \return Symbol (dependent pointer, do not free).
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
/*@dependent@*/ yasm_symrec *yasm_symtab_define_special
|
||||
(yasm_symtab *symtab, const char *name, yasm_sym_vis vis);
|
||||
|
||||
/** 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 line virtual line of visibility-setting
|
||||
* \return Symbol (dependent pointer, do not free).
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
/*@dependent@*/ yasm_symrec *yasm_symtab_declare
|
||||
(yasm_symtab *symtab, const char *name, yasm_sym_vis vis,
|
||||
unsigned long line);
|
||||
|
||||
/** Declare external visibility of a symbol.
|
||||
* \note Not all visibility combinations are allowed.
|
||||
* \param symrec symbol
|
||||
* \param vis visibility
|
||||
* \param line virtual line of visibility-setting
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
void yasm_symrec_declare(yasm_symrec *symrec, 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.
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
int /*@alt void@*/ yasm_symtab_traverse
|
||||
(yasm_symtab *symtab, /*@null@*/ void *d,
|
||||
yasm_symtab_traverse_callback func);
|
||||
|
||||
/** Symbol table iterator (opaque type). */
|
||||
typedef struct yasm_symtab_iter yasm_symtab_iter;
|
||||
|
||||
/** Get an iterator pointing to the first symbol in the symbol table.
|
||||
* \param symtab symbol table
|
||||
* \return Iterator for the symbol table.
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
const yasm_symtab_iter *yasm_symtab_first(const yasm_symtab *symtab);
|
||||
|
||||
/** Move a symbol table iterator to the next symbol in the symbol table.
|
||||
* \param prev Previous iterator value
|
||||
* \return Next iterator value, or NULL if no more symbols in the table.
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
/*@null@*/ const yasm_symtab_iter *yasm_symtab_next
|
||||
(const yasm_symtab_iter *prev);
|
||||
|
||||
/** Get the symbol corresponding to the current symbol table iterator value.
|
||||
* \param cur iterator value
|
||||
* \return Corresponding symbol.
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
yasm_symrec *yasm_symtab_iter_value(const yasm_symtab_iter *cur);
|
||||
|
||||
/** Finalize symbol table after parsing stage. Checks for symbols that are
|
||||
* used but never defined or declared #YASM_SYM_EXTERN or #YASM_SYM_COMMON.
|
||||
* \param symtab symbol table
|
||||
* \param undef_extern if nonzero, all undef syms should be declared extern
|
||||
* \param errwarns error/warning set
|
||||
* \note Errors/warnings are stored into errwarns.
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
void yasm_symtab_parser_finalize(yasm_symtab *symtab, int undef_extern,
|
||||
yasm_errwarns *errwarns);
|
||||
|
||||
/** Print the symbol table. For debugging purposes.
|
||||
* \param symtab symbol table
|
||||
* \param f file
|
||||
* \param indent_level indentation level
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
void yasm_symtab_print(yasm_symtab *symtab, FILE *f, int indent_level);
|
||||
|
||||
/** Get the name of a symbol.
|
||||
* \param sym symbol
|
||||
* \return Symbol name.
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
/*@observer@*/ const char *yasm_symrec_get_name(const yasm_symrec *sym);
|
||||
|
||||
/** Get the externally-visible (global) name of a symbol.
|
||||
* \param sym symbol
|
||||
* \param object object
|
||||
* \return Externally-visible symbol name (allocated, caller must free).
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
/*@only@*/ char *yasm_symrec_get_global_name(const yasm_symrec *sym,
|
||||
const yasm_object *object);
|
||||
|
||||
/** Get the visibility of a symbol.
|
||||
* \param sym symbol
|
||||
* \return Symbol visibility.
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
yasm_sym_vis yasm_symrec_get_visibility(const yasm_symrec *sym);
|
||||
|
||||
/** Get the status of a symbol.
|
||||
* \param sym symbol
|
||||
* \return Symbol status.
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
yasm_sym_status yasm_symrec_get_status(const yasm_symrec *sym);
|
||||
|
||||
/** Get the virtual line of where a symbol was first defined.
|
||||
* \param sym symbol
|
||||
* \return line virtual line
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
unsigned long yasm_symrec_get_def_line(const yasm_symrec *sym);
|
||||
|
||||
/** Get the virtual line of where a symbol was first declared.
|
||||
* \param sym symbol
|
||||
* \return line virtual line
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
unsigned long yasm_symrec_get_decl_line(const yasm_symrec *sym);
|
||||
|
||||
/** Get the virtual line of where a symbol was first used.
|
||||
* \param sym symbol
|
||||
* \return line virtual line
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
unsigned long yasm_symrec_get_use_line(const yasm_symrec *sym);
|
||||
|
||||
/** Get EQU value of a symbol.
|
||||
* \param sym symbol
|
||||
* \return EQU value, or NULL if symbol is not an EQU or is not defined.
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
/*@observer@*/ /*@null@*/ const yasm_expr *yasm_symrec_get_equ
|
||||
(const yasm_symrec *sym);
|
||||
|
||||
/** Dependent pointer to a bytecode. */
|
||||
typedef /*@dependent@*/ yasm_bytecode *yasm_symrec_get_label_bytecodep;
|
||||
|
||||
/** Get the label location of a symbol.
|
||||
* \param sym symbol
|
||||
* \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).
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
int yasm_symrec_get_label(const yasm_symrec *sym,
|
||||
/*@out@*/ yasm_symrec_get_label_bytecodep *precbc);
|
||||
|
||||
/** Set the size of a symbol.
|
||||
* \param sym symbol
|
||||
* \param size size to be set
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
void yasm_symrec_set_size(yasm_symrec *sym, int size);
|
||||
|
||||
/** Get the size of a symbol.
|
||||
* \param sym symbol
|
||||
* \return size of the symbol, 0 if none specified by the user.
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
int yasm_symrec_get_size(const yasm_symrec *sym);
|
||||
|
||||
/** Set the segment of a symbol.
|
||||
* \param sym symbol
|
||||
* \param segment segment to be set
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
void yasm_symrec_set_segment(yasm_symrec *sym, const char *segment);
|
||||
|
||||
/** Get the segment of a symbol.
|
||||
* \param sym symbol
|
||||
* \return segment of the symbol, NULL if none specified by the user.
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
const char *yasm_symrec_get_segment(const yasm_symrec *sym);
|
||||
|
||||
/** Determine if symbol is the "absolute" symbol created by
|
||||
* yasm_symtab_abs_sym().
|
||||
* \param sym symbol
|
||||
* \return 0 if symbol is not the "absolute" symbol, nonzero otherwise.
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
int yasm_symrec_is_abs(const yasm_symrec *sym);
|
||||
|
||||
/** Determine if symbol is a special symbol.
|
||||
* \param sym symbol
|
||||
* \return 0 if symbol is not a special symbol, nonzero otherwise.
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
int yasm_symrec_is_special(const yasm_symrec *sym);
|
||||
|
||||
/** Determine if symbol is a label representing the current assembly position.
|
||||
* \param sym symbol
|
||||
* \return 0 if symbol is not a current position label, nonzero otherwise.
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
int yasm_symrec_is_curpos(const yasm_symrec *sym);
|
||||
|
||||
/** Set object-extended valparams.
|
||||
* \param sym symbol
|
||||
* \param objext_valparams object-extended valparams
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
void yasm_symrec_set_objext_valparams
|
||||
(yasm_symrec *sym, /*@only@*/ yasm_valparamhead *objext_valparams);
|
||||
|
||||
/** Get object-extended valparams, if any, associated with symbol's
|
||||
* declaration.
|
||||
* \param sym symbol
|
||||
* \return Object-extended valparams (NULL if none).
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
/*@null@*/ /*@dependent@*/ yasm_valparamhead *yasm_symrec_get_objext_valparams
|
||||
(yasm_symrec *sym);
|
||||
|
||||
/** Set common size of symbol.
|
||||
* \param sym symbol
|
||||
* \param common_size common size expression
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
void yasm_symrec_set_common_size
|
||||
(yasm_symrec *sym, /*@only@*/ yasm_expr *common_size);
|
||||
|
||||
/** Get common size of symbol, if symbol is declared COMMON and a size was set
|
||||
* for it.
|
||||
* \param sym symbol
|
||||
* \return Common size (NULL if none).
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
/*@dependent@*/ /*@null@*/ yasm_expr **yasm_symrec_get_common_size
|
||||
(yasm_symrec *sym);
|
||||
|
||||
/** Get associated data for a symbol and data callback.
|
||||
* \param sym symbol
|
||||
* \param callback callback used when adding data
|
||||
* \return Associated data (NULL if none).
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
/*@dependent@*/ /*@null@*/ void *yasm_symrec_get_data
|
||||
(yasm_symrec *sym, const yasm_assoc_data_callback *callback);
|
||||
|
||||
/** Add associated data to a symbol.
|
||||
* \attention Deletes any existing associated data for that data callback.
|
||||
* \param sym symbol
|
||||
* \param callback callback
|
||||
* \param data data to associate
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
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
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
void yasm_symrec_print(const yasm_symrec *sym, FILE *f, int indent_level);
|
||||
|
||||
#endif
|
||||
@ -0,0 +1,408 @@
|
||||
/**
|
||||
* \file libyasm/valparam.h
|
||||
* \brief YASM value/parameter interface.
|
||||
*
|
||||
* \license
|
||||
* Copyright (C) 2001-2007 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_VALPARAM_H
|
||||
#define YASM_VALPARAM_H
|
||||
|
||||
#ifndef YASM_LIB_DECL
|
||||
#define YASM_LIB_DECL
|
||||
#endif
|
||||
|
||||
/** Value/parameter pair. \internal */
|
||||
struct yasm_valparam {
|
||||
/*@reldef@*/ STAILQ_ENTRY(yasm_valparam) link; /**< Next pair in list */
|
||||
/*@owned@*/ /*@null@*/ char *val; /**< Value */
|
||||
|
||||
/** Parameter type. */
|
||||
enum yasm_param_type {
|
||||
YASM_PARAM_ID, /**< Identifier */
|
||||
YASM_PARAM_STRING, /**< String */
|
||||
YASM_PARAM_EXPR /**< Expression */
|
||||
} type; /**< Parameter type */
|
||||
|
||||
/** Parameter value. */
|
||||
union yasm_param {
|
||||
/*@owned@*/ char *id; /**< Identifier */
|
||||
/*@owned@*/ char *str; /**< String */
|
||||
/*@owned@*/ yasm_expr *e; /**< Expression */
|
||||
} param; /**< Parameter */
|
||||
|
||||
/** Prefix character that indicates a raw identifier. When
|
||||
* yasm_vp_string() is called on a #YASM_PARAM_ID, all characters are
|
||||
* returned. When yasm_vp_id() is called on a #YASM_PARAM_ID, if the
|
||||
* identifier begins with this character, this character is stripped
|
||||
* from the returned value.
|
||||
*/
|
||||
char id_prefix;
|
||||
};
|
||||
|
||||
/** Linked list of value/parameter pairs. \internal */
|
||||
/*@reldef@*/ STAILQ_HEAD(yasm_valparamhead, yasm_valparam);
|
||||
|
||||
/** Directive list entry structure. */
|
||||
struct yasm_directive {
|
||||
/** Directive name. GAS directives should include the ".", NASM
|
||||
* directives should just be the raw name (not including the []).
|
||||
* NULL entry required to terminate list of directives.
|
||||
*/
|
||||
/*@null@*/ const char *name;
|
||||
|
||||
const char *parser; /**< Parser keyword */
|
||||
|
||||
/** Handler callback function for the directive.
|
||||
* \param object object
|
||||
* \param valparams value/parameters
|
||||
* \param objext_valparams object format-specific value/parameters
|
||||
* \param line virtual line (from yasm_linemap)
|
||||
*/
|
||||
void (*handler) (yasm_object *object, yasm_valparamhead *valparams,
|
||||
yasm_valparamhead *objext_valparams, unsigned long line);
|
||||
|
||||
/** Flags for pre-handler parameter checking. */
|
||||
enum yasm_directive_flags {
|
||||
YASM_DIR_ANY = 0, /**< Any valparams accepted */
|
||||
YASM_DIR_ARG_REQUIRED = 1, /**< Require at least 1 valparam */
|
||||
YASM_DIR_ID_REQUIRED = 2 /**< First valparam must be ID */
|
||||
} flags;
|
||||
};
|
||||
|
||||
/** Call a directive. Performs any valparam checks asked for by the
|
||||
* directive prior to call. Note that for a variety of reasons, a directive
|
||||
* can generate an error.
|
||||
* \param directive directive
|
||||
* \param object object
|
||||
* \param valparams value/parameters
|
||||
* \param objext_valparams object format-specific value/parameters
|
||||
* \param line virtual line (from yasm_linemap)
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
void yasm_call_directive(const yasm_directive *directive, yasm_object *object,
|
||||
yasm_valparamhead *valparams,
|
||||
yasm_valparamhead *objext_valparams,
|
||||
unsigned long line);
|
||||
|
||||
/** Create a new valparam with identifier parameter.
|
||||
* \param v value
|
||||
* \param p parameter
|
||||
* \param id_prefix identifier prefix for raw identifiers
|
||||
* \return Newly allocated valparam.
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
yasm_valparam *yasm_vp_create_id(/*@keep@*/ char *v, /*@keep@*/ char *p,
|
||||
int id_prefix);
|
||||
|
||||
/** Create a new valparam with string parameter.
|
||||
* \param v value
|
||||
* \param p parameter
|
||||
* \return Newly allocated valparam.
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
yasm_valparam *yasm_vp_create_string(/*@keep@*/ char *v, /*@keep@*/ char *p);
|
||||
|
||||
/** Create a new valparam with expression parameter.
|
||||
* \param v value
|
||||
* \param p parameter
|
||||
* \return Newly allocated valparam.
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
yasm_valparam *yasm_vp_create_expr(/*@keep@*/ char *v,
|
||||
/*@keep@*/ yasm_expr *p);
|
||||
|
||||
/** Get a valparam parameter as an expr. If the parameter is an identifier,
|
||||
* it's treated as a symbol (yasm_symtab_use() is called to convert it).
|
||||
* \param vp valparam
|
||||
* \param symtab symbol table
|
||||
* \param line virtual line
|
||||
* \return Expression, or NULL if vp is NULL or the parameter cannot be
|
||||
* converted to an expression.
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
/*@null@*/ /*@only@*/ yasm_expr *yasm_vp_expr
|
||||
(const yasm_valparam *vp, yasm_symtab *symtab, unsigned long line);
|
||||
|
||||
/** Get a valparam parameter as a string. If the parameter is an identifier,
|
||||
* it's treated as a string.
|
||||
* \param vp valparam
|
||||
* \return String, or NULL if vp is NULL or the parameter cannot be realized
|
||||
* as a string.
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
/*@null@*/ /*@dependent@*/ const char *yasm_vp_string(const yasm_valparam *vp);
|
||||
|
||||
/** Get a valparam parameter as an identifier.
|
||||
* \param vp valparam
|
||||
* \return Identifier (string), or NULL if vp is NULL or the parameter is not
|
||||
* an identifier.
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
/*@null@*/ /*@dependent@*/ const char *yasm_vp_id(const yasm_valparam *vp);
|
||||
|
||||
/** Create a new linked list of valparams.
|
||||
* \return Newly allocated valparam list.
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
yasm_valparamhead *yasm_vps_create(void);
|
||||
|
||||
/** Destroy a list of valparams (created with yasm_vps_create).
|
||||
* \param headp list of valparams
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
void yasm_vps_destroy(yasm_valparamhead *headp);
|
||||
|
||||
/** Initialize linked list of valparams.
|
||||
* \param headp linked list
|
||||
*/
|
||||
void yasm_vps_initialize(/*@out@*/ yasm_valparamhead *headp);
|
||||
#ifndef YASM_DOXYGEN
|
||||
#define yasm_vps_initialize(headp) STAILQ_INIT(headp)
|
||||
#endif
|
||||
|
||||
/** Destroy (free allocated memory for) linked list of valparams (created with
|
||||
* yasm_vps_initialize).
|
||||
* \warning Deletes val/params.
|
||||
* \param headp linked list
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
void yasm_vps_delete(yasm_valparamhead *headp);
|
||||
|
||||
/** Append valparam to tail of linked list.
|
||||
* \param headp linked list
|
||||
* \param vp valparam
|
||||
*/
|
||||
void yasm_vps_append(yasm_valparamhead *headp, /*@keep@*/ yasm_valparam *vp);
|
||||
#ifndef YASM_DOXYGEN
|
||||
#define yasm_vps_append(headp, vp) do { \
|
||||
if (vp) \
|
||||
STAILQ_INSERT_TAIL(headp, vp, link); \
|
||||
} while(0)
|
||||
#endif
|
||||
|
||||
/** Get first valparam in linked list.
|
||||
* \param headp linked list
|
||||
* \return First valparam in linked list.
|
||||
*/
|
||||
/*@null@*/ /*@dependent@*/ yasm_valparam *yasm_vps_first
|
||||
(yasm_valparamhead *headp);
|
||||
#ifndef YASM_DOXYGEN
|
||||
#define yasm_vps_first(headp) STAILQ_FIRST(headp)
|
||||
#endif
|
||||
|
||||
/** Get next valparam in linked list.
|
||||
* \param cur previous valparam in linked list
|
||||
* \return Next valparam in linked list.
|
||||
*/
|
||||
/*@null@*/ /*@dependent@*/ yasm_valparam *yasm_vps_next(yasm_valparam *cur);
|
||||
#ifndef YASM_DOXYGEN
|
||||
#define yasm_vps_next(cur) STAILQ_NEXT(cur, link)
|
||||
#endif
|
||||
|
||||
/** Iterate through linked list of valparams.
|
||||
* \internal
|
||||
* \param iter iterator variable
|
||||
* \param headp linked list
|
||||
*/
|
||||
#ifndef YASM_DOXYGEN
|
||||
#define yasm_vps_foreach(iter, headp) STAILQ_FOREACH(iter, headp, link)
|
||||
#endif
|
||||
|
||||
/** Print linked list of valparams. For debugging purposes.
|
||||
* \param f file
|
||||
* \param headp linked list
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
void yasm_vps_print(/*@null@*/ const yasm_valparamhead *headp, FILE *f);
|
||||
|
||||
/** Directive valparam parse helper structure. */
|
||||
typedef struct yasm_dir_help {
|
||||
/** Value portion of val=param (if needsparam=1), or standalone identifier
|
||||
* (if needsparam=0).
|
||||
*/
|
||||
const char *name;
|
||||
|
||||
/** 1 if value requires parameter, 0 if it must not have a parameter. */
|
||||
int needsparam;
|
||||
|
||||
/** Helper callback function if name and parameter existence match.
|
||||
* \param obj obj passed into yasm_dir_helper()
|
||||
* \param vp value/parameter
|
||||
* \param line line passed into yasm_dir_helper()
|
||||
* \param data data passed into yasm_dir_helper() plus
|
||||
#yasm_dir_help.off offset
|
||||
* \param arg #yasm_dir_help.arg argument
|
||||
* \return -1 on error, 0 otherwise.
|
||||
*/
|
||||
int (*helper) (void *obj, yasm_valparam *vp, unsigned long line,
|
||||
void *data, uintptr_t arg);
|
||||
|
||||
/** Offset added to data pointer passed into yasm_dir_helper() before
|
||||
* data pointer is given to #yasm_dir_help.helper(). This is so that
|
||||
* a structure can be passed into yasm_dir_helper() and this can be an
|
||||
* offsetof() to point the helper function to a specific structure
|
||||
* member.
|
||||
*/
|
||||
size_t off;
|
||||
|
||||
/** Argument to pass in as the arg parameter to #yasm_dir_help.helper().
|
||||
*/
|
||||
uintptr_t arg;
|
||||
} yasm_dir_help;
|
||||
|
||||
/** Help parse a list of directive value/parameters. Takes an array of
|
||||
* #yasm_dir_help structures and tries to match val=param (or just val)
|
||||
* against the passed value/parameters. When no match is found in the
|
||||
* array of help structures, calls helper_valparam.
|
||||
* \param obj object to be passed to yasm_dir_help.helper() or
|
||||
* helper_valparam() callback
|
||||
* \param vp_first first value/parameter to examine
|
||||
* \param line virtual line number; passed down to helper callback
|
||||
* \param help array of #yasm_dir_help structures
|
||||
* \param nhelp number of array elements
|
||||
* \param data base data pointer; if a match is found,
|
||||
* the respective #yasm_dir_help.off is added to this
|
||||
* prior to it being passed to the helper callback
|
||||
* \param helper_valparam catch-all callback; should return -1 on error,
|
||||
* 0 if not matched, 1 if matched.
|
||||
* \return -1 on error, 1 if any arguments matched (including via
|
||||
* catch-all callback), 0 if no match.
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
int yasm_dir_helper(void *obj, yasm_valparam *vp_first, unsigned long line,
|
||||
const yasm_dir_help *help, size_t nhelp, void *data,
|
||||
int (*helper_valparam) (void *object,
|
||||
yasm_valparam *vp,
|
||||
unsigned long line,
|
||||
void *data));
|
||||
|
||||
/** Standard helper for yasm_dir_helper() that simply sets a flag when called.
|
||||
* It does not look at the vp; rather, it uses the value of the arg parameter,
|
||||
* and stores an unsigned long value to data.
|
||||
* \param obj unused
|
||||
* \param vp unused
|
||||
* \param line unused
|
||||
* \param data pointer to an unsigned long
|
||||
* \param arg flag to set
|
||||
* \return 0
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
int yasm_dir_helper_flag_set(void *obj, yasm_valparam *vp, unsigned long line,
|
||||
void *data, uintptr_t arg);
|
||||
|
||||
/** Standard helper for yasm_dir_helper() that simply ORs a flag when called.
|
||||
* It does not look at the vp; rather, it uses the value of the arg parameter,
|
||||
* and ORs it with the unsigned long value in data.
|
||||
* \param obj unused
|
||||
* \param vp unused
|
||||
* \param line unused
|
||||
* \param data pointer to an unsigned long
|
||||
* \param arg flag to OR
|
||||
* \return 0
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
int yasm_dir_helper_flag_or(void *obj, yasm_valparam *vp, unsigned long line,
|
||||
void *data, uintptr_t arg);
|
||||
|
||||
/** Standard helper for yasm_dir_helper() that simply ANDs a flag when called.
|
||||
* It does not look at the vp; rather, it uses the value of the arg parameter,
|
||||
* and ANDs its inverse (~) with the unsigned long value in data.
|
||||
* \param obj unused
|
||||
* \param vp unused
|
||||
* \param line unused
|
||||
* \param data pointer to an unsigned long
|
||||
* \param arg flag to AND
|
||||
* \return 0
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
int yasm_dir_helper_flag_and(void *obj, yasm_valparam *vp, unsigned long line,
|
||||
void *data, uintptr_t arg);
|
||||
|
||||
/** Standard helper for yasm_dir_helper() that parses an expr parameter.
|
||||
* The #yasm_dir_help structure that uses this function should have
|
||||
* needsparam=1. The obj parameter to yasm_dir_helper() when this helper
|
||||
* is used MUST point to a #yasm_object. In addition, the data parameter
|
||||
* that is ultimately passed to this function (e.g. yasm_dir_helper() data
|
||||
* parameter plus #yasm_dir_help.off) must point to a #yasm_expr *
|
||||
* initialized to NULL.
|
||||
* \param obj object; must be #yasm_object
|
||||
* \param vp valparam
|
||||
* \param line virtual line number
|
||||
* \param data pointer to #yasm_expr *
|
||||
* \param arg unused argument
|
||||
* \return -1 on error, 0 otherwise.
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
int yasm_dir_helper_expr(void *obj, yasm_valparam *vp, unsigned long line,
|
||||
void *data, uintptr_t arg);
|
||||
|
||||
/** Standard helper for yasm_dir_helper() that parses an intnum parameter.
|
||||
* The #yasm_dir_help structure that uses this function should have
|
||||
* needsparam=1. The obj parameter to yasm_dir_helper() when this helper
|
||||
* is used MUST point to a #yasm_object. In addition, the data parameter
|
||||
* that is ultimately passed to this function (e.g. yasm_dir_helper() data
|
||||
* parameter plus #yasm_dir_help.off) must point to a #yasm_intnum *
|
||||
* initialized to NULL.
|
||||
* \param obj object; must be #yasm_object
|
||||
* \param vp valparam
|
||||
* \param line virtual line number
|
||||
* \param data pointer to #yasm_intnum *
|
||||
* \param arg unused argument
|
||||
* \return -1 on error, 0 otherwise.
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
int yasm_dir_helper_intn(void *obj, yasm_valparam *vp, unsigned long line,
|
||||
void *data, uintptr_t arg);
|
||||
|
||||
/** Standard helper for yasm_dir_helper() that parses an string (or
|
||||
* standalone identifier) parameter.
|
||||
* The #yasm_dir_help structure that uses this function should have
|
||||
* needsparam=1. The data parameter that is ultimately passed to this
|
||||
* function (e.g. yasm_dir_helper() data parameter plus #yasm_dir_help.off)
|
||||
* must point to a char * initialized to NULL.
|
||||
* \param obj unused
|
||||
* \param vp valparam
|
||||
* \param line unused
|
||||
* \param data pointer to char *
|
||||
* \param arg unused
|
||||
* \return -1 on error, 0 otherwise.
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
int yasm_dir_helper_string(void *obj, yasm_valparam *vp, unsigned long line,
|
||||
void *data, uintptr_t arg);
|
||||
|
||||
/** Standard catch-all callback fro yasm_dir_helper(). Generates standard
|
||||
* warning for all valparams.
|
||||
* \param obj unused
|
||||
* \param vp valparam
|
||||
* \param line unused
|
||||
* \param data unused
|
||||
* \return 0
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
int yasm_dir_helper_valparam_warn(void *obj, yasm_valparam *vp,
|
||||
unsigned long line, void *data);
|
||||
#endif
|
||||
@ -0,0 +1,172 @@
|
||||
/**
|
||||
* \file libyasm/value.h
|
||||
* \brief YASM value interface.
|
||||
*
|
||||
* \license
|
||||
* Copyright (C) 2006-2007 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_VALUE_H
|
||||
#define YASM_VALUE_H
|
||||
|
||||
#ifndef YASM_LIB_DECL
|
||||
#define YASM_LIB_DECL
|
||||
#endif
|
||||
|
||||
/** Initialize a #yasm_value with just an expression. No processing is
|
||||
* performed, the expression is simply stuck into value.abs and the other
|
||||
* fields are initialized. Use yasm_expr_extract_value() to perform "smart"
|
||||
* processing into a #yasm_value. This function is intended for use during
|
||||
* parsing simply to ensure all fields of the value are initialized; after
|
||||
* the parse is complete, yasm_value_extract() should be called to finalize
|
||||
* the value. The value defaults to unsigned.
|
||||
* \param value value to be initialized
|
||||
* \param e expression (kept)
|
||||
* \param size value size (in bits)
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
void yasm_value_initialize(/*@out@*/ yasm_value *value,
|
||||
/*@null@*/ /*@kept@*/ yasm_expr *e,
|
||||
unsigned int size);
|
||||
|
||||
/** Initialize a #yasm_value with just a symrec. No processing is performed,
|
||||
* the symrec is simply stuck into value.rel and the other fields are
|
||||
* initialized.
|
||||
* \param value value to be initialized
|
||||
* \param sym symrec
|
||||
* \param size value size (in bits)
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
void yasm_value_init_sym(/*@out@*/ yasm_value *value,
|
||||
/*@null@*/ yasm_symrec *sym, unsigned int size);
|
||||
|
||||
/** Initialize a #yasm_value as a copy of another yasm_value. Any expressions
|
||||
* within orig are copied, so it's safe to delete the copy.
|
||||
* \param value value (copy to create)
|
||||
* \param orig original value
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
void yasm_value_init_copy(yasm_value *value, const yasm_value *orig);
|
||||
|
||||
/** Frees any memory inside value; does not free value itself.
|
||||
* \param value value
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
void yasm_value_delete(yasm_value *value);
|
||||
|
||||
/** Set a value to be relative to the current assembly position rather than
|
||||
* relative to the section start.
|
||||
* \param value value
|
||||
* \param bc bytecode containing value
|
||||
* \param ip_rel if nonzero, indicates IP-relative data relocation,
|
||||
* sometimes used to generate special relocations
|
||||
* \note If value is just an absolute value, will get an absolute symrec to
|
||||
* reference to (via bc's symbol table).
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
void yasm_value_set_curpos_rel(yasm_value *value, yasm_bytecode *bc,
|
||||
unsigned int ip_rel);
|
||||
|
||||
/** Perform yasm_value_finalize_expr() on a value that already exists from
|
||||
* being initialized with yasm_value_initialize().
|
||||
* \param value value
|
||||
* \param precbc previous bytecode to bytecode containing value
|
||||
* \return Nonzero if value could not be split.
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
int yasm_value_finalize(yasm_value *value, /*@null@*/ yasm_bytecode *precbc);
|
||||
|
||||
/** Break a #yasm_expr into a #yasm_value constituent parts. Extracts
|
||||
* the relative portion of the value, SEG and WRT portions, and top-level
|
||||
* right shift, if any. Places the remaining expr into the absolute
|
||||
* portion of the value. Essentially a combination of yasm_value_initialize()
|
||||
* and yasm_value_finalize(). First expands references to symrecs in
|
||||
* absolute sections by expanding with the absolute section start plus the
|
||||
* symrec offset within the absolute section.
|
||||
* \param value value to store split portions into
|
||||
* \param e expression input
|
||||
* \param precbc previous bytecode to bytecode containing expression
|
||||
* \param size value size (in bits)
|
||||
* \return Nonzero if the expr could not be split into a value for some
|
||||
* reason (e.g. the relative portion was not added, but multiplied,
|
||||
* etc).
|
||||
* \warning Do not use e after this call. Even if an error is returned, e
|
||||
* is stored into value.
|
||||
* \note This should only be called after the parse is complete. Calling
|
||||
* before the parse is complete will usually result in an error return.
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
int yasm_value_finalize_expr(/*@out@*/ yasm_value *value,
|
||||
/*@null@*/ /*@kept@*/ yasm_expr *e,
|
||||
/*@null@*/ yasm_bytecode *precbc,
|
||||
unsigned int size);
|
||||
|
||||
/** Get value if absolute or PC-relative section-local relative. Returns NULL
|
||||
* otherwise.
|
||||
* \param value value
|
||||
* \param bc current bytecode (for PC-relative calculation); if
|
||||
* NULL, NULL is returned for PC-relative values.
|
||||
* \param calc_bc_dist if nonzero, calculates bytecode distances in absolute
|
||||
* portion of value
|
||||
* \note Adds in value.rel (correctly) if PC-relative and in the same section
|
||||
* as bc (and there is no WRT or SEG).
|
||||
* \return Intnum if can be resolved to integer value, otherwise NULL.
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
/*@null@*/ /*@only@*/ yasm_intnum *yasm_value_get_intnum
|
||||
(yasm_value *value, /*@null@*/ yasm_bytecode *bc, int calc_bc_dist);
|
||||
|
||||
/** Output value if constant or PC-relative section-local. This should be
|
||||
* used from objfmt yasm_output_value_func() functions.
|
||||
* functions.
|
||||
* \param value value
|
||||
* \param buf buffer for byte representation
|
||||
* \param destsize destination size (in bytes)
|
||||
* \param bc current bytecode (usually passed into higher-level
|
||||
* calling function)
|
||||
* \param warn enables standard warnings: zero for none;
|
||||
* nonzero for overflow/underflow floating point and
|
||||
* integer warnings
|
||||
* \param arch architecture
|
||||
* \note Adds in value.rel (correctly) if PC-relative and in the same section
|
||||
* as bc (and there is no WRT or SEG); if this is not the desired
|
||||
* behavior, e.g. a reloc is needed in this case, don't use this
|
||||
* function!
|
||||
* \return 0 if no value output due to value needing relocation;
|
||||
* 1 if value output; -1 if error.
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
int yasm_value_output_basic
|
||||
(yasm_value *value, /*@out@*/ unsigned char *buf, size_t destsize,
|
||||
yasm_bytecode *bc, int warn, yasm_arch *arch);
|
||||
|
||||
/** Print a value. For debugging purposes.
|
||||
* \param value value
|
||||
* \param indent_level indentation level
|
||||
* \param f file
|
||||
*/
|
||||
YASM_LIB_DECL
|
||||
void yasm_value_print(const yasm_value *value, FILE *f, int indent_level);
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user