1 /**
2  * \file libyasm/value.h
3  * \brief YASM value interface.
4  *
5  * \license
6  *  Copyright (C) 2006-2007  Peter Johnson
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
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.
16  *
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.
28  * \endlicense
29  */
30 #ifndef YASM_VALUE_H
31 #define YASM_VALUE_H
32 
33 #ifndef YASM_LIB_DECL
34 #define YASM_LIB_DECL
35 #endif
36 
37 /** Initialize a #yasm_value with just an expression.  No processing is
38  * performed, the expression is simply stuck into value.abs and the other
39  * fields are initialized.  Use yasm_expr_extract_value() to perform "smart"
40  * processing into a #yasm_value.  This function is intended for use during
41  * parsing simply to ensure all fields of the value are initialized; after
42  * the parse is complete, yasm_value_extract() should be called to finalize
43  * the value.  The value defaults to unsigned.
44  * \param value     value to be initialized
45  * \param e         expression (kept)
46  * \param size      value size (in bits)
47  */
48 YASM_LIB_DECL
49 void yasm_value_initialize(/*@out@*/ yasm_value *value,
50                            /*@null@*/ /*@kept@*/ yasm_expr *e,
51                            unsigned int size);
52 
53 /** Initialize a #yasm_value with just a symrec.  No processing is performed,
54  * the symrec is simply stuck into value.rel and the other fields are
55  * initialized.
56  * \param value     value to be initialized
57  * \param sym       symrec
58  * \param size      value size (in bits)
59  */
60 YASM_LIB_DECL
61 void yasm_value_init_sym(/*@out@*/ yasm_value *value,
62                          /*@null@*/ yasm_symrec *sym, unsigned int size);
63 
64 /** Initialize a #yasm_value as a copy of another yasm_value.  Any expressions
65  * within orig are copied, so it's safe to delete the copy.
66  * \param value     value (copy to create)
67  * \param orig      original value
68  */
69 YASM_LIB_DECL
70 void yasm_value_init_copy(yasm_value *value, const yasm_value *orig);
71 
72 /** Frees any memory inside value; does not free value itself.
73  * \param value     value
74  */
75 YASM_LIB_DECL
76 void yasm_value_delete(yasm_value *value);
77 
78 /** Set a value to be relative to the current assembly position rather than
79  * relative to the section start.
80  * \param value     value
81  * \param bc        bytecode containing value
82  * \param ip_rel    if nonzero, indicates IP-relative data relocation,
83  *                  sometimes used to generate special relocations
84  * \note If value is just an absolute value, will get an absolute symrec to
85  *       reference to (via bc's symbol table).
86  */
87 YASM_LIB_DECL
88 void yasm_value_set_curpos_rel(yasm_value *value, yasm_bytecode *bc,
89                                unsigned int ip_rel);
90 
91 /** Perform yasm_value_finalize_expr() on a value that already exists from
92  * being initialized with yasm_value_initialize().
93  * \param value         value
94  * \param precbc        previous bytecode to bytecode containing value
95  * \return Nonzero if value could not be split.
96  */
97 YASM_LIB_DECL
98 int yasm_value_finalize(yasm_value *value, /*@null@*/ yasm_bytecode *precbc);
99 
100 /** Break a #yasm_expr into a #yasm_value constituent parts.  Extracts
101  * the relative portion of the value, SEG and WRT portions, and top-level
102  * right shift, if any.  Places the remaining expr into the absolute
103  * portion of the value.  Essentially a combination of yasm_value_initialize()
104  * and yasm_value_finalize().  First expands references to symrecs in
105  * absolute sections by expanding with the absolute section start plus the
106  * symrec offset within the absolute section.
107  * \param value         value to store split portions into
108  * \param e             expression input
109  * \param precbc        previous bytecode to bytecode containing expression
110  * \param size          value size (in bits)
111  * \return Nonzero if the expr could not be split into a value for some
112  *         reason (e.g. the relative portion was not added, but multiplied,
113  *         etc).
114  * \warning Do not use e after this call.  Even if an error is returned, e
115  *          is stored into value.
116  * \note This should only be called after the parse is complete.  Calling
117  *       before the parse is complete will usually result in an error return.
118  */
119 YASM_LIB_DECL
120 int yasm_value_finalize_expr(/*@out@*/ yasm_value *value,
121                              /*@null@*/ /*@kept@*/ yasm_expr *e,
122                              /*@null@*/ yasm_bytecode *precbc,
123                              unsigned int size);
124 
125 /** Get value if absolute or PC-relative section-local relative.  Returns NULL
126  * otherwise.
127  * \param value         value
128  * \param bc            current bytecode (for PC-relative calculation); if
129  *                      NULL, NULL is returned for PC-relative values.
130  * \param calc_bc_dist  if nonzero, calculates bytecode distances in absolute
131  *                      portion of value
132  * \note Adds in value.rel (correctly) if PC-relative and in the same section
133  *       as bc (and there is no WRT or SEG).
134  * \return Intnum if can be resolved to integer value, otherwise NULL.
135  */
136 YASM_LIB_DECL
137 /*@null@*/ /*@only@*/ yasm_intnum *yasm_value_get_intnum
138     (yasm_value *value, /*@null@*/ yasm_bytecode *bc, int calc_bc_dist);
139 
140 /** Output value if constant or PC-relative section-local.  This should be
141  * used from objfmt yasm_output_value_func() functions.
142  * functions.
143  * \param value         value
144  * \param buf           buffer for byte representation
145  * \param destsize      destination size (in bytes)
146  * \param bc            current bytecode (usually passed into higher-level
147  *                      calling function)
148  * \param warn          enables standard warnings: zero for none;
149  *                      nonzero for overflow/underflow floating point and
150  *                      integer warnings
151  * \param arch          architecture
152  * \note Adds in value.rel (correctly) if PC-relative and in the same section
153  *       as bc (and there is no WRT or SEG); if this is not the desired
154  *       behavior, e.g. a reloc is needed in this case, don't use this
155  *       function!
156  * \return 0 if no value output due to value needing relocation;
157  *         1 if value output; -1 if error.
158  */
159 YASM_LIB_DECL
160 int yasm_value_output_basic
161     (yasm_value *value, /*@out@*/ unsigned char *buf, size_t destsize,
162      yasm_bytecode *bc, int warn, yasm_arch *arch);
163 
164 /** Print a value.  For debugging purposes.
165  * \param value         value
166  * \param indent_level  indentation level
167  * \param f             file
168  */
169 YASM_LIB_DECL
170 void yasm_value_print(const yasm_value *value, FILE *f, int indent_level);
171 
172 #endif
173