2 * \file libyasm/bytecode.h
3 * \brief YASM bytecode interface.
6 * Copyright (C) 2001-2007 Peter Johnson
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
11 * - Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * - Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND OTHER CONTRIBUTORS ``AS IS''
18 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR OTHER CONTRIBUTORS BE
21 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 * POSSIBILITY OF SUCH DAMAGE.
30 #ifndef YASM_BYTECODE_H
31 #define YASM_BYTECODE_H
37 /** A data value (opaque type). */
38 typedef struct yasm_dataval yasm_dataval;
39 /** A list of data values. */
40 typedef struct yasm_datavalhead yasm_datavalhead;
42 /** Linked list of data values. */
43 /*@reldef@*/ STAILQ_HEAD(yasm_datavalhead, yasm_dataval);
45 /** Add a dependent span for a bytecode.
46 * \param add_span_data add_span_data passed into bc_calc_len()
47 * \param bc bytecode containing span
48 * \param id non-zero identifier for span; may be any non-zero value
49 * if <0, expand is called for any change;
50 * if >0, expand is only called when exceeds threshold
51 * \param value dependent value for bytecode expansion
52 * \param neg_thres negative threshold for long/short decision
53 * \param pos_thres positive threshold for long/short decision
55 typedef void (*yasm_bc_add_span_func)
56 (void *add_span_data, yasm_bytecode *bc, int id, const yasm_value *value,
57 long neg_thres, long pos_thres);
59 /** Bytecode callback structure. Any implementation of a specific bytecode
60 * must implement these functions and this callback structure. The bytecode
61 * implementation-specific data is stored in #yasm_bytecode.contents.
63 typedef struct yasm_bytecode_callback {
64 /** Destroys the implementation-specific data.
65 * Called from yasm_bc_destroy().
66 * \param contents #yasm_bytecode.contents
68 void (*destroy) (/*@only@*/ void *contents);
70 /** Prints the implementation-specific data (for debugging purposes).
71 * Called from yasm_bc_print().
72 * \param contents #yasm_bytecode.contents
74 * \param indent_level indentation level
76 void (*print) (const void *contents, FILE *f, int indent_level);
78 /** Finalizes the bytecode after parsing. Called from yasm_bc_finalize().
79 * A generic fill-in for this is yasm_bc_finalize_common().
81 * \param prev_bc bytecode directly preceding bc
83 void (*finalize) (yasm_bytecode *bc, yasm_bytecode *prev_bc);
85 /** Return elements size of a data bytecode.
86 * This function should return the size of each elements of a data
87 * bytecode, for proper dereference of symbols attached to it.
89 * \return 0 if element size is unknown.
91 int (*elem_size) (yasm_bytecode *bc);
93 /** Calculates the minimum size of a bytecode.
94 * Called from yasm_bc_calc_len().
95 * A generic fill-in for this is yasm_bc_calc_len_common(), but as this
96 * function internal errors when called, be very careful when using it!
97 * This function should simply add to bc->len and not set it directly
98 * (it's initialized by yasm_bc_calc_len() prior to passing control to
102 * \param add_span function to call to add a span
103 * \param add_span_data extra data to be passed to add_span function
104 * \return 0 if no error occurred, nonzero if there was an error
105 * recognized (and output) during execution.
106 * \note May store to bytecode updated expressions.
108 int (*calc_len) (yasm_bytecode *bc, yasm_bc_add_span_func add_span,
109 void *add_span_data);
111 /** Recalculates the bytecode's length based on an expanded span length.
112 * Called from yasm_bc_expand().
113 * A generic fill-in for this is yasm_bc_expand_common(), but as this
114 * function internal errors when called, if used, ensure that calc_len()
116 * This function should simply add to bc->len to increase the length by
119 * \param span span ID (as given to add_span in calc_len)
120 * \param old_val previous span value
121 * \param new_val new span value
122 * \param neg_thres negative threshold for long/short decision
124 * \param pos_thres positive threshold for long/short decision
126 * \return 0 if bc no longer dependent on this span's length, negative if
127 * there was an error recognized (and output) during execution,
128 * and positive if bc size may increase for this span further
129 * based on the new negative and positive thresholds returned.
130 * \note May store to bytecode updated expressions.
132 int (*expand) (yasm_bytecode *bc, int span, long old_val, long new_val,
133 /*@out@*/ long *neg_thres, /*@out@*/ long *pos_thres);
135 /** Convert a bytecode into its byte representation.
136 * Called from yasm_bc_tobytes().
137 * A generic fill-in for this is yasm_bc_tobytes_common(), but as this
138 * function internal errors when called, be very careful when using it!
140 * \param bufp byte representation destination buffer;
141 * should be incremented as it's written to,
142 * so that on return its delta from the
143 * passed-in buf matches the bytecode length
144 * (it's okay not to do this if an error
145 * indication is returned)
146 * \param bufstart For calculating the correct offset parameter for
147 * the \a output_value calls: *bufp - bufstart.
148 * \param d data to pass to each call to
149 * output_value/output_reloc
150 * \param output_value function to call to convert values into their byte
152 * \param output_reloc function to call to output relocation entries
154 * \return Nonzero on error, 0 on success.
155 * \note May result in non-reversible changes to the bytecode, but it's
156 * preferable if calling this function twice would result in the
159 int (*tobytes) (yasm_bytecode *bc, unsigned char **bufp,
160 unsigned char *bufstart, void *d,
161 yasm_output_value_func output_value,
162 /*@null@*/ yasm_output_reloc_func output_reloc);
164 /** Special bytecode classifications. Most bytecode types should use
165 * #YASM_BC_SPECIAL_NONE. Others cause special handling to kick in
166 * in various parts of yasm.
168 enum yasm_bytecode_special_type {
169 YASM_BC_SPECIAL_NONE = 0,
171 /** Bytecode reserves space instead of outputting data. */
172 YASM_BC_SPECIAL_RESERVE,
174 /** Adjusts offset instead of calculating len. */
175 YASM_BC_SPECIAL_OFFSET,
177 /** Instruction bytecode. */
180 } yasm_bytecode_callback;
183 struct yasm_bytecode {
184 /** Bytecodes are stored as a singly linked list, with tail insertion.
185 * \see section.h (#yasm_section).
187 /*@reldef@*/ STAILQ_ENTRY(yasm_bytecode) link;
189 /** The bytecode callback structure for this bytecode. May be NULL
190 * during partial initialization.
192 /*@null@*/ const yasm_bytecode_callback *callback;
194 /** Pointer to section containing bytecode; NULL if not part of a
197 /*@dependent@*/ /*@null@*/ yasm_section *section;
199 /** Number of times bytecode is repeated.
200 * NULL=1 (to save space in the common case).
202 /*@only@*/ /*@null@*/ yasm_expr *multiple;
204 /** Total length of entire bytecode (not including multiple copies). */
207 /** Number of copies, integer version. */
210 /** Line number where bytecode was defined. */
213 /** Offset of bytecode from beginning of its section.
214 * 0-based, ~0UL (e.g. all 1 bits) if unknown.
216 unsigned long offset;
218 /** Unique integer index of bytecode. Used during optimization. */
219 unsigned long bc_index;
221 /** NULL-terminated array of labels that point to this bytecode (as the
222 * bytecode previous to the label). NULL if no labels point here.
224 /*@null@*/ yasm_symrec **symrecs;
226 /** Implementation-specific data (type identified by callback). */
230 /** Create a bytecode of any specified type.
231 * \param callback bytecode callback functions, if NULL, creates empty
232 * bytecode (may not be resolved or output)
233 * \param contents type-specific data
234 * \param line virtual line (from yasm_linemap)
235 * \return Newly allocated bytecode of the specified type.
238 /*@only@*/ yasm_bytecode *yasm_bc_create_common
239 (/*@null@*/ const yasm_bytecode_callback *callback,
240 /*@only@*/ /*@null@*/ void *contents, unsigned long line);
242 /** Transform a bytecode of any type into a different type.
243 * \param bc bytecode to transform
244 * \param callback new bytecode callback function
245 * \param contents new type-specific data
248 void yasm_bc_transform(yasm_bytecode *bc,
249 const yasm_bytecode_callback *callback,
252 /** Common bytecode callback finalize function, for where no finalization
253 * is ever required for this type of bytecode.
256 void yasm_bc_finalize_common(yasm_bytecode *bc, yasm_bytecode *prev_bc);
258 /** Common bytecode callback calc_len function, for where the bytecode has
259 * no calculatable length. Causes an internal error if called.
262 int yasm_bc_calc_len_common(yasm_bytecode *bc, yasm_bc_add_span_func add_span,
263 void *add_span_data);
265 /** Common bytecode callback expand function, for where the bytecode is
266 * always short (calc_len never calls add_span). Causes an internal
270 int yasm_bc_expand_common
271 (yasm_bytecode *bc, int span, long old_val, long new_val,
272 /*@out@*/ long *neg_thres, /*@out@*/ long *pos_thres);
274 /** Common bytecode callback tobytes function, for where the bytecode
275 * cannot be converted to bytes. Causes an internal error if called.
278 int yasm_bc_tobytes_common
279 (yasm_bytecode *bc, unsigned char **bufp, unsigned char *bufstart, void *d,
280 yasm_output_value_func output_value,
281 /*@null@*/ yasm_output_reloc_func output_reloc);
283 /** Get the next bytecode in a linked list of bytecodes.
285 * \return Next bytecode.
287 #define yasm_bc__next(bc) STAILQ_NEXT(bc, link)
289 /** Set multiple field of a bytecode.
290 * A bytecode can be repeated a number of times when output. This function
291 * sets that multiple.
293 * \param e multiple (kept, do not free)
296 void yasm_bc_set_multiple(yasm_bytecode *bc, /*@keep@*/ yasm_expr *e);
298 /** Create a bytecode containing data value(s).
299 * \param datahead list of data values (kept, do not free)
300 * \param size storage size (in bytes) for each data value
301 * \param append_zero append a single zero byte after each data value
303 * \param arch architecture (optional); if provided, data items
304 * are directly simplified to bytes if possible
305 * \param line virtual line (from yasm_linemap)
306 * \return Newly allocated bytecode.
309 /*@only@*/ yasm_bytecode *yasm_bc_create_data
310 (yasm_datavalhead *datahead, unsigned int size, int append_zero,
311 /*@null@*/ yasm_arch *arch, unsigned long line);
313 /** Create a bytecode containing LEB128-encoded data value(s).
314 * \param datahead list of data values (kept, do not free)
315 * \param sign signedness (1=signed, 0=unsigned) of each data value
316 * \param line virtual line (from yasm_linemap)
317 * \return Newly allocated bytecode.
320 /*@only@*/ yasm_bytecode *yasm_bc_create_leb128
321 (yasm_datavalhead *datahead, int sign, unsigned long line);
323 /** Create a bytecode reserving space.
324 * \param numitems number of reserve "items" (kept, do not free)
325 * \param itemsize reserved size (in bytes) for each item
326 * \param line virtual line (from yasm_linemap)
327 * \return Newly allocated bytecode.
330 /*@only@*/ yasm_bytecode *yasm_bc_create_reserve
331 (/*@only@*/ yasm_expr *numitems, unsigned int itemsize,
334 /** Get the number of items and itemsize for a reserve bytecode. If bc
335 * is not a reserve bytecode, returns NULL.
337 * \param itemsize reserved size (in bytes) for each item (returned)
338 * \return NULL if bc is not a reserve bytecode, otherwise an expression
339 * for the number of items to reserve.
342 /*@null@*/ const yasm_expr *yasm_bc_reserve_numitems
343 (yasm_bytecode *bc, /*@out@*/ unsigned int *itemsize);
345 /** Create a bytecode that includes a binary file verbatim.
346 * \param filename path to binary file (kept, do not free)
347 * \param start starting location in file (in bytes) to read data from
348 * (kept, do not free); may be NULL to indicate 0
349 * \param maxlen maximum number of bytes to read from the file (kept, do
350 * do not free); may be NULL to indicate no maximum
351 * \param linemap line mapping repository
352 * \param line virtual line (from yasm_linemap) for the bytecode
353 * \return Newly allocated bytecode.
356 /*@only@*/ yasm_bytecode *yasm_bc_create_incbin
357 (/*@only@*/ char *filename, /*@only@*/ /*@null@*/ yasm_expr *start,
358 /*@only@*/ /*@null@*/ yasm_expr *maxlen, yasm_linemap *linemap,
361 /** Create a bytecode that aligns the following bytecode to a boundary.
362 * \param boundary byte alignment (must be a power of two)
363 * \param fill fill data (if NULL, code_fill or 0 is used)
364 * \param maxskip maximum number of bytes to skip
365 * \param code_fill code fill data (if NULL, 0 is used)
366 * \param line virtual line (from yasm_linemap)
367 * \return Newly allocated bytecode.
368 * \note The precedence on generated fill is as follows:
369 * - from fill parameter (if not NULL)
370 * - from code_fill parameter (if not NULL)
374 /*@only@*/ yasm_bytecode *yasm_bc_create_align
375 (/*@keep@*/ yasm_expr *boundary, /*@keep@*/ /*@null@*/ yasm_expr *fill,
376 /*@keep@*/ /*@null@*/ yasm_expr *maxskip,
377 /*@null@*/ const unsigned char **code_fill, unsigned long line);
379 /** Create a bytecode that puts the following bytecode at a fixed section
381 * \param start section offset of following bytecode
382 * \param fill fill value
383 * \param line virtual line (from yasm_linemap)
384 * \return Newly allocated bytecode.
387 /*@only@*/ yasm_bytecode *yasm_bc_create_org
388 (unsigned long start, unsigned long fill, unsigned long line);
390 /** Get the section that contains a particular bytecode.
392 * \return Section containing bc (can be NULL if bytecode is not part of a
396 /*@dependent@*/ /*@null@*/ yasm_section *yasm_bc_get_section
399 /** Add to the list of symrecs that reference a bytecode. For symrec use
405 void yasm_bc__add_symrec(yasm_bytecode *bc, /*@dependent@*/ yasm_symrec *sym);
407 /** Delete (free allocated memory for) a bytecode.
408 * \param bc bytecode (only pointer to it); may be NULL
411 void yasm_bc_destroy(/*@only@*/ /*@null@*/ yasm_bytecode *bc);
413 /** Print a bytecode. For debugging purposes.
415 * \param indent_level indentation level
419 void yasm_bc_print(const yasm_bytecode *bc, FILE *f, int indent_level);
421 /** Finalize a bytecode after parsing.
423 * \param prev_bc bytecode directly preceding bc in a list of bytecodes
426 void yasm_bc_finalize(yasm_bytecode *bc, yasm_bytecode *prev_bc);
428 /** Determine the distance between the starting offsets of two bytecodes.
429 * \param precbc1 preceding bytecode to the first bytecode
430 * \param precbc2 preceding bytecode to the second bytecode
431 * \return Distance in bytes between the two bytecodes (bc2-bc1), or NULL if
432 * the distance was indeterminate.
433 * \warning Only valid /after/ optimization.
436 /*@null@*/ /*@only@*/ yasm_intnum *yasm_calc_bc_dist
437 (yasm_bytecode *precbc1, yasm_bytecode *precbc2);
439 /** Get the offset of the next bytecode (the next bytecode doesn't have to
441 * \param precbc preceding bytecode
442 * \return Offset of the next bytecode in bytes.
443 * \warning Only valid /after/ optimization.
446 unsigned long yasm_bc_next_offset(yasm_bytecode *precbc);
448 /** Return elemens size of a data bytecode.
449 * Returns the size of each elements of a data bytecode, for proper dereference
450 * of symbols attached to it.
452 * \return 0 if element size is unknown
455 int yasm_bc_elem_size(yasm_bytecode *bc);
457 /** Resolve EQUs in a bytecode and calculate its minimum size.
458 * Generates dependent bytecode spans for cases where, if the length spanned
459 * increases, it could cause the bytecode size to increase.
460 * Any bytecode multiple is NOT included in the length or spans generation;
461 * this must be handled at a higher level.
463 * \param add_span function to call to add a span
464 * \param add_span_data extra data to be passed to add_span function
465 * \return 0 if no error occurred, nonzero if there was an error recognized
466 * (and output) during execution.
467 * \note May store to bytecode updated expressions and the short length.
470 int yasm_bc_calc_len(yasm_bytecode *bc, yasm_bc_add_span_func add_span,
471 void *add_span_data);
473 /** Recalculate a bytecode's length based on an expanded span length.
475 * \param span span ID (as given to yasm_bc_add_span_func in
477 * \param old_val previous span value
478 * \param new_val new span value
479 * \param neg_thres negative threshold for long/short decision (returned)
480 * \param pos_thres positive threshold for long/short decision (returned)
481 * \return 0 if bc no longer dependent on this span's length, negative if
482 * there was an error recognized (and output) during execution, and
483 * positive if bc size may increase for this span further based on the
484 * new negative and positive thresholds returned.
485 * \note May store to bytecode updated expressions and the updated length.
488 int yasm_bc_expand(yasm_bytecode *bc, int span, long old_val, long new_val,
489 /*@out@*/ long *neg_thres, /*@out@*/ long *pos_thres);
491 /** Convert a bytecode into its byte representation.
493 * \param buf byte representation destination buffer
494 * \param bufsize size of buf (in bytes) prior to call; size of the
495 * generated data after call
496 * \param gap if nonzero, indicates the data does not really need to
497 * exist in the object file; if nonzero, contents of buf
498 * are undefined [output]
499 * \param d data to pass to each call to output_value/output_reloc
500 * \param output_value function to call to convert values into their byte
502 * \param output_reloc function to call to output relocation entries
504 * \return Newly allocated buffer that should be used instead of buf for
505 * reading the byte representation, or NULL if buf was big enough to
506 * hold the entire byte representation.
507 * \note Calling twice on the same bytecode may \em not produce the same
508 * results on the second call, as calling this function may result in
509 * non-reversible changes to the bytecode.
512 /*@null@*/ /*@only@*/ unsigned char *yasm_bc_tobytes
513 (yasm_bytecode *bc, unsigned char *buf, unsigned long *bufsize,
514 /*@out@*/ int *gap, void *d, yasm_output_value_func output_value,
515 /*@null@*/ yasm_output_reloc_func output_reloc)
518 /** Get the bytecode multiple value as an integer.
520 * \param multiple multiple value (output)
521 * \param calc_bc_dist nonzero if distances between bytecodes should be
522 * calculated, 0 if error should be returned in this case
523 * \return 1 on error (set with yasm_error_set), 0 on success.
526 int yasm_bc_get_multiple(yasm_bytecode *bc, /*@out@*/ long *multiple,
529 /** Get the bytecode multiple value as an expression.
531 * \return Bytecode multiple, NULL if =1.
534 const yasm_expr *yasm_bc_get_multiple_expr(const yasm_bytecode *bc);
536 /** Get a #yasm_insn structure from an instruction bytecode (if possible).
538 * \return Instruction details if bytecode is an instruction bytecode,
542 /*@dependent@*/ /*@null@*/ yasm_insn *yasm_bc_get_insn(yasm_bytecode *bc);
544 /** Create a new data value from an expression.
545 * \param expn expression
546 * \return Newly allocated data value.
549 yasm_dataval *yasm_dv_create_expr(/*@keep@*/ yasm_expr *expn);
551 /** Create a new data value from a string.
552 * \param contents string (may contain NULs)
553 * \param len length of string
554 * \return Newly allocated data value.
556 yasm_dataval *yasm_dv_create_string(/*@keep@*/ char *contents, size_t len);
558 /** Create a new data value from raw bytes data.
559 * \param contents raw data (may contain NULs)
561 * \return Newly allocated data value.
564 yasm_dataval *yasm_dv_create_raw(/*@keep@*/ unsigned char *contents,
567 /** Create a new uninitialized data value.
568 * \return Newly allocated data value.
570 yasm_dataval *yasm_dv_create_reserve(void);
573 #define yasm_dv_create_string(s, l) yasm_dv_create_raw((unsigned char *)(s), \
577 /** Get the underlying value of a data value.
578 * \param dv data value
579 * \return Value, or null if non-value (e.g. string or raw).
581 yasm_value *yasm_dv_get_value(yasm_dataval *dv);
583 /** Set multiple field of a data value.
584 * A data value can be repeated a number of times when output. This function
585 * sets that multiple.
586 * \param dv data value
587 * \param e multiple (kept, do not free)
589 void yasm_dv_set_multiple(yasm_dataval *dv, /*@keep@*/ yasm_expr *e);
591 /** Get the data value multiple value as an unsigned long integer.
592 * \param dv data value
593 * \param multiple multiple value (output)
594 * \return 1 on error (set with yasm_error_set), 0 on success.
596 int yasm_dv_get_multiple(yasm_dataval *dv, /*@out@*/ unsigned long *multiple);
598 /** Initialize a list of data values.
599 * \param headp list of data values
601 void yasm_dvs_initialize(yasm_datavalhead *headp);
603 #define yasm_dvs_initialize(headp) STAILQ_INIT(headp)
606 /** Delete (free allocated memory for) a list of data values.
607 * \param headp list of data values
610 void yasm_dvs_delete(yasm_datavalhead *headp);
612 /** Add data value to the end of a list of data values.
613 * \note Does not make a copy of the data value; so don't pass this function
614 * static or local variables, and discard the dv pointer after calling
616 * \param headp data value list
617 * \param dv data value (may be NULL)
618 * \return If data value was actually appended (it wasn't NULL), the data
619 * value; otherwise NULL.
622 /*@null@*/ yasm_dataval *yasm_dvs_append
623 (yasm_datavalhead *headp, /*@returned@*/ /*@null@*/ yasm_dataval *dv);
625 /** Print a data value list. For debugging purposes.
627 * \param indent_level indentation level
628 * \param headp data value list
631 void yasm_dvs_print(const yasm_datavalhead *headp, FILE *f, int indent_level);