12 #define MAX_LABEL_REFS 32
39 uint32_t label_addrs[MAX_LABELS];
43 const char *label_names[MAX_LABELS];
57 uint32_t current_aligned_write_pos;
71 #define ALIGNED_WRITE_POSITION_NONE 1
148 static const x86opnd_t NO_OPND = { OPND_NONE, 0, .as.imm = 0 };
151 static const x86opnd_t RIP = { OPND_REG, 64, .as.reg = { REG_IP, 5 }};
154 static const x86opnd_t RAX = { OPND_REG, 64, .as.reg = { REG_GP, 0 }};
155 static const x86opnd_t RCX = { OPND_REG, 64, .as.reg = { REG_GP, 1 }};
156 static const x86opnd_t RDX = { OPND_REG, 64, .as.reg = { REG_GP, 2 }};
157 static const x86opnd_t RBX = { OPND_REG, 64, .as.reg = { REG_GP, 3 }};
158 static const x86opnd_t RSP = { OPND_REG, 64, .as.reg = { REG_GP, 4 }};
159 static const x86opnd_t RBP = { OPND_REG, 64, .as.reg = { REG_GP, 5 }};
160 static const x86opnd_t RSI = { OPND_REG, 64, .as.reg = { REG_GP, 6 }};
161 static const x86opnd_t RDI = { OPND_REG, 64, .as.reg = { REG_GP, 7 }};
162 static const x86opnd_t R8 = { OPND_REG, 64, .as.reg = { REG_GP, 8 }};
163 static const x86opnd_t R9 = { OPND_REG, 64, .as.reg = { REG_GP, 9 }};
164 static const x86opnd_t R10 = { OPND_REG, 64, .as.reg = { REG_GP, 10 }};
165 static const x86opnd_t R11 = { OPND_REG, 64, .as.reg = { REG_GP, 11 }};
166 static const x86opnd_t R12 = { OPND_REG, 64, .as.reg = { REG_GP, 12 }};
167 static const x86opnd_t R13 = { OPND_REG, 64, .as.reg = { REG_GP, 13 }};
168 static const x86opnd_t R14 = { OPND_REG, 64, .as.reg = { REG_GP, 14 }};
169 static const x86opnd_t R15 = { OPND_REG, 64, .as.reg = { REG_GP, 15 }};
172 static const x86opnd_t EAX = { OPND_REG, 32, .as.reg = { REG_GP, 0 }};
173 static const x86opnd_t ECX = { OPND_REG, 32, .as.reg = { REG_GP, 1 }};
174 static const x86opnd_t EDX = { OPND_REG, 32, .as.reg = { REG_GP, 2 }};
175 static const x86opnd_t EBX = { OPND_REG, 32, .as.reg = { REG_GP, 3 }};
176 static const x86opnd_t ESP = { OPND_REG, 32, .as.reg = { REG_GP, 4 }};
177 static const x86opnd_t EBP = { OPND_REG, 32, .as.reg = { REG_GP, 5 }};
178 static const x86opnd_t ESI = { OPND_REG, 32, .as.reg = { REG_GP, 6 }};
179 static const x86opnd_t EDI = { OPND_REG, 32, .as.reg = { REG_GP, 7 }};
180 static const x86opnd_t R8D = { OPND_REG, 32, .as.reg = { REG_GP, 8 }};
181 static const x86opnd_t R9D = { OPND_REG, 32, .as.reg = { REG_GP, 9 }};
182 static const x86opnd_t R10D = { OPND_REG, 32, .as.reg = { REG_GP, 10 }};
183 static const x86opnd_t R11D = { OPND_REG, 32, .as.reg = { REG_GP, 11 }};
184 static const x86opnd_t R12D = { OPND_REG, 32, .as.reg = { REG_GP, 12 }};
185 static const x86opnd_t R13D = { OPND_REG, 32, .as.reg = { REG_GP, 13 }};
186 static const x86opnd_t R14D = { OPND_REG, 32, .as.reg = { REG_GP, 14 }};
187 static const x86opnd_t R15D = { OPND_REG, 32, .as.reg = { REG_GP, 15 }};
190 static const x86opnd_t AX = { OPND_REG, 16, .as.reg = { REG_GP, 0 }};
191 static const x86opnd_t CX = { OPND_REG, 16, .as.reg = { REG_GP, 1 }};
192 static const x86opnd_t DX = { OPND_REG, 16, .as.reg = { REG_GP, 2 }};
193 static const x86opnd_t BX = { OPND_REG, 16, .as.reg = { REG_GP, 3 }};
194 static const x86opnd_t SP = { OPND_REG, 16, .as.reg = { REG_GP, 4 }};
195 static const x86opnd_t BP = { OPND_REG, 16, .as.reg = { REG_GP, 5 }};
196 static const x86opnd_t SI = { OPND_REG, 16, .as.reg = { REG_GP, 6 }};
197 static const x86opnd_t DI = { OPND_REG, 16, .as.reg = { REG_GP, 7 }};
198 static const x86opnd_t R8W = { OPND_REG, 16, .as.reg = { REG_GP, 8 }};
199 static const x86opnd_t R9W = { OPND_REG, 16, .as.reg = { REG_GP, 9 }};
200 static const x86opnd_t R10W = { OPND_REG, 16, .as.reg = { REG_GP, 10 }};
201 static const x86opnd_t R11W = { OPND_REG, 16, .as.reg = { REG_GP, 11 }};
202 static const x86opnd_t R12W = { OPND_REG, 16, .as.reg = { REG_GP, 12 }};
203 static const x86opnd_t R13W = { OPND_REG, 16, .as.reg = { REG_GP, 13 }};
204 static const x86opnd_t R14W = { OPND_REG, 16, .as.reg = { REG_GP, 14 }};
205 static const x86opnd_t R15W = { OPND_REG, 16, .as.reg = { REG_GP, 15 }};
208 static const x86opnd_t AL = { OPND_REG, 8, .as.reg = { REG_GP, 0 }};
209 static const x86opnd_t CL = { OPND_REG, 8, .as.reg = { REG_GP, 1 }};
210 static const x86opnd_t DL = { OPND_REG, 8, .as.reg = { REG_GP, 2 }};
211 static const x86opnd_t BL = { OPND_REG, 8, .as.reg = { REG_GP, 3 }};
212 static const x86opnd_t SPL = { OPND_REG, 8, .as.reg = { REG_GP, 4 }};
213 static const x86opnd_t BPL = { OPND_REG, 8, .as.reg = { REG_GP, 5 }};
214 static const x86opnd_t SIL = { OPND_REG, 8, .as.reg = { REG_GP, 6 }};
215 static const x86opnd_t DIL = { OPND_REG, 8, .as.reg = { REG_GP, 7 }};
216 static const x86opnd_t R8B = { OPND_REG, 8, .as.reg = { REG_GP, 8 }};
217 static const x86opnd_t R9B = { OPND_REG, 8, .as.reg = { REG_GP, 9 }};
218 static const x86opnd_t R10B = { OPND_REG, 8, .as.reg = { REG_GP, 10 }};
219 static const x86opnd_t R11B = { OPND_REG, 8, .as.reg = { REG_GP, 11 }};
220 static const x86opnd_t R12B = { OPND_REG, 8, .as.reg = { REG_GP, 12 }};
221 static const x86opnd_t R13B = { OPND_REG, 8, .as.reg = { REG_GP, 13 }};
222 static const x86opnd_t R14B = { OPND_REG, 8, .as.reg = { REG_GP, 14 }};
223 static const x86opnd_t R15B = { OPND_REG, 8, .as.reg = { REG_GP, 15 }};
226 #define NUM_C_ARG_REGS 6
227 #define C_ARG_REGS ( (x86opnd_t[]){ RDI, RSI, RDX, RCX, R8, R9 } )
230 static inline uint32_t sig_imm_size(int64_t imm);
231 static inline uint32_t unsig_imm_size(uint64_t imm);
234 static inline x86opnd_t mem_opnd(uint32_t num_bits,
x86opnd_t base_reg, int32_t disp);
240 static inline x86opnd_t imm_opnd(int64_t val);
243 static inline x86opnd_t const_ptr_opnd(
const void *ptr);
246 #define member_opnd(base_reg, struct_type, member_name) mem_opnd( \
247 8 * sizeof(((struct_type*)0)->member_name), \
249 offsetof(struct_type, member_name) \
253 #define member_opnd_idx(base_reg, struct_type, member_name, idx) mem_opnd( \
254 8 * sizeof(((struct_type*)0)->member_name[0]), \
256 (offsetof(struct_type, member_name) + \
257 sizeof(((struct_type*)0)->member_name[0]) * idx) \
261 static uint8_t *alloc_exec_mem(uint32_t mem_size);
264 static inline void cb_init(
codeblock_t *cb, uint8_t *mem_block, uint32_t mem_size);
265 static inline void cb_align_pos(
codeblock_t *cb, uint32_t multiple);
266 static inline void cb_set_pos(
codeblock_t *cb, uint32_t pos);
267 static inline void cb_set_write_ptr(
codeblock_t *cb, uint8_t *code_ptr);
268 static inline uint8_t *cb_get_ptr(
const codeblock_t *cb, uint32_t index);
269 static inline uint8_t *cb_get_write_ptr(
const codeblock_t *cb);
270 static inline void cb_write_byte(
codeblock_t *cb, uint8_t
byte);
271 static inline void cb_write_bytes(
codeblock_t *cb, uint32_t num_bytes, ...);
272 static inline void cb_write_int(
codeblock_t *cb, uint64_t val, uint32_t num_bits);
273 static inline uint32_t cb_new_label(
codeblock_t *cb,
const char *name);
274 static inline void cb_write_label(
codeblock_t *cb, uint32_t label_idx);
275 static inline void cb_label_ref(
codeblock_t *cb, uint32_t label_idx);
276 static inline void cb_link_labels(
codeblock_t *cb);
277 static inline void cb_mark_all_writeable(
codeblock_t *cb);
278 static inline void cb_mark_position_writeable(
codeblock_t *cb, uint32_t write_pos);
279 static inline void cb_mark_all_executable(
codeblock_t *cb);
285 static inline void call_label(
codeblock_t *cb, uint32_t label_idx);
321 static inline void ja_label(
codeblock_t *cb, uint32_t label_idx);
322 static inline void jae_label(
codeblock_t *cb, uint32_t label_idx);
323 static inline void jb_label(
codeblock_t *cb, uint32_t label_idx);
324 static inline void jbe_label(
codeblock_t *cb, uint32_t label_idx);
325 static inline void jc_label(
codeblock_t *cb, uint32_t label_idx);
326 static inline void je_label(
codeblock_t *cb, uint32_t label_idx);
327 static inline void jg_label(
codeblock_t *cb, uint32_t label_idx);
328 static inline void jge_label(
codeblock_t *cb, uint32_t label_idx);
329 static inline void jl_label(
codeblock_t *cb, uint32_t label_idx);
330 static inline void jle_label(
codeblock_t *cb, uint32_t label_idx);
331 static inline void jna_label(
codeblock_t *cb, uint32_t label_idx);
332 static inline void jnae_label(
codeblock_t *cb, uint32_t label_idx);
333 static inline void jnb_label(
codeblock_t *cb, uint32_t label_idx);
334 static inline void jnbe_label(
codeblock_t *cb, uint32_t label_idx);
335 static inline void jnc_label(
codeblock_t *cb, uint32_t label_idx);
336 static inline void jne_label(
codeblock_t *cb, uint32_t label_idx);
337 static inline void jng_label(
codeblock_t *cb, uint32_t label_idx);
338 static inline void jnge_label(
codeblock_t *cb, uint32_t label_idx);
339 static inline void jnl_label(
codeblock_t *cb, uint32_t label_idx);
340 static inline void jnle_label(
codeblock_t *cb, uint32_t label_idx);
341 static inline void jno_label(
codeblock_t *cb, uint32_t label_idx);
342 static inline void jnp_label(
codeblock_t *cb, uint32_t label_idx);
343 static inline void jns_label(
codeblock_t *cb, uint32_t label_idx);
344 static inline void jnz_label(
codeblock_t *cb, uint32_t label_idx);
345 static inline void jo_label(
codeblock_t *cb, uint32_t label_idx);
346 static inline void jp_label(
codeblock_t *cb, uint32_t label_idx);
347 static inline void jpe_label(
codeblock_t *cb, uint32_t label_idx);
348 static inline void jpo_label(
codeblock_t *cb, uint32_t label_idx);
349 static inline void js_label(
codeblock_t *cb, uint32_t label_idx);
350 static inline void jz_label(
codeblock_t *cb, uint32_t label_idx);
351 static inline void ja_ptr(
codeblock_t *cb, uint8_t *ptr);
352 static inline void jae_ptr(
codeblock_t *cb, uint8_t *ptr);
353 static inline void jb_ptr(
codeblock_t *cb, uint8_t *ptr);
354 static inline void jbe_ptr(
codeblock_t *cb, uint8_t *ptr);
355 static inline void jc_ptr(
codeblock_t *cb, uint8_t *ptr);
356 static inline void je_ptr(
codeblock_t *cb, uint8_t *ptr);
357 static inline void jg_ptr(
codeblock_t *cb, uint8_t *ptr);
358 static inline void jge_ptr(
codeblock_t *cb, uint8_t *ptr);
359 static inline void jl_ptr(
codeblock_t *cb, uint8_t *ptr);
360 static inline void jle_ptr(
codeblock_t *cb, uint8_t *ptr);
361 static inline void jna_ptr(
codeblock_t *cb, uint8_t *ptr);
362 static inline void jnae_ptr(
codeblock_t *cb, uint8_t *ptr);
363 static inline void jnb_ptr(
codeblock_t *cb, uint8_t *ptr);
364 static inline void jnbe_ptr(
codeblock_t *cb, uint8_t *ptr);
365 static inline void jnc_ptr(
codeblock_t *cb, uint8_t *ptr);
366 static inline void jne_ptr(
codeblock_t *cb, uint8_t *ptr);
367 static inline void jng_ptr(
codeblock_t *cb, uint8_t *ptr);
368 static inline void jnge_ptr(
codeblock_t *cb, uint8_t *ptr);
369 static inline void jnl_ptr(
codeblock_t *cb, uint8_t *ptr);
370 static inline void jnle_ptr(
codeblock_t *cb, uint8_t *ptr);
371 static inline void jno_ptr(
codeblock_t *cb, uint8_t *ptr);
372 static inline void jnp_ptr(
codeblock_t *cb, uint8_t *ptr);
373 static inline void jns_ptr(
codeblock_t *cb, uint8_t *ptr);
374 static inline void jnz_ptr(
codeblock_t *cb, uint8_t *ptr);
375 static inline void jo_ptr(
codeblock_t *cb, uint8_t *ptr);
376 static inline void jp_ptr(
codeblock_t *cb, uint8_t *ptr);
377 static inline void jpe_ptr(
codeblock_t *cb, uint8_t *ptr);
378 static inline void jpo_ptr(
codeblock_t *cb, uint8_t *ptr);
379 static inline void js_ptr(
codeblock_t *cb, uint8_t *ptr);
380 static inline void jz_ptr(
codeblock_t *cb, uint8_t *ptr);
381 static inline void jmp_label(
codeblock_t *cb, uint32_t label_idx);
382 static inline void jmp_ptr(
codeblock_t *cb, uint8_t *ptr);
384 static inline void jmp32(
codeblock_t *cb, int32_t offset);
389 static inline void nop(
codeblock_t *cb, uint32_t length);
406 static inline void cb_write_lock_prefix(
codeblock_t *cb);
uint8_t base_reg_no
Base register number.
bool has_idx
Has index register flag.
bool is_iprel
IP-relative addressing flag.
uint8_t scale_exp
SIB scale exponent value (power of two, two bits)
int32_t disp
Constant displacement from the base, not scaled.
uint8_t idx_reg_no
Index register number.