-/* $IdPath$
- * YASM architecture interface header file
+/**
+ * \file arch.h
+ * \brief YASM architecture interface.
+ *
+ * $IdPath$
*
* Copyright (C) 2002 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
+ * - 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
+ * - 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.
*
#ifndef YASM_ARCH_H
#define YASM_ARCH_H
+/** Return value from yasm_arch::check_identifier(). */
typedef enum {
- YASM_ARCH_CHECK_ID_NONE = 0, /* just a normal identifier */
- YASM_ARCH_CHECK_ID_INSN, /* an instruction */
- YASM_ARCH_CHECK_ID_PREFIX, /* an instruction prefix */
- YASM_ARCH_CHECK_ID_REG, /* a register */
- YASM_ARCH_CHECK_ID_SEGREG, /* a segment register (for memory overrides) */
- YASM_ARCH_CHECK_ID_TARGETMOD /* an target modifier (for jumps) */
+ YASM_ARCH_CHECK_ID_NONE = 0, /**< Just a normal identifier. */
+ YASM_ARCH_CHECK_ID_INSN, /**< An instruction. */
+ YASM_ARCH_CHECK_ID_PREFIX, /**< An instruction prefix. */
+ YASM_ARCH_CHECK_ID_REG, /**< A register. */
+ YASM_ARCH_CHECK_ID_SEGREG,/**< a segment register (for memory overrides). */
+ YASM_ARCH_CHECK_ID_TARGETMOD /**< A target modifier (for jumps) */
} yasm_arch_check_id_retval;
+/** An instruction operand (opaque type). */
typedef struct yasm_insn_operand yasm_insn_operand;
+/** A list of instruction operands (opaque type).
+ * The list goes from left-to-right as parsed.
+ */
typedef struct yasm_insn_operandhead yasm_insn_operandhead;
#ifdef YASM_INTERNAL
/*@reldef@*/ STAILQ_HEAD(yasm_insn_operandhead, yasm_insn_operand);
#endif
-/* Different assemblers order instruction operands differently. Also, some
+/** "Flavor" of the parser.
+ * Different assemblers order instruction operands differently. Also, some
* differ on how exactly various registers are specified. There's no great
* solution to this, as the parsers aren't supposed to have knowledge of the
- * architectural internals, and the architecture is supposed to be parser-
+ * architectural internals, and the architecture is supposed to be parser
* independent. To make things work, as a rather hackish solution, we give the
* architecture a little knowledge about the general "flavor" of the parser,
* and let the architecture decide what to do with it. Most architectures will
* for correct behavior on all parsers.
*/
typedef enum {
- YASM_ARCH_SYNTAX_FLAVOR_NASM = 1, /* like NASM */
- YASM_ARCH_SYNTAX_FLAVOR_GAS /* like GAS */
+ YASM_ARCH_SYNTAX_FLAVOR_NASM = 1, /**< Like NASM */
+ YASM_ARCH_SYNTAX_FLAVOR_GAS /**< Like GAS */
} yasm_arch_syntax_flavor;
+/** YASM architecture interface.
+ * \note All "data" in parser-related functions needs to start the parse
+ * initialized to 0 to make it okay for a parser-related function to
+ * use/check previously stored data to see if it's been called before on
+ * the same piece of data.
+ */
struct yasm_arch {
- /* one-line description of the architecture */
+ /** One-line description of the architecture. */
const char *name;
- /* keyword used to select architecture */
+ /** Keyword used to select architecture. */
const char *keyword;
+ /** Initialize architecture for use. */
void (*initialize) (void);
- void (*cleanup) (void);
- /* All "data" below starts the parse initialized to 0. Thus, it is
- * okay for a funtion to use/check previously stored data to see if
- * it's been called before on the same piece of data.
- */
+ /** Clean up, free any architecture-allocated memory. */
+ void (*cleanup) (void);
- /* Switches available instructions/registers/etc. based on a
- * user-specified CPU identifier. Should modify behavior ONLY of
- * parse_* functions! The bytecode and output functions should be able
- * to handle any CPU.
+ /** Switch available instructions/registers/etc based on a user-specified
+ * CPU identifier. Should modify behavior ONLY of parse_* functions! The
+ * bytecode and output functions should be able to handle any CPU.
+ * \param cpuid cpu identifier as in the input file
+ * \param lindex line index (as from yasm_linemgr)
*/
void (*parse_cpu) (const char *cpuid, unsigned long lindex);
- /* Checks an generic identifier to see if it matches architecture
- * specific names for instructions, registers, etc (see the
- * arch_check_id_retval enum above for the various types this function
- * can detect & return. Unrecognized identifiers should be returned
- * as NONE 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.
- * Note: even though this is passed a data[4], only data[0] should be
- * used for TARGETMOD, REG, and SEGREG return values.
+ /** Check an generic identifier to see if it matches architecture specific
+ * names for instructions, registers, etc. Unrecognized identifiers should
+ * be returned as #YASM_ARCH_CHECK_ID_NONE 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.
+ * \note Even though this is passed a data[4], only data[0] should be used
+ * for #YASM_ARCH_CHECK_ID_TARGETMOD, #YASM_ARCH_CHECK_ID_REG, and
+ * #YASM_ARCH_CHECK_ID_SEGREG return values.
+ * \param data extra identification information (yasm_arch-specific)
+ * [output]
+ * \param id identifier as in the input file
+ * \param lindex line index (as from yasm_linemgr)
+ * \return General type of identifier (#yasm_arch_check_id_retval).
*/
yasm_arch_check_id_retval (*parse_check_id)
(unsigned long data[4], const char *id, unsigned long lindex);
- /* Architecture-specific directive support. Returns 1 if directive was
- * not recognized. Returns 0 if directive was recognized, even if it
- * wasn't valid. Should modify behavior ONLY of parse functions, much
- * like switch_cpu() above.
+ /** Handle architecture-specific directives.
+ * Should modify behavior ONLY of parse functions, much like switch_cpu().
+ * \param name directive name
+ * \param valparams value/parameters
+ * \param objext_valparams object format extensions
+ * value/parameters
+ * \param headp list of sections
+ * \param lindex line index (as from yasm_linemgr)
+ * \return Nonzero if directive was recognized; 0 if directive was
+ * recognized, even if it wasn't valid.
*/
int (*parse_directive) (const char *name, yasm_valparamhead *valparams,
/*@null@*/ yasm_valparamhead *objext_valparams,
yasm_sectionhead *headp, unsigned long lindex);
- /* Creates an instruction. Creates a bytecode by matching the
+ /** Create an instruction. Creates a bytecode by matching the
* instruction data and the parameters given with a valid instruction.
- * If no match is found (the instruction is invalid), returns NULL.
- * All zero data indicates an empty instruction should be created.
+ * \param data instruction data (from check_identifier()); all
+ * zero indicates an empty instruction
+ * \param num_operands number of operands parsed
+ * \param operands list of operands (in parse order)
+ * \param cur_section currently active section
+ * \param prev_bc previously parsed bytecode in section (NULL if
+ * first bytecode in section)
+ * \param lindex line index (as from yasm_linemgr)
+ * \return If no match is found (the instruction is invalid), NULL,
+ * otherwise newly allocated bytecode containing instruction.
*/
/*@null@*/ yasm_bytecode * (*parse_insn)
(const unsigned long data[4], int num_operands,
- /*@null@*/ yasm_insn_operandhead *operands,
- yasm_section *cur_section, /*@null@*/ yasm_bytecode *prev_bc,
- unsigned long lindex);
-
- /* Handle an instruction prefix by modifying bc as necessary. */
+ /*@null@*/ yasm_insn_operandhead *operands, yasm_section *cur_section,
+ /*@null@*/ yasm_bytecode *prev_bc, unsigned long lindex);
+
+ /** Handle an instruction prefix.
+ * Modifies an instruction bytecode based on the prefix in data.
+ * \param bc bytecode (must be instruction bytecode)
+ * \param data prefix (from check_identifier())
+ * \param lindex line index (as from yasm_linemgr)
+ */
void (*parse_prefix) (yasm_bytecode *bc, const unsigned long data[4],
unsigned long lindex);
- /* Handle an segment register instruction prefix by modifying bc as
- * necessary.
+ /** Handle an segment register instruction prefix.
+ * Modifies an instruction bytecode based on a segment register prefix.
+ * \param bc bytecode (must be instruction bytecode)
+ * \param segreg segment register (from check_identifier())
+ * \param lindex line index (as from yasm_linemgr)
*/
void (*parse_seg_prefix) (yasm_bytecode *bc, unsigned long segreg,
unsigned long lindex);
- /* Handle memory expression segment overrides by modifying ea as
- * necessary.
+ /** Handle a memory expression segment override.
+ * Modifies an instruction bytecode based on a segment override in a
+ * memory expression.
+ * \param bc bytecode (must be instruction bytecode)
+ * \param segreg segment register (from check_identifier())
+ * \param lindex line index (as from yasm_linemgr)
*/
void (*parse_seg_override) (yasm_effaddr *ea, unsigned long segreg,
unsigned long lindex);
- /* Maximum used bytecode type value+1. Should be set to
- * BYTECODE_TYPE_BASE if no additional bytecode types are defined by
- * the architecture.
+ /** Maximum used bytecode type value+1. Should be set to
+ * #YASM_BYTECODE_TYPE_BASE if no additional bytecode types are defined
+ * by the architecture.
+ * \internal
*/
const int bc_type_max;
+ /** Delete a yasm_arch-defined bytecode.
+ * \internal Do not call directly, instead call yasm_bc_delete().
+ *
+ * \copydoc yasm_bc_delete()
+ */
void (*bc_delete) (yasm_bytecode *bc);
+
+ /** Print a yasm_arch-defined bytecode.
+ * \internal Do not call directly, instead call yasm_bc_print().
+ *
+ * \copydoc yasm_bc_print()
+ */
void (*bc_print) (FILE *f, int indent_level, const yasm_bytecode *bc);
- /* See bytecode.h comments on bc_resolve() */
+ /** Resolve labels in a yasm_arch-defined bytecode.
+ * \internal Do not call directly, instead call yasm_bc_resolve().
+ *
+ * \copydoc yasm_bc_resolve()
+ */
yasm_bc_resolve_flags (*bc_resolve)
(yasm_bytecode *bc, int save, const yasm_section *sect,
yasm_calc_bc_dist_func calc_bc_dist);
- /* See bytecode.h comments on bc_tobytes() */
+
+ /** Convert a yasm_arch-defined bytecode into its byte representation.
+ * \internal Do not call directly, instead call yasm_bc_tobytes().
+ *
+ * \copydoc yasm_bc_tobytes()
+ */
int (*bc_tobytes) (yasm_bytecode *bc, unsigned char **bufp,
const yasm_section *sect, void *d,
yasm_output_expr_func output_expr);
- /* Functions to output floats and integers, architecture-specific because
- * of endianness. Returns nonzero on error, otherwise updates bufp by
- * valsize (bytes saved to bufp). For intnums, rel indicates a relative
- * displacement, and bc is the containing bytecode to compute it from.
+ /** Output #yasm_floatnum to buffer.
+ * Architecture-specific because of endianness.
+ * \param flt floating point value
+ * \param bufp buffer to write into
+ * \param valsize length (in bytes)
+ * \param e expression containing value
+ * \return Nonzero on error, otherwise updates *bufp by valsize (number of
+ * bytes saved to bufp).
*/
int (*floatnum_tobytes) (const yasm_floatnum *flt, unsigned char **bufp,
unsigned long valsize, const yasm_expr *e);
+
+ /** Output #yasm_intnum to buffer.
+ * \param intn integer value
+ * \param bufp buffer to write into
+ * \param valsize length (in bytes)
+ * \param e expression containing value
+ * \param bc bytecode being output ("parent" of value)
+ * \param rel value is a relative displacement from bc
+ * \return Nonzero on error, otherwise updates *bufp by valsize (number of
+ * bytes saved to bufp).
+ */
int (*intnum_tobytes) (const yasm_intnum *intn, unsigned char **bufp,
unsigned long valsize, const yasm_expr *e,
const yasm_bytecode *bc, int rel);
- /* Gets the equivalent register size in bytes. Returns 0 if there is no
- * suitable equivalent size.
+ /** Get the equivalent byte size of a register.
+ * \param reg register
+ * \return 0 if there is no suitable equivalent size, otherwise the size.
*/
unsigned int (*get_reg_size) (unsigned long reg);
+ /** Print a register. For debugging purposes.
+ * \param f file
+ * \param indent_level indentation level
+ * \param reg register
+ */
void (*reg_print) (FILE *f, unsigned long reg);
+
+ /** Print a segment register. For debugging purposes.
+ * \param f file
+ * \param indent_level indentation level
+ * \param segreg segment register
+ */
void (*segreg_print) (FILE *f, unsigned long segreg);
- /* Convert an expression into an effective address. */
+ /** Create an effective address from an expression.
+ * \param e expression (kept, do not delete)
+ * \return Newly allocated effective address.
+ */
yasm_effaddr * (*ea_new_expr) (/*@keep@*/ yasm_expr *e);
- /* Deletes the arch-specific data in ea. May be NULL if no special
- * deletion is required (e.g. there's no dynamically allocated pointers
- * in the ea data).
+ /** Delete the yasm_arch-specific data in an effective address.
+ * May be NULL if no special deletion is required (e.g. there's no
+ * dynamically allocated pointers in the effective address data).
+ * \internal Do not call directly, instead call yasm_ea_delete().
+ *
+ * \copydoc yasm_ea_delete()
*/
void (*ea_data_delete) (yasm_effaddr *ea);
+ /** Print the yasm_arch-specific data in an effective address.
+ * \internal Do not call directly, instead call yasm_ea_print().
+ *
+ * \copydoc yasm_ea_print()
+ */
void (*ea_data_print) (FILE *f, int indent_level, const yasm_effaddr *ea);
};
#ifdef YASM_INTERNAL
+/** An instruction operand. */
struct yasm_insn_operand {
+ /** Link for building linked list of operands. \internal */
/*@reldef@*/ STAILQ_ENTRY(yasm_insn_operand) link;
+ /** Operand type. */
enum {
- 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_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. */
} type;
+ /** Operand data. */
union {
- unsigned long reg; /* arch data for reg/segreg */
- yasm_effaddr *ea; /* effective address for memory references */
- yasm_expr *val; /* value of immediate or jump target */
+ unsigned long reg; /**< Arch data for reg/segreg. */
+ yasm_effaddr *ea; /**< Effective address for memory references. */
+ yasm_expr *val; /**< Value of immediate or jump target. */
} data;
- unsigned long targetmod; /* arch target modifier, 0 if none */
+ unsigned long targetmod; /**< Arch target modifier, 0 if none. */
- /* Specified size of the operand, in bytes. 0 if not user-specified. */
+ /** Specified size of the operand, in bytes. 0 if not user-specified. */
unsigned int size;
};
#endif
+/** Common initializer for yasm_arch helper functions.
+ * \param a architecture in use
+ */
void yasm_arch_common_initialize(yasm_arch *a);
-/* insn_operand constructors. operand_new_imm() will look for cases of a
- * single register and create an INSN_OPERAND_REG variant of insn_operand.
+/** Create a yasm_insn_operand from a register.
+ * \param reg register
+ * \return Newly allocated operand.
*/
yasm_insn_operand *yasm_operand_new_reg(unsigned long reg);
+
+/** Create a yasm_insn_operand from a segment register.
+ * \param segreg segment register
+ * \return Newly allocated operand.
+ */
yasm_insn_operand *yasm_operand_new_segreg(unsigned long segreg);
+
+/** Create a yasm_insn_operand from an effective address.
+ * \param ea effective address
+ * \return Newly allocated operand.
+ */
yasm_insn_operand *yasm_operand_new_mem(/*@only@*/ yasm_effaddr *ea);
+
+/** Create a yasm_insn_operand from an immediate expression.
+ * Looks for cases of a single register and creates an INSN_OPERAND_REG variant
+ * of yasm_insn_operand.
+ * \param val immediate expression
+ * \return Newly allocated operand.
+ */
yasm_insn_operand *yasm_operand_new_imm(/*@only@*/ yasm_expr *val);
+/** Print an instruction operand. For debugging purposes.
+ * \param f file
+ * \param indent_level indentation level
+ * \param op instruction operand
+ */
void yasm_operand_print(FILE *f, int indent_level,
const yasm_insn_operand *op);
+/** Initialize a list of instruction operands.
+ * \param headp list of instruction operands
+ */
void yasm_ops_initialize(yasm_insn_operandhead *headp);
+
+/** Get the first operand in a list of instruction operands.
+ * \param headp list of instruction operands
+ * \return First operand in list (NULL if list is empty).
+ */
yasm_insn_operand *yasm_ops_first(yasm_insn_operandhead *headp);
+
+/** Get the next operand in a list of instruction operands.
+ * \param cur previous operand
+ * \return Next operand in list (NULL if cur was the last operand).
+ */
yasm_insn_operand *yasm_ops_next(yasm_insn_operand *cur);
+
#ifdef YASM_INTERNAL
#define yasm_ops_initialize(headp) STAILQ_INIT(headp)
#define yasm_ops_first(headp) STAILQ_FIRST(headp)
#define yasm_ops_next(cur) STAILQ_NEXT(cur, link)
#endif
-/* Deletes operands linked list. Deletes content of each operand if content i
- * nonzero.
+/** Delete (free allocated memory for) a list of instruction operands.
+ * \param headp list of instruction operands
+ * \param content if nonzero, deletes content of each operand
*/
void yasm_ops_delete(yasm_insn_operandhead *headp, int content);
-/* Adds op to the list of operands headp.
- * NOTE: Does not make a copy of op; so don't pass this function
- * static or local variables, and discard the op pointer after calling
- * this function. If op was actually appended (it wasn't NULL), then
- * returns op, otherwise returns NULL.
+/** Add data value to the end of a list of instruction operands.
+ * \note Does not make a copy of the operand; so don't pass this function
+ * static or local variables, and discard the op pointer after calling
+ * this function.
+ * \param headp list of instruction operands
+ * \param op operand (may be NULL)
+ * \return If operand was actually appended (it wasn't NULL), the operand;
+ * otherwise NULL.
*/
/*@null@*/ yasm_insn_operand *yasm_ops_append
(yasm_insn_operandhead *headp,
/*@returned@*/ /*@null@*/ yasm_insn_operand *op);
+/** Print a list of instruction operands. For debugging purposes.
+ * \param f file
+ * \param indent_level indentation level
+ * \param headp list of instruction operands
+ */
void yasm_ops_print(FILE *f, int indent_level,
const yasm_insn_operandhead *headp);
-/* $IdPath$
- * YASM bytecode utility functions header file
+/**
+ * \file bytecode.h
+ * \brief YASM bytecode interface.
+ *
+ * $IdPath$
*
* Copyright (C) 2001 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
+ * - 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
+ * - 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.
*
#ifndef YASM_BYTECODE_H
#define YASM_BYTECODE_H
+/** An effective address (opaque type). */
typedef struct yasm_effaddr yasm_effaddr;
+/** An immediate value (opaque type). */
typedef struct yasm_immval yasm_immval;
+/** A data value (opaque type). */
typedef struct yasm_dataval yasm_dataval;
+/** A list of data values (opaque type). */
typedef struct yasm_datavalhead yasm_datavalhead;
#ifdef YASM_INTERNAL
/*@reldef@*/ STAILQ_HEAD(yasm_bytecodehead, yasm_bytecode);
/*@reldef@*/ STAILQ_HEAD(yasm_datavalhead, yasm_dataval);
-/* Additional types may be architecture-defined starting at
- * YASM_BYTECODE_TYPE_BASE.
+/** \internal Built-in bytecode types.
+ * Additional types may be #yasm_arch defined starting at
+ * #YASM_BYTECODE_TYPE_BASE.
*/
typedef enum {
- YASM_BC__EMPTY = 0,
- YASM_BC__DATA,
- YASM_BC__RESERVE,
- YASM_BC__INCBIN,
- YASM_BC__ALIGN,
- YASM_BC__OBJFMT_DATA
+ YASM_BC__EMPTY = 0, /**< Empty; should not exist except temporarily. */
+ YASM_BC__DATA, /**< One or more data value(s). */
+ YASM_BC__RESERVE, /**< Reserved space. */
+ YASM_BC__INCBIN, /**< Included binary file. */
+ YASM_BC__ALIGN, /**< Alignment to a boundary. */
+ YASM_BC__OBJFMT_DATA /**< yasm_objfmt specific data. */
} yasm_bytecode_type;
+
+/** Starting yasm_bytecode_type numeric value available for yasm_arch use. */
#define YASM_BYTECODE_TYPE_BASE YASM_BC__OBJFMT_DATA+1
#endif
+/** Initialize bytecode utility functions.
+ * \param a architecture used during bytecode operations.
+ */
void yasm_bc_initialize(yasm_arch *a);
+/** Create an immediate value from an unsigned integer.
+ * \param int_val unsigned integer
+ * \param lindex line index (as from yasm_linemgr) for error/warning
+ * purposes.
+ * \return Newly allocated immediate value.
+ */
/*@only@*/ yasm_immval *yasm_imm_new_int(unsigned long int_val,
unsigned long lindex);
+
+/** Create an immediate value from an expression.
+ * \param e expression (kept, do not free).
+ * \return Newly allocated immediate value.
+ */
/*@only@*/ yasm_immval *yasm_imm_new_expr(/*@keep@*/ yasm_expr *e);
+/** Get the displacement portion of an effective address.
+ * \param ea effective address
+ * \return Expression representing the displacement (read-only).
+ */
/*@observer@*/ const yasm_expr *yasm_ea_get_disp(const yasm_effaddr *ea);
+
+/** Set the length of the displacement portion of an effective address.
+ * The length is specified in bytes.
+ * \param ea effective address
+ * \param len length in bytes
+ */
void yasm_ea_set_len(yasm_effaddr *ea, unsigned int len);
+
+/** Set/clear nosplit flag of an effective address.
+ * The nosplit 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.
+ * \param ea effective address
+ * \param nosplit nosplit flag setting (0=splits allowed, nonzero=splits
+ * not allowed)
+ */
void yasm_ea_set_nosplit(yasm_effaddr *ea, unsigned int nosplit);
+
+/** Delete (free allocated memory for) an effective address.
+ * \param ea effective address (only pointer to it).
+ */
void yasm_ea_delete(/*@only@*/ yasm_effaddr *ea);
+
+/** Print an effective address. For debugging purposes.
+ * \param f file
+ * \param indent_level indentation level
+ * \param ea effective address
+ */
void yasm_ea_print(FILE *f, int indent_level, const yasm_effaddr *ea);
+/** 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)
+ */
void yasm_bc_set_multiple(yasm_bytecode *bc, /*@keep@*/ yasm_expr *e);
#ifdef YASM_INTERNAL
+/** Create a bytecode of any specified type.
+ * \param type bytecode type
+ * \param datasize size of type-specific data (in bytes)
+ * \param lindex line index (as from yasm_linemgr) for the bytecode
+ * \return Newly allocated bytecode of the specified type.
+ */
/*@only@*/ yasm_bytecode *yasm_bc_new_common(yasm_bytecode_type type,
size_t datasize,
unsigned long lindex);
#endif
+/** Create a bytecode containing data value(s).
+ * \param datahead list of data values (kept, do not free)
+ * \param size storage size (in bytes) for each data value
+ * \param lindex line index (as from yasm_linemgr) for the bytecode
+ * \return Newly allocated bytecode.
+ */
/*@only@*/ yasm_bytecode *yasm_bc_new_data(yasm_datavalhead *datahead,
unsigned int size,
unsigned long lindex);
+
+/** Create a bytecode reserving space.
+ * \param numitems number of reserve "items" (kept, do not free)
+ * \param itemsize reserved size (in bytes) for each item
+ * \param lindex line index (as from yasm_linemgr) for the bytecode
+ * \return Newly allocated bytecode.
+ */
/*@only@*/ yasm_bytecode *yasm_bc_new_reserve(/*@only@*/ yasm_expr *numitems,
unsigned int itemsize,
unsigned long lindex);
+
+/** Create a bytecode that includes a binary file verbatim.
+ * \param filename full 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 lindex line index (as from yasm_linemgr) for the bytecode
+ * \return Newly allocated bytecode.
+ */
/*@only@*/ yasm_bytecode *yasm_bc_new_incbin
(/*@only@*/ char *filename, /*@only@*/ /*@null@*/ yasm_expr *start,
/*@only@*/ /*@null@*/ yasm_expr *maxlen, unsigned long lindex);
+
+/** Create a bytecode that aligns the following bytecode to a boundary.
+ * \param boundary byte alignment (must be a power of two)
+ * \param lindex line index (as from yasm_linemgr) for the bytecode
+ * \return Newly allocated bytecode.
+ */
/*@only@*/ yasm_bytecode *yasm_bc_new_align(unsigned long boundary,
unsigned long lindex);
+
+/** Create a bytecode that includes yasm_objfmt-specific data.
+ * \param type yasm_objfmt-specific type
+ * \param len length (in bytes) of data
+ * \param of yasm_objfmt storing the data
+ * \param data data (kept, do not free)
+ * \param lindex line index (as from yasm_linemgr) for the bytecode
+ * \return Newly allocated bytecode.
+ */
/*@only@*/ yasm_bytecode *yasm_bc_new_objfmt_data
(unsigned int type, unsigned long len, yasm_objfmt *of,
/*@only@*/ void *data, unsigned long lindex);
+/** Delete (free allocated memory for) a bytecode.
+ * \param bc bytecode (only pointer to it); may be NULL
+ */
void yasm_bc_delete(/*@only@*/ /*@null@*/ yasm_bytecode *bc);
+/** Print a bytecode. For debugging purposes.
+ * \param f file
+ * \param indent_level indentation level
+ * \param bc bytecode
+ */
void yasm_bc_print(FILE *f, int indent_level, const yasm_bytecode *bc);
-/* A common version of a calc_bc_dist function that should work for the final
- * stages of optimizers as well as in objfmt expr output functions. It takes
- * the offsets from the bytecodes.
+/** Common version of calc_bc_dist that takes offsets from bytecodes.
+ * Should be used for the final stages of optimizers as well as in yasm_objfmt
+ * yasm_expr output functions.
+ * \see yasm_calc_bc_dist_func for parameter descriptions.
*/
/*@null@*/ yasm_intnum *yasm_common_calc_bc_dist
(yasm_section *sect, /*@null@*/ yasm_bytecode *precbc1,
/*@null@*/ yasm_bytecode *precbc2);
-/* Return value flags for bc_resolve() */
+/** Return value flags for yasm_bc_resolve(). */
typedef enum {
- YASM_BC_RESOLVE_NONE = 0, /* Ok, but length is not minimum */
- YASM_BC_RESOLVE_ERROR = 1<<0, /* Error found, output */
- YASM_BC_RESOLVE_MIN_LEN = 1<<1, /* Length is minimum possible */
- YASM_BC_RESOLVE_UNKNOWN_LEN = 1<<2 /* Length indeterminate */
+ YASM_BC_RESOLVE_NONE = 0, /**< Ok, but length is not minimum. */
+ YASM_BC_RESOLVE_ERROR = 1<<0, /**< Error found, output. */
+ YASM_BC_RESOLVE_MIN_LEN = 1<<1, /**< Length is minimum possible. */
+ YASM_BC_RESOLVE_UNKNOWN_LEN = 1<<2 /**< Length indeterminate. */
} yasm_bc_resolve_flags;
-/* Resolves labels in bytecode, and calculates its length.
+/** Resolve labels in a bytecode, and calculate its length.
* Tries to minimize the length as much as possible.
- * Returns whether the length is the minimum possible, indeterminate, and
- * if there was an error recognized and output during execution (see above
- * for return flags).
- * Note: sometimes it's impossible to determine if a length is the minimum
+ * \note Sometimes it's impossible to determine if a length is the minimum
* possible. In this case, this function returns that the length is NOT
* the minimum.
- * resolve_label is the function used to determine the value (offset) of a
- * in-file label (eg, not an EXTERN variable, which is indeterminate).
- * When save is zero, this function does *not* modify bc other than the
- * length/size values (i.e. it doesn't keep the values returned by
- * resolve_label except temporarily to try to minimize the length).
- * When save is nonzero, all fields in bc may be modified by this function.
+ * \param bc bytecode
+ * \param save when zero, this function does <em>not</em> modify bc
+ * other than the length/size values (i.e. it doesn't keep
+ * the values returned by calc_bc_dist except temporarily
+ * to try to minimize the length); when nonzero, all
+ * fields in bc may be modified by this function
+ * \param sect section containing the bytecode
+ * \param calc_bc_dist function used to determine bytecode distance
+ * \return Flags indicating whether the length is the minimum possible,
+ * indeterminate, and if there was an error recognized (and output)
+ * during execution.
*/
yasm_bc_resolve_flags yasm_bc_resolve(yasm_bytecode *bc, int save,
const yasm_section *sect,
yasm_calc_bc_dist_func calc_bc_dist);
-/* Converts the bytecode bc into its byte representation.
- * Inputs:
- * bc - the bytecode to convert
- * buf - where to put the byte representation
- * bufsize - the size of buf
- * d - the data to pass to each call to output_expr()
- * output_expr - the function to call to convert expressions to byte rep
- * output_bc_objfmt_data - the function to call to convert objfmt data
- * bytecodes into their byte representation
- * Outputs:
- * bufsize - the size of the generated data.
- * multiple - the number of times the data should be dup'ed when output
- * gap - indicates the data does not really need to exist in the
- * object file. buf's contents are undefined if true.
- * Returns either NULL (if buf was big enough to hold the entire byte
- * representation), or a newly allocated buffer that should be used instead
- * of buf for reading the byte representation.
+/** 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 multiple number of times the data should be duplicated when
+ * written to the object file [output]
+ * \param gap if nonzero, indicates the data does not really need to
+ * exist in the object file; if nonzero, contents of buf
+ * are undefined [output]
+ * \param sect section containing the bytecode
+ * \param d data to pass to each call to output_expr
+ * \param output_expr function to call to convert expressions into their byte
+ * representation
+ * \param output_bc_objfmt_data function to call to convert yasm_objfmt data
+ * bytecodes into their byte representation
+ * \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.
*/
/*@null@*/ /*@only@*/ unsigned char *yasm_bc_tobytes
(yasm_bytecode *bc, unsigned char *buf, unsigned long *bufsize,
/*@null@*/ yasm_output_bc_objfmt_data_func output_bc_objfmt_data)
/*@sets *buf@*/;
+/** Initialize list of bytecodes.
+ * \param headp bytecode list
+ */
void yasm_bcs_initialize(yasm_bytecodehead *headp);
#ifdef YASM_INTERNAL
#define yasm_bcs_initialize(headp) STAILQ_INIT(headp)
#endif
-yasm_bytecode *yasm_bcs_first(yasm_bytecodehead *headp);
+/** Get the first bytecode in a list of bytecodes.
+ * \param headp bytecode list
+ * \return First bytecode in list (NULL if list is empty).
+ */
+/*@null@*/ yasm_bytecode *yasm_bcs_first(yasm_bytecodehead *headp);
#ifdef YASM_INTERNAL
#define yasm_bcs_first(headp) STAILQ_FIRST(headp)
#endif
+/** Get the last bytecode in a list of bytecodes.
+ * \param headp bytecode list
+ * \return Last bytecode in list (NULL if list is empty).
+ */
/*@null@*/ yasm_bytecode *yasm_bcs_last(yasm_bytecodehead *headp);
+
+/** Delete (free allocated memory for) a list of bytecodes.
+ * \param headp bytecode list
+ */
void yasm_bcs_delete(yasm_bytecodehead *headp);
-/* Adds bc to the list of bytecodes headp.
- * 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. If bc was actually appended (it wasn't NULL or empty),
- * then returns bc, otherwise returns NULL.
+/** Add bytecode to the end of a list of bytecodes.
+ * \note Does not make a copy of bc; so don't pass this function static or
+ * local variables, and discard the bc pointer after calling this
+ * function.
+ * \param headp bytecode list
+ * \param bc bytecode (may be NULL)
+ * \return If bytecode was actually appended (it wasn't NULL or empty), the
+ * bytecode; otherwise NULL.
*/
/*@only@*/ /*@null@*/ yasm_bytecode *yasm_bcs_append
(yasm_bytecodehead *headp,
/*@returned@*/ /*@only@*/ /*@null@*/ yasm_bytecode *bc);
+/** Print a bytecode list. For debugging purposes.
+ * \param f file
+ * \param indent_level indentation level
+ * \param headp bytecode list
+ */
void yasm_bcs_print(FILE *f, int indent_level, const yasm_bytecodehead *headp);
-/* Calls func for each bytecode in the linked list of bytecodes pointed to by
- * headp. The data pointer d is passed to each func call.
- *
- * Stops early (and returns func's return value) if func returns a nonzero
- * value. Otherwise returns 0.
+/** Traverses a bytecode list, calling a function on each bytecode.
+ * \param headp bytecode list
+ * \param d data pointer passed to func on each call
+ * \param func function
+ * \return Stops early (and returns func's return value) if func returns a
+ * nonzero value; otherwise 0.
*/
int yasm_bcs_traverse(yasm_bytecodehead *headp, /*@null@*/ void *d,
int (*func) (yasm_bytecode *bc, /*@null@*/ void *d));
+/** Create a new data value from an expression.
+ * \param expn expression
+ * \return Newly allocated data value.
+ */
yasm_dataval *yasm_dv_new_expr(/*@keep@*/ yasm_expr *expn);
+
+/** Create a new data value from a float.
+ * \param flt floating point value
+ * \return Newly allocated data value.
+ */
yasm_dataval *yasm_dv_new_float(/*@keep@*/ yasm_floatnum *flt);
+
+/** Create a new data value from a string.
+ * \param str_val string
+ * \return Newly allocated data value.
+ */
yasm_dataval *yasm_dv_new_string(/*@keep@*/ char *str_val);
+/** Initialize a list of data values.
+ * \param headp list of data values
+ */
void yasm_dvs_initialize(yasm_datavalhead *headp);
#ifdef YASM_INTERNAL
#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
+ */
void yasm_dvs_delete(yasm_datavalhead *headp);
-/* Adds dv to the list of datavals headp.
- * NOTE: Does not make a copy of dv; so don't pass this function
- * static or local variables, and discard the dv pointer after calling
- * this function. If dv was actually appended (it wasn't NULL), then
- * returns dv, otherwise returns NULL.
+/** 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.
*/
/*@null@*/ yasm_dataval *yasm_dvs_append
(yasm_datavalhead *headp, /*@returned@*/ /*@null@*/ yasm_dataval *dv);
-void yasm_dvs_print(FILE *f, int indent_level, const yasm_datavalhead *head);
+/** Print a data value list. For debugging purposes.
+ * \param f file
+ * \param indent_level indentation level
+ * \param headp data value list
+ */
+void yasm_dvs_print(FILE *f, int indent_level, const yasm_datavalhead *headp);
#endif
-/* $IdPath$
- * YASM core (used by many modules/header files) type definitions.
+/**
+ * \file coretype.h
+ * \brief YASM core type definitions.
+ *
+ * $IdPath$
*
* Copyright (C) 2001 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
+ * - 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
+ * - 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.
*
#ifndef YASM_CORETYPE_H
#define YASM_CORETYPE_H
+/** Architecture interface. \see arch.h for details. */
typedef struct yasm_arch yasm_arch;
-
+/** Preprocessor interface. \see preproc.h for details. */
typedef struct yasm_preproc yasm_preproc;
+/** Parser interface. \see parser.h for details. */
typedef struct yasm_parser yasm_parser;
+/** Optimizer interface. \see optimizer.h for details. */
typedef struct yasm_optimizer yasm_optimizer;
+/** 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;
+/** Bytecode (opaque type).
+ * \see bytecode.h for related functions.
+ * Define YASM_BC_INTERNAL to get visible internals.
+ */
typedef struct yasm_bytecode yasm_bytecode;
+/** List of bytecodes (opaque type). \see bytecode.h for related functions. */
typedef struct yasm_bytecodehead yasm_bytecodehead;
+/** Section (opaque type). \see section.h for related functions. */
typedef struct yasm_section yasm_section;
+/** List of sections (opaque type). \see section.h for related functions. */
typedef struct yasm_sectionhead yasm_sectionhead;
+/** Symbol record (opaque type). \see symrec.h for related functions. */
typedef struct yasm_symrec yasm_symrec;
+/** Expression (opaque type).
+ * \see expr.h for related functions.
+ * Define YASM_EXPR_INTERNAL to get visible internals.
+ */
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;
+/** Line number management interface. \see linemgr.h for more details. */
typedef struct yasm_linemgr yasm_linemgr;
+/** 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;
+/** Expression operators usable in #yasm_expr expressions. */
typedef enum {
- YASM_EXPR_ADD,
- YASM_EXPR_SUB,
- YASM_EXPR_MUL,
- YASM_EXPR_DIV,
- YASM_EXPR_SIGNDIV,
- YASM_EXPR_MOD,
- YASM_EXPR_SIGNMOD,
- YASM_EXPR_NEG,
- YASM_EXPR_NOT,
- YASM_EXPR_OR,
- YASM_EXPR_AND,
- YASM_EXPR_XOR,
- YASM_EXPR_SHL,
- YASM_EXPR_SHR,
- YASM_EXPR_LOR,
- YASM_EXPR_LAND,
- YASM_EXPR_LNOT,
- YASM_EXPR_LT,
- YASM_EXPR_GT,
- YASM_EXPR_EQ,
- YASM_EXPR_LE,
- YASM_EXPR_GE,
- YASM_EXPR_NE,
- YASM_EXPR_SEG,
- YASM_EXPR_WRT,
- YASM_EXPR_SEGOFF, /* The ':' in SEG:OFF */
- 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_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_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_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_IDENT /**< No operation, just a value. */
} yasm_expr_op;
-/* EXTERN and COMMON are mutually exclusive */
+/** Symbol record visibility.
+ * \see symrec.h for related functions.
+ * \note YASM_SYM_EXTERN and YASM_SYM_COMMON are mutually exclusive.
+ */
typedef enum {
- YASM_SYM_LOCAL = 0, /* default, local only */
- YASM_SYM_GLOBAL = 1 << 0, /* if it's declared GLOBAL */
- YASM_SYM_COMMON = 1 << 1, /* if it's declared COMMON */
- YASM_SYM_EXTERN = 1 << 2 /* if it's declared EXTERN */
+ 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_vis;
-/* Determines the distance, in bytes, between the starting offsets of two
- * bytecodes in a section.
- * Inputs: sect, the section in which the bytecodes reside.
- * precbc1, preceding bytecode to the first bytecode
- * precbc2, preceding bytecode to the second bytecode
- * Outputs: dist, the distance in bytes (bc2-bc1)
- * Returns distance in bytes (bc2-bc1), or NULL if the distance was
- * indeterminate.
+/** Determine the distance between the starting offsets of two bytecodes in a
+ * section.
+ * \param sect section containing the two bytecodes
+ * \param precbc1 preceding bytecode to the first bytecode (NULL
+ * indicates first bytecode in section)
+ * \param precbc2 preceding bytecode to the second bytecode (NULL
+ * indicates first bytecode in section)
+ * \return Distance in bytes between the two bytecodes (bc2-bc1), or NULL if
+ * the distance was indeterminate.
*/
typedef /*@null@*/ yasm_intnum * (*yasm_calc_bc_dist_func)
(yasm_section *sect, /*@null@*/ yasm_bytecode *precbc1,
/*@null@*/ yasm_bytecode *precbc2);
-/* Converts an expr to its byte representation. Usually implemented by
+/** Convert yasm_expr to its byte representation. Usually implemented by
* object formats to keep track of relocations and verify legal expressions.
- * Inputs:
- * ep - (double) pointer to the expression to output
- * bufp - (double) pointer to buffer to contain byte representation
- * valsize - the size (in bytes) to be used for the byte rep
- * offset - the offset (in bytes) of the expr contents from the bc start
- * sect - current section (usually passed into higher-level calling fct)
- * bc - current bytecode (usually passed into higher-level calling fct)
- * rel - should the expr be treated as PC/IP-relative? (nonzero=yes)
- * d - objfmt-specific data (passed into higher-level calling fct)
- * Returns nonzero if an error occurred, 0 otherwise
+ * \param ep (double) pointer to expression
+ * \param bufp (double) pointer to buffer for byte representation
+ * \param valsize size (in bytes) of the byte representation
+ * \param offset offset (in bytes) of the expr contents from the start
+ * of the bytecode (sometimes needed for conditional jumps)
+ * \param sect current section (usually passed into higher-level
+ * calling function)
+ * \param bc current bytecode (usually passed into higher-level
+ * calling function)
+ * \param rel if nonzero, expr should be treated as PC/IP-relative
+ * \param d objfmt-specific data (passed into higher-level calling
+ * function)
+ * \return Nonzero if an error occurred, 0 otherwise.
*/
typedef int (*yasm_output_expr_func)
(yasm_expr **ep, unsigned char **bufp, unsigned long valsize,
yasm_bytecode *bc, int rel, /*@null@*/ void *d)
/*@uses *ep@*/ /*@sets **bufp@*/;
-/* Converts a objfmt data bytecode into its byte representation. Usually
- * implemented by object formats to output their own generated data.
- * Inputs:
- * type - objfmt-specific type
- * data - objfmt-specific data
- * bufp - (double) pointer to buffer to contain byte representation
- * bufp is guaranteed to have enough space to store the data into (as given
- * by the original bc_new_objfmt_data() call).
- * Returns nonzero if an error occurred, 0 otherwise.
+/** Convert a yasm_objfmt-specific data bytecode into its byte representation.
+ * Usually implemented by object formats to output their own generated data.
+ * \param type yasm_objfmt-specific type
+ * \param data data
+ * \param bufp (double) pointer to buffer for byte representation
+ * \note bufp is guaranteed to have enough space to store the data into (as
+ * given by the original yasm_bc_new_objfmt_data() call).
+ * \return Nonzero if an error occurred, 0 otherwise.
*/
typedef int (*yasm_output_bc_objfmt_data_func)
(unsigned int type, /*@observer@*/ void *data, unsigned char **bufp)