• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * \file libyasm/insn.h
3  * \brief YASM mnenomic instruction.
4  *
5  * \license
6  *  Copyright (C) 2002-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_INSN_H
31 #define YASM_INSN_H
32 
33 #ifndef YASM_LIB_DECL
34 #define YASM_LIB_DECL
35 #endif
36 
37 /** Base structure for an effective address.  As with all base
38  * structures, must be present as the first element in any
39  * #yasm_arch implementation of an effective address.
40  */
41 struct yasm_effaddr {
42     yasm_value disp;            /**< address displacement */
43 
44     /** Segment register override (0 if none). */
45     uintptr_t segreg;
46 
47     /** 1 if length of disp must be >0. */
48     unsigned int need_nonzero_len:1;
49 
50     /** 1 if a displacement should be present in the output. */
51     unsigned int need_disp:1;
52 
53     /** 1 if reg*2 should not be split into reg+reg. (0 if not).
54      * This flag indicates (for architectures that support complex effective
55      * addresses such as x86) if various types of complex effective addresses
56      * can be split into different forms in order to minimize instruction
57      * length.
58      */
59     unsigned int nosplit:1;
60 
61     /** 1 if effective address is /definitely/ an effective address.
62      * This is used in e.g. the GAS parser to differentiate
63      * between "expr" (which might or might not be an effective address) and
64      * "expr(,1)" (which is definitely an effective address).
65      */
66     unsigned int strong:1;
67 
68     /** 1 if effective address is forced PC-relative. */
69     unsigned int pc_rel:1;
70 
71     /** 1 if effective address is forced non-PC-relative. */
72     unsigned int not_pc_rel:1;
73 
74     /** length of pointed data (in bytes), 0 if unknown. */
75     unsigned int data_len;
76 };
77 
78 /** An instruction operand (opaque type). */
79 typedef struct yasm_insn_operand yasm_insn_operand;
80 
81 /** The type of an instruction operand. */
82 typedef enum yasm_insn_operand_type {
83     YASM_INSN__OPERAND_REG = 1,     /**< A register. */
84     YASM_INSN__OPERAND_SEGREG,      /**< A segment register. */
85     YASM_INSN__OPERAND_MEMORY,      /**< An effective address
86                                      *   (memory reference). */
87     YASM_INSN__OPERAND_IMM          /**< An immediate or jump target. */
88 } yasm_insn_operand_type;
89 
90 /** An instruction operand. */
91 struct yasm_insn_operand {
92     /** Link for building linked list of operands.  \internal */
93     /*@reldef@*/ STAILQ_ENTRY(yasm_insn_operand) link;
94 
95     /** Operand data. */
96     union {
97         uintptr_t reg;      /**< Arch data for reg/segreg. */
98         yasm_effaddr *ea;   /**< Effective address for memory references. */
99         yasm_expr *val;     /**< Value of immediate or jump target. */
100     } data;
101 
102     yasm_expr *seg;         /**< Segment expression */
103 
104     uintptr_t targetmod;        /**< Arch target modifier, 0 if none. */
105 
106     /** Specified size of the operand, in bits.  0 if not user-specified. */
107     unsigned int size:16;
108 
109     /** Nonzero if dereference.  Used for "*foo" in GAS.
110      * The reason for this is that by default in GAS, an unprefixed value
111      * is a memory address, except for jumps/calls, in which case it needs a
112      * "*" prefix to become a memory address (otherwise it's an immediate).
113      * This isn't knowable in the parser stage, so the parser sets this flag
114      * to indicate the "*" prefix has been used, and the arch needs to adjust
115      * the operand type appropriately depending on the instruction type.
116      */
117     unsigned int deref:1;
118 
119     /** Nonzero if strict.  Used for "strict foo" in NASM.
120      * This is used to inhibit optimization on otherwise "sized" values.
121      * For example, the user may just want to be explicit with the size on
122      * "push dword 4", but not actually want to force the immediate size to
123      * 4 bytes (rather wanting the optimizer to optimize it down to 1 byte as
124      * though "dword" was not specified).  To indicate the immediate should
125      * actually be forced to 4 bytes, the user needs to write
126      * "push strict dword 4", which sets this flag.
127      */
128     unsigned int strict:1;
129 
130     /** Operand type. */
131     unsigned int type:4;
132 };
133 
134 /** Base structure for "instruction" bytecodes.  These are the mnenomic
135  * (rather than raw) representation of instructions.  As with all base
136  * structures, must be present as the first element in any
137  * #yasm_arch implementation of mnenomic instruction bytecodes.
138  */
139 struct yasm_insn {
140     /** Linked list of operands. */
141     /*@reldef@*/ STAILQ_HEAD(yasm_insn_operands, yasm_insn_operand) operands;
142 
143     /** Array of prefixes. */
144     /*@null@*/ uintptr_t *prefixes;
145 
146     /** Array of segment prefixes. */
147     /*@null@*/ uintptr_t *segregs;
148 
149     unsigned int num_operands;       /**< Number of operands. */
150     unsigned int num_prefixes;       /**< Number of prefixes. */
151     unsigned int num_segregs;        /**< Number of segment prefixes. */
152 };
153 
154 /** Set segment override for an effective address.
155  * Some architectures (such as x86) support segment overrides on effective
156  * addresses.  A override of an override will result in a warning.
157  * \param ea            effective address
158  * \param segreg        segment register (0 if none)
159  */
160 YASM_LIB_DECL
161 void yasm_ea_set_segreg(yasm_effaddr *ea, uintptr_t segreg);
162 
163 /** Create an instruction operand from a register.
164  * \param reg   register
165  * \return Newly allocated operand.
166  */
167 YASM_LIB_DECL
168 yasm_insn_operand *yasm_operand_create_reg(uintptr_t reg);
169 
170 /** Create an instruction operand from a segment register.
171  * \param segreg        segment register
172  * \return Newly allocated operand.
173  */
174 YASM_LIB_DECL
175 yasm_insn_operand *yasm_operand_create_segreg(uintptr_t segreg);
176 
177 /** Create an instruction operand from an effective address.
178  * \param ea    effective address
179  * \return Newly allocated operand.
180  */
181 YASM_LIB_DECL
182 yasm_insn_operand *yasm_operand_create_mem(/*@only@*/ yasm_effaddr *ea);
183 
184 /** Create an instruction operand from an immediate expression.
185  * Looks for cases of a single register and creates a register variant of
186  * #yasm_insn_operand.
187  * \param val   immediate expression
188  * \return Newly allocated operand.
189  */
190 YASM_LIB_DECL
191 yasm_insn_operand *yasm_operand_create_imm(/*@only@*/ yasm_expr *val);
192 
193 /** Get the first operand in an instruction.
194  * \param insn          instruction
195  * \return First operand (NULL if no operands).
196  */
197 yasm_insn_operand *yasm_insn_ops_first(yasm_insn *insn);
198 #define yasm_insn_ops_first(insn)   STAILQ_FIRST(&((insn)->operands))
199 
200 /** Get the next operand in an instruction.
201  * \param op            previous operand
202  * \return Next operand (NULL if op was the last operand).
203  */
204 yasm_insn_operand *yasm_insn_op_next(yasm_insn_operand *op);
205 #define yasm_insn_op_next(cur)      STAILQ_NEXT(cur, link)
206 
207 /** Add operand to the end of an instruction.
208  * \note Does not make a copy of the operand; so don't pass this function
209  *       static or local variables, and discard the op pointer after calling
210  *       this function.
211  * \param insn          instruction
212  * \param op            operand (may be NULL)
213  * \return If operand was actually appended (it wasn't NULL), the operand;
214  *         otherwise NULL.
215  */
216 YASM_LIB_DECL
217 /*@null@*/ yasm_insn_operand *yasm_insn_ops_append
218     (yasm_insn *insn,
219      /*@returned@*/ /*@null@*/ yasm_insn_operand *op);
220 
221 /** Associate a prefix with an instruction.
222  * \param insn          instruction
223  * \param prefix        data that identifies the prefix
224  */
225 YASM_LIB_DECL
226 void yasm_insn_add_prefix(yasm_insn *insn, uintptr_t prefix);
227 
228 /** Associate a segment prefix with an instruction.
229  * \param insn          instruction
230  * \param segreg        data that identifies the segment register
231  */
232 YASM_LIB_DECL
233 void yasm_insn_add_seg_prefix(yasm_insn *insn, uintptr_t segreg);
234 
235 /** Initialize the common parts of an instruction.
236  * \internal For use by yasm_arch implementations only.
237  * \param insn          instruction
238  */
239 YASM_LIB_DECL
240 void yasm_insn_initialize(/*@out@*/ yasm_insn *insn);
241 
242 /** Delete the common parts of an instruction.
243  * \internal For use by yasm_arch implementations only.
244  * \param insn          instruction
245  * \param content       if nonzero, deletes content of each operand
246  * \param arch          architecture
247  */
248 YASM_LIB_DECL
249 void yasm_insn_delete(yasm_insn *insn,
250                       void (*ea_destroy) (/*@only@*/ yasm_effaddr *));
251 
252 /** Print a list of instruction operands.  For debugging purposes.
253  * \internal For use by yasm_arch implementations only.
254  * \param insn          instruction
255  * \param f             file
256  * \param indent_level  indentation level
257  * \param arch          architecture
258  */
259 YASM_LIB_DECL
260 void yasm_insn_print(const yasm_insn *insn, FILE *f, int indent_level);
261 
262 /** Finalize the common parts of an instruction.
263  * \internal For use by yasm_arch implementations only.
264  * \param insn          instruction
265  */
266 YASM_LIB_DECL
267 void yasm_insn_finalize(yasm_insn *insn);
268 
269 #endif
270