aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/tools/yasm/libyasm/bytecode.h
diff options
context:
space:
mode:
authorsomov <somov@yandex-team.ru>2022-02-10 16:45:49 +0300
committerDaniil Cherednik <dcherednik@yandex-team.ru>2022-02-10 16:45:49 +0300
commit7489e4682331202b9c7d863c0898eb83d7b12c2b (patch)
tree9142afc54d335ea52910662635b898e79e192e49 /contrib/tools/yasm/libyasm/bytecode.h
parenta5950576e397b1909261050b8c7da16db58f10b1 (diff)
downloadydb-7489e4682331202b9c7d863c0898eb83d7b12c2b.tar.gz
Restoring authorship annotation for <somov@yandex-team.ru>. Commit 2 of 2.
Diffstat (limited to 'contrib/tools/yasm/libyasm/bytecode.h')
-rw-r--r--contrib/tools/yasm/libyasm/bytecode.h1276
1 files changed, 638 insertions, 638 deletions
diff --git a/contrib/tools/yasm/libyasm/bytecode.h b/contrib/tools/yasm/libyasm/bytecode.h
index fc75e57d0e1..47cd26244b0 100644
--- a/contrib/tools/yasm/libyasm/bytecode.h
+++ b/contrib/tools/yasm/libyasm/bytecode.h
@@ -1,638 +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
+/**
+ * \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