Android Build Tools

This commit is contained in:
Isuru Samarathunga
2025-10-16 00:43:42 +05:30
parent f742dcfaff
commit 160bf65a1f
5549 changed files with 1752060 additions and 0 deletions

View File

@ -0,0 +1,5 @@
@echo off
setlocal
set ANDROID_NDK_PYTHON=%~dp0..\..\..\toolchains\llvm\prebuilt\windows-x86_64\python3\python.exe
set SHELL=cmd
"%ANDROID_NDK_PYTHON%" -u "%~dp0ndkgdb.pyz" %*

View File

@ -0,0 +1,5 @@
@echo off
setlocal
set ANDROID_NDK_PYTHON=%~dp0..\..\..\toolchains\llvm\prebuilt\windows-x86_64\python3\python.exe
set SHELL=cmd
"%ANDROID_NDK_PYTHON%" -u "%~dp0ndkstack.pyz" %*

View File

@ -0,0 +1,110 @@
#!/usr/bin/env bash
#
# Copyright (C) 2012 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
#
# DEPRECATED
#
# This script shows the path of the active toolchain components within
# the ndk. This was necessary for GCC and binutils, where each ABI had
# its own tools, but is not needed for LLVM-based tools which should be
# used in preference.
usage() {
echo "USAGE: ndk-which [--abi ABI] TOOL"
echo "ABI is 'armeabi-v7a', 'arm64-v8a', 'x86', or 'x86_64'"
echo "TOOL is 'gdb', 'objdump', 'readelf', etc."
echo
echo "Note that LLVM replacements for binutils tools work for all ABIs."
exit 1
}
error() {
echo "The tool: $1 doesn't exist"
echo "Possible choices are: "
count=0
for file in $2*
do
if [[ $file == *$1 ]]
then
echo $file
((count = count + 1))
fi
done
if [ $count -eq 0 ]
then
echo " None "
fi
exit 1
}
ABI=armeabi-v7a
while (( "$#" )); do
case "$1" in
--abi)
ABI=$2
shift 2
abis='^(armeabi-v7a|arm64-v8a|x86|x86_64)$'
if [[ ! "$ABI" =~ $abis ]]; then usage; fi
;;
*)
break
;;
esac
done
TOOL=$1
shift
if [ "$#" != 0 -o "$TOOL" == "" ]; then
usage
fi
# This tool is installed in prebuilt/linux-x86_64/bin/.
MYNDKDIR=`dirname $0`/../../..
# create a temporary skeleton project so that we can leverage build-local.mk
TMPDIR=/tmp/ndk-which-$$
mkdir -p $TMPDIR/jni
cat >$TMPDIR/jni/Android.mk << "END_OF_FILE"
include $(CLEAR_VARS)
END_OF_FILE
get_build_var_for_abi() {
if [ -z "$GNUMAKE" ] ; then
GNUMAKE=make
fi
NDK_PROJECT_PATH=$TMPDIR $GNUMAKE --no-print-dir -f $MYNDKDIR/build/core/build-local.mk DUMP_$1 APP_ABI=$2
}
LLVM_TOOLCHAIN_PREFIX=`get_build_var_for_abi LLVM_TOOLCHAIN_PREFIX $ABI`
TOOLCHAIN_PREFIX=`get_build_var_for_abi TOOLCHAIN_PREFIX $ABI`
rm -Rf $TMPDIR
# fully qualified file name
FQFN=${TOOLCHAIN_PREFIX}$TOOL
# use the host system's 'which' to decide/report if the file exists or not, and is executable
if [ ! -f $FQFN ]
then
FQFN=${LLVM_TOOLCHAIN_PREFIX}llvm-$TOOL
if [ ! -f $FQFN ]
then
error $TOOL $LLVM_TOOLCHAIN_PREFIX
fi
fi
which "$FQFN"

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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 */

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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 */

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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);

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -0,0 +1,349 @@
'\" t
.\" Title: yasm
.\" Author: Peter Johnson <peter@tortall.net>
.\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
.\" Date: April 2007
.\" Manual: The Yasm Modular Assembler
.\" Source: Yasm
.\" Language: English
.\"
.TH "YASM" "1" "April 2007" "Yasm" "The Yasm Modular Assembler"
.\" -----------------------------------------------------------------
.\" * set default formatting
.\" -----------------------------------------------------------------
.\" disable hyphenation
.nh
.\" disable justification (adjust text to left margin only)
.ad l
.\" -----------------------------------------------------------------
.\" * MAIN CONTENT STARTS HERE *
.\" -----------------------------------------------------------------
.SH "NAME"
yasm \- The Yasm Modular Assembler
.SH "SYNOPSIS"
.HP \w'\fByasm\fR\ 'u
\fByasm\fR [\fB\-f\ \fR\fB\fIformat\fR\fR] [\fB\-o\ \fR\fB\fIoutfile\fR\fR] [\fB\fIother\ options\fR\fR...] {\fIinfile\fR}
.HP \w'\fByasm\fR\ 'u
\fByasm\fR \fB\-h\fR
.SH "DESCRIPTION"
.PP
The Yasm Modular Assembler is a portable, retargetable assembler written under the
\(lqnew\(rq
(2 or 3 clause) BSD license\&. Yasm currently supports the x86 and AMD64 instruction sets, accepts NASM and GAS assembler syntaxes, outputs binary, ELF32, ELF64, COFF, Win32, and Win64 object formats, and generates source debugging information in STABS, DWARF 2, and CodeView 8 formats\&.
.PP
YASM consists of the
\fByasm\fR
command, libyasm, the core backend library, and a large number of modules\&. Currently, libyasm and the loadable modules are statically built into the
\fByasm\fR
executable\&.
.PP
The
\fByasm\fR
command assembles the file infile and directs output to the file
\fIoutfile\fR
if specified\&. If
\fIoutfile\fR
is not specified,
\fByasm\fR
will derive a default output file name from the name of its input file, usually by appending
\&.o
or
\&.obj, or by removing all extensions for a raw binary file\&. Failing that, the output file name will be
yasm\&.out\&.
.PP
If called with an
\fIinfile\fR
of
\(lq\-\(rq,
\fByasm\fR
assembles the standard input and directs output to the file
\fIoutfile\fR, or
yasm\&.out
if no
\fIoutfile\fR
is specified\&.
.SH "OPTIONS"
.PP
Many options may be given in one of two forms: either a dash followed by a single letter, or two dashes followed by a long option name\&. Options are listed in alphabetical order\&.
.SS "General Options"
.PP
\fB\-a \fR\fB\fIarch\fR\fR or \fB\-\-arch=\fR\fB\fIarch\fR\fR: Select target architecture
.RS 4
Selects the target architecture\&. The default architecture is
\(lqx86\(rq, which supports both the IA\-32 and derivatives and AMD64 instruction sets\&. To print a list of available architectures to standard output, use
\(lqhelp\(rq
as
\fIarch\fR\&. See
\fByasm_arch\fR(7)
for a list of supported architectures\&.
.RE
.PP
\fB\-f \fR\fB\fIformat\fR\fR or \fB\-\-oformat=\fR\fB\fIformat\fR\fR: Select object format
.RS 4
Selects the output object format\&. The default object format is
\(lqbin\(rq, which is a flat format binary with no relocation\&. To print a list of available object formats to standard output, use
\(lqhelp\(rq
as
\fIformat\fR\&. See
\fByasm_objfmts\fR(7)
for a list of supported object formats\&.
.RE
.PP
\fB\-g \fR\fB\fIdebug\fR\fR or \fB\-\-dformat=\fR\fB\fIdebug\fR\fR: Select debugging format
.RS 4
Selects the debugging format for debug information\&. Debugging information can be used by a debugger to associate executable code back to the source file or get data structure and type information\&. Available debug formats vary between different object formats;
\fByasm\fR
will error when an invalid combination is selected\&. The default object format is selected by the object format\&. To print a list of available debugging formats to standard output, use
\(lqhelp\(rq
as
\fIdebug\fR\&. See
\fByasm_dbgfmts\fR(7)
for a list of supported debugging formats\&.
.RE
.PP
\fB\-L \fR\fB\fIlist\fR\fR or \fB\-\-lformat=\fR\fB\fIlist\fR\fR: Select list file format
.RS 4
Selects the format/style of the output list file\&. List files typically intermix the original source with the machine code generated by the assembler\&. The default list format is
\(lqnasm\(rq, which mimics the NASM list file format\&. To print a list of available list file formats to standard output, use
\(lqhelp\(rq
as
\fIlist\fR\&.
.RE
.PP
\fB\-l \fR\fB\fIlistfile\fR\fR or \fB\-\-list=\fR\fB\fIlistfile\fR\fR: Specify list filename
.RS 4
Specifies the name of the output list file\&. If this option is not used, no list file is generated\&.
.RE
.PP
\fB\-m \fR\fB\fImachine\fR\fR or \fB\-\-machine=\fR\fB\fImachine\fR\fR: Select target machine architecture
.RS 4
Selects the target machine architecture\&. Essentially a subtype of the selected architecture, the machine type selects between major subsets of an architecture\&. For example, for the
\(lqx86\(rq
architecture, the two available machines are
\(lqx86\(rq, which is used for the IA\-32 and derivative 32\-bit instruction set, and
\(lqamd64\(rq, which is used for the 64\-bit instruction set\&. This differentiation is required to generate the proper object file for relocatable object formats such as COFF and ELF\&. To print a list of available machines for a given architecture to standard output, use
\(lqhelp\(rq
as
\fImachine\fR
and the given architecture using
\fB\-a \fR\fB\fIarch\fR\fR\&. See
\fByasm_arch\fR(7)
for more details\&.
.RE
.PP
\fB\-o \fR\fB\fIfilename\fR\fR or \fB\-\-objfile=\fR\fB\fIfilename\fR\fR: Specify object filename
.RS 4
Specifies the name of the output file, overriding any default name generated by Yasm\&.
.RE
.PP
\fB\-p \fR\fB\fIparser\fR\fR or \fB\-\-parser=\fR\fB\fIparser\fR\fR: Select parser
.RS 4
Selects the parser (the assembler syntax)\&. The default parser is
\(lqnasm\(rq, which emulates the syntax of NASM, the Netwide Assembler\&. Another available parser is
\(lqgas\(rq, which emulates the syntax of GNU AS\&. To print a list of available parsers to standard output, use
\(lqhelp\(rq
as
\fIparser\fR\&. See
\fByasm_parsers\fR(7)
for a list of supported parsers\&.
.RE
.PP
\fB\-r \fR\fB\fIpreproc\fR\fR or \fB\-\-preproc=\fR\fB\fIpreproc\fR\fR: Select preprocessor
.RS 4
Selects the preprocessor to use on the input file before passing it to the parser\&. Preprocessors often provide macro functionality that is not included in the main parser\&. The default preprocessor is
\(lqnasm\(rq, which is an imported version of the actual NASM preprocessor\&. A
\(lqraw\(rq
preprocessor is also available, which simply skips the preprocessing step, passing the input file directly to the parser\&. To print a list of available preprocessors to standard output, use
\(lqhelp\(rq
as
\fIpreproc\fR\&.
.RE
.PP
\fB\-h\fR or \fB\-\-help\fR: Print a summary of options
.RS 4
Prints a summary of invocation options\&. All other options are ignored, and no output file is generated\&.
.RE
.PP
\fB\-\-version\fR: Get the Yasm version
.RS 4
This option causes Yasm to prints the version number of Yasm as well as a license summary to standard output\&. All other options are ignored, and no output file is generated\&.
.RE
.SS "Warning Options"
.PP
\fB\-W\fR
options have two contrary forms:
\fB\-W\fR\fB\fIname\fR\fR
and
\fB\-Wno\-\fR\fB\fIname\fR\fR\&. Only the non\-default forms are shown here\&.
.PP
The warning options are handled in the order given on the command line, so if
\fB\-w\fR
is followed by
\fB\-Worphan\-labels\fR, all warnings are turned off
\fIexcept\fR
for orphan\-labels\&.
.PP
\fB\-w\fR: Inhibit all warning messages
.RS 4
This option causes Yasm to inhibit all warning messages\&. As discussed above, this option may be followed by other options to re\-enable specified warnings\&.
.RE
.PP
\fB\-Werror\fR: Treat warnings as errors
.RS 4
This option causes Yasm to treat all warnings as errors\&. Normally warnings do not prevent an object file from being generated and do not result in a failure exit status from
\fByasm\fR, whereas errors do\&. This option makes warnings equivalent to errors in terms of this behavior\&.
.RE
.PP
\fB\-Wno\-unrecognized\-char\fR: Do not warn on unrecognized input characters
.RS 4
Causes Yasm to not warn on unrecognized characters found in the input\&. Normally Yasm will generate a warning for any non\-ASCII character found in the input file\&.
.RE
.PP
\fB\-Worphan\-labels\fR: Warn on labels lacking a trailing option
.RS 4
When using the NASM\-compatible parser, causes Yasm to warn about labels found alone on a line without a trailing colon\&. While these are legal labels in NASM syntax, they may be unintentional, due to typos or macro definition ordering\&.
.RE
.PP
\fB\-X \fR\fB\fIstyle\fR\fR: Change error/warning reporting style
.RS 4
Selects a specific output style for error and warning messages\&. The default is
\(lqgnu\(rq
style, which mimics the output of
\fBgcc\fR\&. The
\(lqvc\(rq
style is also available, which mimics the output of Microsoft\'s Visual C++ compiler\&.
.sp
This option is available so that Yasm integrates more naturally into IDE environments such as
Visual Studio
or
Emacs, allowing the IDE to correctly recognize the error/warning message as such and link back to the offending line of source code\&.
.RE
.SS "Preprocessor Options"
.PP
While these preprocessor options theoretically will affect any preprocessor, the only preprocessor currently in Yasm is the
\(lqnasm\(rq
preprocessor\&.
.PP
\fB\-D \fR\fB\fImacro[=value]\fR\fR: Pre\-define a macro
.RS 4
Pre\-defines a single\-line macro\&. The value is optional (if no value is given, the macro is still defined, but to an empty value)\&.
.RE
.PP
\fB\-e\fR or \fB\-\-preproc\-only\fR: Only preprocess
.RS 4
Stops assembly after the preprocessing stage; preprocessed output is sent to the specified output name or, if no output name is specified, the standard output\&. No object file is produced\&.
.RE
.PP
\fB\-I \fR\fB\fIpath\fR\fR: Add include file path
.RS 4
Adds directory
\fIpath\fR
to the search path for include files\&. The search path defaults to only including the directory in which the source file resides\&.
.RE
.PP
\fB\-P \fR\fB\fIfilename\fR\fR: Pre\-include a file
.RS 4
Pre\-includes file
\fIfilename\fR, making it look as though
\fIfilename\fR
was prepended to the input\&. Can be useful for prepending multi\-line macros that the
\fB\-D\fR
can\'t support\&.
.RE
.PP
\fB\-U \fR\fB\fImacro\fR\fR: Undefine a macro
.RS 4
Undefines a single\-line macro (may be either a built\-in macro or one defined earlier in the command line with
\fB\-D\fR\&.
.RE
.SH "EXAMPLES"
.PP
To assemble NASM syntax, 32\-bit x86 source
source\&.asm
into ELF file
source\&.o, warning on orphan labels:
.sp
.if n \{\
.RS 4
.\}
.nf
yasm \-f elf32 \-Worphan\-labels source\&.asm
.fi
.if n \{\
.RE
.\}
.PP
To assemble NASM syntax AMD64 source
x\&.asm
into Win64 file
object\&.obj:
.sp
.if n \{\
.RS 4
.\}
.nf
yasm \-f win64 \-o object\&.obj x\&.asm
.fi
.if n \{\
.RE
.\}
.PP
To assemble already preprocessed NASM syntax x86 source
y\&.asm
into flat binary file
y\&.com:
.sp
.if n \{\
.RS 4
.\}
.nf
yasm \-f bin \-r raw \-o y\&.com y\&.asm
.fi
.if n \{\
.RE
.\}
.SH "DIAGNOSTICS"
.PP
The
\fByasm\fR
command exits 0 on success, and nonzero if an error occurs\&.
.SH "COMPATIBILITY"
.PP
Yasm\'s NASM parser and preprocessor, while they strive to be as compatible as possible with NASM, have a few incompatibilities due to YASM\'s different internal structure\&.
.PP
Yasm\'s GAS parser and preprocessor are missing a number of features present in GNU AS\&.
.SH "RESTRICTIONS"
.PP
As object files are often architecture and machine dependent, not all combinations of object formats, architectures, and machines are legal; trying to use an invalid combination will result in an error\&.
.PP
There is no support for symbol maps\&.
.SH "SEE ALSO"
.PP
\fByasm_arch\fR(7),
\fByasm_dbgfmts\fR(7),
\fByasm_objfmts\fR(7),
\fByasm_parsers\fR(7)
.PP
Related tools:
\fBas\fR(1),
\fBld\fR(1),
\fBnasm\fR(1)
.SH "BUGS"
.PP
When using the
\(lqx86\(rq
architecture, it is overly easy to generate AMD64 code (using the
\fBBITS 64\fR
directive) and generate a 32\-bit object file (by failing to specify
\fB\-m amd64\fR
or selecting a 64\-bit object format such as ELF64 on the command line)\&.
.SH "AUTHOR"
.PP
\fBPeter Johnson\fR <\&peter@tortall\&.net\&>
.RS 4
Author.
.RE
.SH "COPYRIGHT"
.br
Copyright \(co 2004, 2005, 2006, 2007 Peter Johnson
.br

View File

@ -0,0 +1,860 @@
'\" t
.\" Title: yasm_arch
.\" Author: Peter Johnson <peter@tortall.net>
.\" Generator: DocBook XSL Stylesheets v1.76.1 <http://docbook.sf.net/>
.\" Date: October 2006
.\" Manual: Yasm Supported Architectures
.\" Source: Yasm
.\" Language: English
.\"
.TH "YASM_ARCH" "7" "October 2006" "Yasm" "Yasm Supported Architectures"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.\" http://bugs.debian.org/507673
.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.ie \n(.g .ds Aq \(aq
.el .ds Aq '
.\" -----------------------------------------------------------------
.\" * set default formatting
.\" -----------------------------------------------------------------
.\" disable hyphenation
.nh
.\" disable justification (adjust text to left margin only)
.ad l
.\" -----------------------------------------------------------------
.\" * MAIN CONTENT STARTS HERE *
.\" -----------------------------------------------------------------
.SH "NAME"
yasm_arch \- Yasm Supported Target Architectures
.SH "SYNOPSIS"
.HP \w'\fByasm\fR\ 'u
\fByasm\fR \fB\-a\ \fR\fB\fIarch\fR\fR [\fB\-m\ \fR\fB\fImachine\fR\fR] \fB\fI\&.\&.\&.\fR\fR
.SH "DESCRIPTION"
.PP
The standard Yasm distribution includes a number of modules for different target architectures\&. Each target architecture can support one or more machine architectures\&.
.PP
The architecture and machine are selected on the
\fByasm\fR(1)
command line by use of the
\fB\-a \fR\fB\fIarch\fR\fR
and
\fB\-m \fR\fB\fImachine\fR\fR
command line options, respectively\&.
.PP
The machine architecture may also automatically be selected by certain object formats\&. For example, the
\(lqelf32\(rq
object format selects the
\(lqx86\(rq
machine architecture by default, while the
\(lqelf64\(rq
object format selects the
\(lqamd64\(rq
machine architecture by default\&.
.SH "X86 ARCHITECTURE"
.PP
The
\(lqx86\(rq
architecture supports the IA\-32 instruction set and derivatives and the AMD64 instruction set\&. It consists of two machines:
\(lqx86\(rq
(for the IA\-32 and derivatives) and
\(lqamd64\(rq
(for the AMD64 and derivatives)\&. The default machine for the
\(lqx86\(rq
architecture is the
\(lqx86\(rq
machine\&.
.SS "BITS Setting"
.PP
The x86 architecture BITS setting specifies to Yasm the processor mode in which the generated code is intended to execute\&. x86 processors can run in three different major execution modes: 16\-bit, 32\-bit, and on AMD64\-supporting processors, 64\-bit\&. As the x86 instruction set contains portions whose function is execution\-mode dependent (such as operand\-size and address\-size override prefixes), Yasm cannot assemble x86 instructions correctly unless it is told by the user in what processor mode the code will execute\&.
.PP
The BITS setting can be changed in a variety of ways\&. When using the NASM\-compatible parser, the BITS setting can be changed directly via the use of the
\fBBITS xx\fR
assembler directive\&. The default BITS setting is determined by the object format in use\&.
.SS "BITS 64 Extensions"
.PP
The AMD64 architecture is a new 64\-bit architecture developed by AMD, based on the 32\-bit x86 architecture\&. It extends the original x86 architecture by doubling the number of general purpose and SIMD registers, extending the arithmetic operations and address space to 64 bits, as well as other features\&.
.PP
Recently, Intel has introduced an essentially identical version of AMD64 called EM64T\&.
.PP
When an AMD64\-supporting processor is executing in 64\-bit mode, a number of additional extensions are available, including extra general purpose registers, extra SSE2 registers, and RIP\-relative addressing\&.
.PP
Yasm extends the base NASM syntax to support AMD64 as follows\&. To enable assembly of instructions for the 64\-bit mode of AMD64 processors, use the directive
\fBBITS 64\fR\&. As with NASM\*(Aqs BITS directive, this does not change the format of the output object file to 64 bits; it only changes the assembler mode to assume that the instructions being assembled will be run in 64\-bit mode\&. To specify an AMD64 object file, use
\fB\-m amd64\fR
on the Yasm command line, or explicitly target a 64\-bit object format such as
\fB\-f win64\fR
or
\fB\-f elf64\fR\&.
\fB\-f elfx32\fR
can be used to select 32\-bit ELF object format for AMD64 processors\&.
.sp
.it 1 an-trap
.nr an-no-space-flag 1
.nr an-break-flag 1
.br
.ps +1
\fBRegister Changes\fR
.RS 4
.PP
The additional 64\-bit general purpose registers are named r8\-r15\&. There are also 8\-bit (rXb), 16\-bit (rXw), and 32\-bit (rXd) subregisters that map to the least significant 8, 16, or 32 bits of the 64\-bit register\&. The original 8 general purpose registers have also been extended to 64\-bits: eax, edx, ecx, ebx, esi, edi, esp, and ebp have new 64\-bit versions called rax, rdx, rcx, rbx, rsi, rdi, rsp, and rbp respectively\&. The old 32\-bit registers map to the least significant bits of the new 64\-bit registers\&.
.PP
New 8\-bit registers are also available that map to the 8 least significant bits of rsi, rdi, rsp, and rbp\&. These are called sil, dil, spl, and bpl respectively\&. Unfortunately, due to the way instructions are encoded, these new 8\-bit registers are encoded the same as the old 8\-bit registers ah, dh, ch, and bh\&. The processor tells which is being used by the presence of the new REX prefix that is used to specify the other extended registers\&. This means it is illegal to mix the use of ah, dh, ch, and bh with an instruction that requires the REX prefix for other reasons\&. For instance:
.sp
.if n \{\
.RS 4
.\}
.nf
add ah, [r10]
.fi
.if n \{\
.RE
.\}
.PP
(NASM syntax) is not a legal instruction because the use of r10 requires a REX prefix, making it impossible to use ah\&.
.PP
In 64\-bit mode, an additional 8 SSE2 registers are also available\&. These are named xmm8\-xmm15\&.
.RE
.sp
.it 1 an-trap
.nr an-no-space-flag 1
.nr an-break-flag 1
.br
.ps +1
\fB64 Bit Instructions\fR
.RS 4
.PP
By default, most operations in 64\-bit mode remain 32\-bit; operations that are 64\-bit usually require a REX prefix (one bit in the REX prefix determines whether an operation is 64\-bit or 32\-bit)\&. Thus, essentially all 32\-bit instructions have a 64\-bit version, and the 64\-bit versions of instructions can use extended registers
\(lqfor free\(rq
(as the REX prefix is already present)\&. Examples in NASM syntax:
.sp
.if n \{\
.RS 4
.\}
.nf
mov eax, 1 ; 32\-bit instruction
.fi
.if n \{\
.RE
.\}
.sp
.if n \{\
.RS 4
.\}
.nf
mov rcx, 1 ; 64\-bit instruction
.fi
.if n \{\
.RE
.\}
.PP
Instructions that modify the stack (push, pop, call, ret, enter, and leave) are implicitly 64\-bit\&. Their 32\-bit counterparts are not available, but their 16\-bit counterparts are\&. Examples in NASM syntax:
.sp
.if n \{\
.RS 4
.\}
.nf
push eax ; illegal instruction
.fi
.if n \{\
.RE
.\}
.sp
.if n \{\
.RS 4
.\}
.nf
push rbx ; 1\-byte instruction
.fi
.if n \{\
.RE
.\}
.sp
.if n \{\
.RS 4
.\}
.nf
push r11 ; 2\-byte instruction with REX prefix
.fi
.if n \{\
.RE
.\}
.RE
.sp
.it 1 an-trap
.nr an-no-space-flag 1
.nr an-break-flag 1
.br
.ps +1
\fBImplicit Zero Extension\fR
.RS 4
.PP
Results of 32\-bit operations are implicitly zero\-extended to the upper 32 bits of the corresponding 64\-bit register\&. 16 and 8 bit operations, on the other hand, do not affect upper bits of the register (just as in 32\-bit and 16\-bit modes)\&. This can be used to generate smaller code in some instances\&. Examples in NASM syntax:
.sp
.if n \{\
.RS 4
.\}
.nf
mov ecx, 1 ; 1 byte shorter than mov rcx, 1
.fi
.if n \{\
.RE
.\}
.sp
.if n \{\
.RS 4
.\}
.nf
and edx, 3 ; equivalent to and rdx, 3
.fi
.if n \{\
.RE
.\}
.RE
.sp
.it 1 an-trap
.nr an-no-space-flag 1
.nr an-break-flag 1
.br
.ps +1
\fBImmediates\fR
.RS 4
.PP
For most instructions in 64\-bit mode, immediate values remain 32 bits; their value is sign\-extended into the upper 32 bits of the target register prior to being used\&. The exception is the mov instruction, which can take a 64\-bit immediate when the destination is a 64\-bit register\&. Examples in NASM syntax:
.sp
.if n \{\
.RS 4
.\}
.nf
add rax, 1 ; optimized down to signed 8\-bit
.fi
.if n \{\
.RE
.\}
.sp
.if n \{\
.RS 4
.\}
.nf
add rax, dword 1 ; force size to 32\-bit
.fi
.if n \{\
.RE
.\}
.sp
.if n \{\
.RS 4
.\}
.nf
add rax, 0xffffffff ; sign\-extended 32\-bit
.fi
.if n \{\
.RE
.\}
.sp
.if n \{\
.RS 4
.\}
.nf
add rax, \-1 ; same as above
.fi
.if n \{\
.RE
.\}
.sp
.if n \{\
.RS 4
.\}
.nf
add rax, 0xffffffffffffffff ; truncated to 32\-bit (warning)
.fi
.if n \{\
.RE
.\}
.sp
.if n \{\
.RS 4
.\}
.nf
mov eax, 1 ; 5 byte
.fi
.if n \{\
.RE
.\}
.sp
.if n \{\
.RS 4
.\}
.nf
mov rax, 1 ; 5 byte (optimized to signed 32\-bit)
.fi
.if n \{\
.RE
.\}
.sp
.if n \{\
.RS 4
.\}
.nf
mov rax, qword 1 ; 10 byte (forced 64\-bit)
.fi
.if n \{\
.RE
.\}
.sp
.if n \{\
.RS 4
.\}
.nf
mov rbx, 0x1234567890abcdef ; 10 byte
.fi
.if n \{\
.RE
.\}
.sp
.if n \{\
.RS 4
.\}
.nf
mov rcx, 0xffffffff ; 10 byte (does not fit in signed 32\-bit)
.fi
.if n \{\
.RE
.\}
.sp
.if n \{\
.RS 4
.\}
.nf
mov ecx, \-1 ; 5 byte, equivalent to above
.fi
.if n \{\
.RE
.\}
.sp
.if n \{\
.RS 4
.\}
.nf
mov rcx, sym ; 5 byte, 32\-bit size default for symbols
.fi
.if n \{\
.RE
.\}
.sp
.if n \{\
.RS 4
.\}
.nf
mov rcx, qword sym ; 10 byte, override default size
.fi
.if n \{\
.RE
.\}
.PP
The handling of mov reg64, unsized immediate is different between YASM and NASM 2\&.x; YASM follows the above behavior, while NASM 2\&.x does the following:
.sp
.if n \{\
.RS 4
.\}
.nf
add rax, 0xffffffff ; sign\-extended 32\-bit immediate
.fi
.if n \{\
.RE
.\}
.sp
.if n \{\
.RS 4
.\}
.nf
add rax, \-1 ; same as above
.fi
.if n \{\
.RE
.\}
.sp
.if n \{\
.RS 4
.\}
.nf
add rax, 0xffffffffffffffff ; truncated 32\-bit (warning)
.fi
.if n \{\
.RE
.\}
.sp
.if n \{\
.RS 4
.\}
.nf
add rax, sym ; sign\-extended 32\-bit immediate
.fi
.if n \{\
.RE
.\}
.sp
.if n \{\
.RS 4
.\}
.nf
mov eax, 1 ; 5 byte (32\-bit immediate)
.fi
.if n \{\
.RE
.\}
.sp
.if n \{\
.RS 4
.\}
.nf
mov rax, 1 ; 10 byte (64\-bit immediate)
.fi
.if n \{\
.RE
.\}
.sp
.if n \{\
.RS 4
.\}
.nf
mov rbx, 0x1234567890abcdef ; 10 byte instruction
.fi
.if n \{\
.RE
.\}
.sp
.if n \{\
.RS 4
.\}
.nf
mov rcx, 0xffffffff ; 10 byte instruction
.fi
.if n \{\
.RE
.\}
.sp
.if n \{\
.RS 4
.\}
.nf
mov ecx, \-1 ; 5 byte, equivalent to above
.fi
.if n \{\
.RE
.\}
.sp
.if n \{\
.RS 4
.\}
.nf
mov ecx, sym ; 5 byte (32\-bit immediate)
.fi
.if n \{\
.RE
.\}
.sp
.if n \{\
.RS 4
.\}
.nf
mov rcx, sym ; 10 byte instruction
.fi
.if n \{\
.RE
.\}
.sp
.if n \{\
.RS 4
.\}
.nf
mov rcx, qword sym ; 10 byte (64\-bit immediate)
.fi
.if n \{\
.RE
.\}
.RE
.sp
.it 1 an-trap
.nr an-no-space-flag 1
.nr an-break-flag 1
.br
.ps +1
\fBDisplacements\fR
.RS 4
.PP
Just like immediates, displacements, for the most part, remain 32 bits and are sign extended prior to use\&. Again, the exception is one restricted form of the mov instruction: between the al/ax/eax/rax register and a 64\-bit absolute address (no registers allowed in the effective address)\&. In NASM syntax, use of the 64\-bit absolute form requires
\fB[qword]\fR\&. Examples in NASM syntax:
.sp
.if n \{\
.RS 4
.\}
.nf
mov eax, [1] ; 32 bit, with sign extension
.fi
.if n \{\
.RE
.\}
.sp
.if n \{\
.RS 4
.\}
.nf
mov al, [rax\-1] ; 32 bit, with sign extension
.fi
.if n \{\
.RE
.\}
.sp
.if n \{\
.RS 4
.\}
.nf
mov al, [qword 0x1122334455667788] ; 64\-bit absolute
.fi
.if n \{\
.RE
.\}
.sp
.if n \{\
.RS 4
.\}
.nf
mov al, [0x1122334455667788] ; truncated to 32\-bit (warning)
.fi
.if n \{\
.RE
.\}
.RE
.sp
.it 1 an-trap
.nr an-no-space-flag 1
.nr an-break-flag 1
.br
.ps +1
\fBRIP Relative Addressing\fR
.RS 4
.PP
In 64\-bit mode, a new form of effective addressing is available to make it easier to write position\-independent code\&. Any memory reference may be made RIP relative (RIP is the instruction pointer register, which contains the address of the location immediately following the current instruction)\&.
.PP
In NASM syntax, there are two ways to specify RIP\-relative addressing:
.sp
.if n \{\
.RS 4
.\}
.nf
mov dword [rip+10], 1
.fi
.if n \{\
.RE
.\}
.PP
stores the value 1 ten bytes after the end of the instruction\&.
\fB10\fR
can also be a symbolic constant, and will be treated the same way\&. On the other hand,
.sp
.if n \{\
.RS 4
.\}
.nf
mov dword [symb wrt rip], 1
.fi
.if n \{\
.RE
.\}
.PP
stores the value 1 into the address of symbol
\fBsymb\fR\&. This is distinctly different than the behavior of:
.sp
.if n \{\
.RS 4
.\}
.nf
mov dword [symb+rip], 1
.fi
.if n \{\
.RE
.\}
.PP
which takes the address of the end of the instruction, adds the address of
\fBsymb\fR
to it, then stores the value 1 there\&. If
\fBsymb\fR
is a variable, this will
\fInot\fR
store the value 1 into the
\fBsymb\fR
variable!
.PP
Yasm also supports the following syntax for RIP\-relative addressing:
.sp
.if n \{\
.RS 4
.\}
.nf
mov [rel sym], rax ; RIP\-relative
.fi
.if n \{\
.RE
.\}
.sp
.if n \{\
.RS 4
.\}
.nf
mov [abs sym], rax ; not RIP\-relative
.fi
.if n \{\
.RE
.\}
.PP
The behavior of:
.sp
.if n \{\
.RS 4
.\}
.nf
mov [sym], rax
.fi
.if n \{\
.RE
.\}
.PP
Depends on a mode set by the DEFAULT directive, as follows\&. The default mode is always "abs", and in "rel" mode, use of registers, an fs or gs segment override, or an explicit "abs" override will result in a non\-RIP\-relative effective address\&.
.sp
.if n \{\
.RS 4
.\}
.nf
default rel
.fi
.if n \{\
.RE
.\}
.sp
.if n \{\
.RS 4
.\}
.nf
mov [sym], rbx ; RIP\-relative
.fi
.if n \{\
.RE
.\}
.sp
.if n \{\
.RS 4
.\}
.nf
mov [abs sym], rbx ; not RIP\-relative (explicit override)
.fi
.if n \{\
.RE
.\}
.sp
.if n \{\
.RS 4
.\}
.nf
mov [rbx+1], rbx ; not RIP\-relative (register use)
.fi
.if n \{\
.RE
.\}
.sp
.if n \{\
.RS 4
.\}
.nf
mov [fs:sym], rbx ; not RIP\-relative (fs or gs use)
.fi
.if n \{\
.RE
.\}
.sp
.if n \{\
.RS 4
.\}
.nf
mov [ds:sym], rbx ; RIP\-relative (segment, but not fs or gs)
.fi
.if n \{\
.RE
.\}
.sp
.if n \{\
.RS 4
.\}
.nf
mov [rel sym], rbx ; RIP\-relative (redundant override)
.fi
.if n \{\
.RE
.\}
.sp
.if n \{\
.RS 4
.\}
.nf
default abs
.fi
.if n \{\
.RE
.\}
.sp
.if n \{\
.RS 4
.\}
.nf
mov [sym], rbx ; not RIP\-relative
.fi
.if n \{\
.RE
.\}
.sp
.if n \{\
.RS 4
.\}
.nf
mov [abs sym], rbx ; not RIP\-relative
.fi
.if n \{\
.RE
.\}
.sp
.if n \{\
.RS 4
.\}
.nf
mov [rbx+1], rbx ; not RIP\-relative
.fi
.if n \{\
.RE
.\}
.sp
.if n \{\
.RS 4
.\}
.nf
mov [fs:sym], rbx ; not RIP\-relative
.fi
.if n \{\
.RE
.\}
.sp
.if n \{\
.RS 4
.\}
.nf
mov [ds:sym], rbx ; not RIP\-relative
.fi
.if n \{\
.RE
.\}
.sp
.if n \{\
.RS 4
.\}
.nf
mov [rel sym], rbx ; RIP\-relative (explicit override)
.fi
.if n \{\
.RE
.\}
.RE
.sp
.it 1 an-trap
.nr an-no-space-flag 1
.nr an-break-flag 1
.br
.ps +1
\fBMemory references\fR
.RS 4
.PP
Usually the size of a memory reference can be deduced by which registers you\*(Aqre moving\-\-for example, "mov [rax],ecx" is a 32\-bit move, because ecx is 32 bits\&. YASM currently gives the non\-obvious "invalid combination of opcode and operands" error if it can\*(Aqt figure out how much memory you\*(Aqre moving\&. The fix in this case is to add a memory size specifier: qword, dword, word, or byte\&.
.PP
Here\*(Aqs a 64\-bit memory move, which sets 8 bytes starting at rax:
.sp
.if n \{\
.RS 4
.\}
.nf
mov qword [rax], 1
.fi
.if n \{\
.RE
.\}
.PP
Here\*(Aqs a 32\-bit memory move, which sets 4 bytes:
.sp
.if n \{\
.RS 4
.\}
.nf
mov dword [rax], 1
.fi
.if n \{\
.RE
.\}
.PP
Here\*(Aqs a 16\-bit memory move, which sets 2 bytes:
.sp
.if n \{\
.RS 4
.\}
.nf
mov word [rax], 1
.fi
.if n \{\
.RE
.\}
.PP
Here\*(Aqs an 8\-bit memory move, which sets 1 byte:
.sp
.if n \{\
.RS 4
.\}
.nf
mov byte [rax], 1
.fi
.if n \{\
.RE
.\}
.RE
.SH "LC3B ARCHITECTURE"
.PP
The
\(lqlc3b\(rq
architecture supports the LC\-3b ISA as used in the ECE 312 (now ECE 411) course at the University of Illinois, Urbana\-Champaign, as well as other university courses\&. See
\m[blue]\fB\%http://courses.ece.uiuc.edu/ece411/\fR\m[]
for more details and example code\&. The
\(lqlc3b\(rq
architecture consists of only one machine:
\(lqlc3b\(rq\&.
.SH "SEE ALSO"
.PP
\fByasm\fR(1)
.SH "BUGS"
.PP
When using the
\(lqx86\(rq
architecture, it is overly easy to generate AMD64 code (using the
\fBBITS 64\fR
directive) and generate a 32\-bit object file (by failing to specify
\fB\-m amd64\fR
on the command line or selecting a 64\-bit object format)\&. Similarly, specifying
\fB\-m amd64\fR
does not default the BITS setting to 64\&. An easy way to avoid this is by directly specifying a 64\-bit object format such as
\fB\-f elf64\fR\&.
.SH "AUTHOR"
.PP
\fBPeter Johnson\fR <\&peter@tortall\&.net\&>
.RS 4
Author.
.RE
.SH "COPYRIGHT"
.br
Copyright \(co 2004, 2005, 2006, 2007 Peter Johnson
.br

View File

@ -0,0 +1,63 @@
'\" t
.\" Title: yasm_dbgfmts
.\" Author: Peter Johnson <peter@tortall.net>
.\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
.\" Date: October 2006
.\" Manual: Yasm Supported Debug Formats
.\" Source: Yasm
.\" Language: English
.\"
.TH "YASM_DBGFMTS" "7" "October 2006" "Yasm" "Yasm Supported Debug Formats"
.\" -----------------------------------------------------------------
.\" * set default formatting
.\" -----------------------------------------------------------------
.\" disable hyphenation
.nh
.\" disable justification (adjust text to left margin only)
.ad l
.\" -----------------------------------------------------------------
.\" * MAIN CONTENT STARTS HERE *
.\" -----------------------------------------------------------------
.SH "NAME"
yasm_dbgfmts \- Yasm Supported Debugging Formats
.SH "SYNOPSIS"
.HP \w'\fByasm\fR\ 'u
\fByasm\fR \fB\-g\ \fR\fB\fIdbgfmt\fR\fR \fB\fI\&.\&.\&.\fR\fR
.SH "DESCRIPTION"
.PP
The standard Yasm distribution includes a number of modules for different debugging formats\&. The debugging information is embedded into the object file\&. Use of a non\-\(lqnull\(rq
debug format also causes Yasm to output all symbols to the object file (including local symbols)\&.
.PP
The debug format is selected on the
\fByasm\fR(1)
command line by use of the
\fB\-g \fR\fB\fIdbgfmt\fR\fR
command line option\&.
.SH "CV8"
.PP
The CV8 debug format is used by Microsoft Visual Studio 2005 (version 8\&.0) and is completely undocumented, although it bears strong similarities to earlier CodeView formats\&. Yasm\'s support for the CV8 debug format is currently limited to generating assembly\-level line number information (to allow some level of source\-level debugging)\&. The CV8 debug information is stored in the \&.debug$S and \&.debug$T sections of the Win64 object file\&.
.SH "DWARF2"
.PP
The DWARF 2 debug format is a complex, well\-documented standard for debugging information\&. It was created to overcome shortcomings in STABS, allowing for much more detailed and compact descriptions of data structures, data variable movement, and complex language structures such as in C++\&. The debugging information is stored in sections (just like normal program sections) in the object file\&. Yasm supports full pass\-through of DWARF2 debugging information (e\&.g\&. from a C++ compiler), and can also generate assembly\-level line number information\&.
.SH "NULL"
.PP
The
\(lqnull\(rq
debug format is a placeholder; it adds no debugging information to the output file\&.
.SH "STABS"
.PP
The STABS debug format is a poorly documented, semi\-standard format for debugging information in COFF and ELF object files\&. The debugging information is stored as part of the object file\'s symbol table and thus is limited in complexity and scope\&. Despite this, STABS is a common debugging format on older Unix and compatible systems, as well as DJGPP\&.
.SH "SEE ALSO"
.PP
\fByasm\fR(1),
\fByasm_objfmts\fR(7)
.SH "AUTHOR"
.PP
\fBPeter Johnson\fR <\&peter@tortall\&.net\&>
.RS 4
Author.
.RE
.SH "COPYRIGHT"
.br
Copyright \(co 2006 Peter Johnson
.br

View File

@ -0,0 +1,102 @@
'\" t
.\" Title: yasm_objfmts
.\" Author: Peter Johnson <peter@tortall.net>
.\" Generator: DocBook XSL Stylesheets v1.76.1 <http://docbook.sf.net/>
.\" Date: February 2007
.\" Manual: Yasm Supported Object Formats
.\" Source: Yasm
.\" Language: English
.\"
.TH "YASM_OBJFMTS" "7" "February 2007" "Yasm" "Yasm Supported Object Formats"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.\" http://bugs.debian.org/507673
.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.ie \n(.g .ds Aq \(aq
.el .ds Aq '
.\" -----------------------------------------------------------------
.\" * set default formatting
.\" -----------------------------------------------------------------
.\" disable hyphenation
.nh
.\" disable justification (adjust text to left margin only)
.ad l
.\" -----------------------------------------------------------------
.\" * MAIN CONTENT STARTS HERE *
.\" -----------------------------------------------------------------
.SH "NAME"
yasm_objfmts \- Yasm Supported Object Formats
.SH "SYNOPSIS"
.HP \w'\fByasm\fR\ 'u
\fByasm\fR \fB\-f\ \fR\fB\fIobjfmt\fR\fR \fB\fI\&.\&.\&.\fR\fR
.SH "DESCRIPTION"
.PP
The standard Yasm distribution includes a number of modules for different object formats (Yasm\*(Aqs primary output)\&.
.PP
The object format is selected on the
\fByasm\fR(1)
command line by use of the
\fB\-f \fR\fB\fIobjfmt\fR\fR
command line option\&.
.SH "BIN"
.PP
The
\(lqbin\(rq
object format produces a flat\-format, non\-relocatable binary file\&. It is appropriate for producing DOS \&.COM executables or things like boot blocks\&. It supports only 3 sections and those sections are written in a predefined order to the output file\&.
.SH "COFF"
.PP
The COFF object format is an older relocatable object format used on older Unix and compatible systems, and also (more recently) on the DJGPP development system for DOS\&.
.SH "DBG"
.PP
The
\(lqdbg\(rq
object format is not a
\(lqreal\(rq
object format; the output file it creates simply describes the sequence of calls made to it by Yasm and the final object and symbol table information in a human\-readable text format (that in a normal object format would get processed into that object format\*(Aqs particular binary representation)\&. This object format is not intended for real use, but rather for debugging Yasm\*(Aqs internals\&.
.SH "ELF"
.PP
The ELF object format really comes in three flavors:
\(lqelf32\(rq
(for 32\-bit targets),
\(lqelf64\(rq
(for 64\-bit targets and
\(lqelfx32\(rq
(for x32 targets)\&. ELF is a standard object format in common use on modern Unix and compatible systems (e\&.g\&. Linux, FreeBSD)\&. ELF has complex support for relocatable and shared objects\&.
.SH "MACHO"
.PP
The Mach\-O object format really comes in two flavors:
\(lqmacho32\(rq
(for 32\-bit targets) and
\(lqmacho64\(rq
(for 64\-bit targets)\&. Mach\-O is used as the object format on MacOS X\&. As Yasm currently only supports x86 and AMD64 instruction sets, it can only generate Mach\-O objects for Intel\-based Macs\&.
.SH "RDF"
.PP
The RDOFF2 object format is a simple multi\-section format originally designed for NASM\&. It supports segment references but not WRT references\&. It was designed primarily for simplicity and has minimalistic headers for ease of loading and linking\&. A complete toolchain (linker, librarian, and loader) is distributed with NASM\&.
.SH "WIN32"
.PP
The Win32 object format produces object files compatible with Microsoft compilers (such as Visual C++) that target the 32\-bit x86 Windows platform\&. The object format itself is an extended version of COFF\&.
.SH "WIN64"
.PP
The Win64 object format produces object files compatible with Microsoft compilers that target the 64\-bit
\(lqx64\(rq
Windows platform\&. This format is very similar to the win32 object format, but produces 64\-bit objects\&.
.SH "XDF"
.PP
The XDF object format is essentially a simplified version of COFF\&. It\*(Aqs a multi\-section relocatable format that supports 64\-bit physical and virtual addresses\&.
.SH "SEE ALSO"
.PP
\fByasm\fR(1),
\fByasm_arch\fR(7)
.SH "AUTHOR"
.PP
\fBPeter Johnson\fR <\&peter@tortall\&.net\&>
.RS 4
Author.
.RE
.SH "COPYRIGHT"
.br
Copyright \(co 2006 Peter Johnson
.br

View File

@ -0,0 +1,58 @@
'\" t
.\" Title: yasm_parsers
.\" Author: Peter Johnson <peter@tortall.net>
.\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
.\" Date: October 2006
.\" Manual: Yasm Supported Parsers
.\" Source: Yasm
.\" Language: English
.\"
.TH "YASM_PARSERS" "7" "October 2006" "Yasm" "Yasm Supported Parsers"
.\" -----------------------------------------------------------------
.\" * set default formatting
.\" -----------------------------------------------------------------
.\" disable hyphenation
.nh
.\" disable justification (adjust text to left margin only)
.ad l
.\" -----------------------------------------------------------------
.\" * MAIN CONTENT STARTS HERE *
.\" -----------------------------------------------------------------
.SH "NAME"
yasm_parsers \- Yasm Supported Parsers (Assembler Syntaxes)
.SH "SYNOPSIS"
.HP \w'\fByasm\fR\ 'u
\fByasm\fR \fB\-p\ \fR\fB\fIparser\fR\fR [\fB\-r\ \fR\fB\fIpreproc\fR\fR] \fB\fI\&.\&.\&.\fR\fR
.SH "DESCRIPTION"
.PP
The standard Yasm distribution includes a number of modules for different parsers (assembler syntaxes)\&.
.PP
The parser is selected on the
\fByasm\fR(1)
command line by use of the
\fB\-p \fR\fB\fIparser\fR\fR
command line option\&.
.SH "NASM PARSER"
.PP
NASM syntax, selected with
\fB\-p nasm\fR, is the most full\-featured syntax supported by Yasm\&. Yasm is nearly 100% compatible with NASM for 16\-bit and 32\-bit x86 code\&. Yasm additionally supports 64\-bit AMD64 code with Yasm extensions to the NASM syntax; see
\fByasm_arch\fR(7)
for details\&. NASM syntax is the Yasm default\&.
.SH "GAS PARSER"
.PP
The GNU Assembler (GAS) is the de\-facto cross\-platform assembler for modern Unix systems, and is used as the backend for the GCC compiler\&. Yasm\'s support for GAS syntax is moderately good, although immature: not all directives are supported, and only 32\-bit x86 and AMD64 architectures are supported\&. Nearly all of the GAS preprocessor is also supported\&. Yasm\'s GAS syntax support is good enough to handle essentially all x86 and AMD64 GCC compiler output\&. The GAS parser can be selected with
\fB\-p gas\fR\&.
.SH "SEE ALSO"
.PP
\fByasm\fR(1),
\fByasm_arch\fR(7)
.SH "AUTHOR"
.PP
\fBPeter Johnson\fR <\&peter@tortall\&.net\&>
.RS 4
Author.
.RE
.SH "COPYRIGHT"
.br
Copyright \(co 2006 Peter Johnson
.br