Update release-README after completing the 2.43 release.
[binutils-gdb.git] / gas / config / tc-i386-ginsn.c
blobb9dc9c10cbbc5a08df52be70fbeba36da39d2996
1 /* tc-i386-ginsn.c -- Ginsn generation for the x86-64 ISA
3 Copyright (C) 2024 Free Software Foundation, Inc.
5 This file is part of GAS.
7 GAS is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the license, or
10 (at your option) any later version.
12 GAS is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; see the file COPYING3. If not,
19 see <http://www.gnu.org/licenses/>. */
21 /* This file contains the implementation of the ginsn creation for x86-64
22 instructions. */
24 /* DWARF register number for EFLAGS. Used for pushf/popf insns. */
25 #define GINSN_DW2_REGNUM_EFLAGS 49
26 /* DWARF register number for RSI. Used as dummy value when RegIP/RegIZ. */
27 #define GINSN_DW2_REGNUM_RSI_DUMMY 4
29 /* Identify the callee-saved registers in System V AMD64 ABI. */
31 bool
32 x86_scfi_callee_saved_p (unsigned int dw2reg_num)
34 if (dw2reg_num == 3 /* rbx. */
35 || dw2reg_num == REG_FP /* rbp. */
36 || dw2reg_num == REG_SP /* rsp. */
37 || (dw2reg_num >= 12 && dw2reg_num <= 15) /* r12 - r15. */)
38 return true;
40 return false;
43 /* Check whether an instruction prefix which affects operation size
44 accompanies. For insns in the legacy space, setting REX.W takes precedence
45 over the operand-size prefix (66H) when both are used.
47 The current users of this API are in the handlers for PUSH, POP or other
48 instructions which affect the stack pointer implicitly: the operation size
49 (16, 32, or 64 bits) determines the amount by which the stack pointer is
50 incremented / decremented (2, 4 or 8). */
52 static bool
53 ginsn_opsize_prefix_p (void)
55 return (!(i.prefix[REX_PREFIX] & REX_W) && i.prefix[DATA_PREFIX]);
58 /* Get the DWARF register number for the given register entry.
59 For specific byte/word/dword register accesses like al, cl, ah, ch, r8d,
60 r20w etc., we need to identify the DWARF register number for the
61 corresponding 8-byte GPR.
63 This function is a hack - it relies on relative ordering of reg entries in
64 the i386_regtab. FIXME - it will be good to allow a more direct way to get
65 this information. */
67 static unsigned int
68 ginsn_dw2_regnum (const reg_entry *ireg)
70 const reg_entry *temp = ireg;
71 unsigned int dwarf_reg = Dw2Inval, idx = 0;
73 /* ginsn creation is available for AMD64 abi only ATM. Other flag_code
74 are not expected. */
75 gas_assert (ireg && flag_code == CODE_64BIT);
77 /* Watch out for RegIP, RegIZ. These are expected to appear only with
78 base/index addressing modes. Although creating inaccurate data
79 dependencies, using a dummy value (lets say volatile register rsi) will
80 not hurt SCFI. TBD_GINSN_GEN_NOT_SCFI. */
81 if (ireg->reg_num == RegIP || ireg->reg_num == RegIZ)
82 return GINSN_DW2_REGNUM_RSI_DUMMY;
84 dwarf_reg = ireg->dw2_regnum[object_64bit];
86 if (dwarf_reg == Dw2Inval)
88 if (ireg <= &i386_regtab[3])
89 /* For al, cl, dl, bl, bump over to axl, cxl, dxl, bxl respectively by
90 adding 8. */
91 temp = ireg + 8;
92 else if (ireg <= &i386_regtab[7])
93 /* For ah, ch, dh, bh, bump over to axl, cxl, dxl, bxl respectively by
94 adding 4. */
95 temp = ireg + 4;
96 else
98 /* The code relies on the relative ordering of the reg entries in
99 i386_regtab. There are 32 register entries between axl-r31b,
100 ax-r31w etc. The assertions here ensures the code does not
101 recurse indefinitely. */
102 gas_assert ((temp - &i386_regtab[0]) >= 0);
103 idx = temp - &i386_regtab[0];
104 gas_assert (idx + 32 < i386_regtab_size - 1);
106 temp = temp + 32;
109 dwarf_reg = ginsn_dw2_regnum (temp);
112 /* Sanity check - failure may indicate state corruption, bad ginsn or
113 perhaps the i386-reg table and the current function got out of sync. */
114 gas_assert (dwarf_reg < Dw2Inval);
116 return dwarf_reg;
119 static ginsnS *
120 x86_ginsn_addsub_reg_mem (const symbolS *insn_end_sym)
122 unsigned int dw2_regnum;
123 unsigned int src1_dw2_regnum;
124 ginsnS *ginsn = NULL;
125 ginsnS * (*ginsn_func) (const symbolS *, bool,
126 enum ginsn_src_type, unsigned int, offsetT,
127 enum ginsn_src_type, unsigned int, offsetT,
128 enum ginsn_dst_type, unsigned int, offsetT);
129 uint16_t opcode = i.tm.base_opcode;
131 gas_assert (i.tm.opcode_space == SPACE_BASE
132 && (opcode == 0x1 || opcode == 0x29));
133 ginsn_func = (opcode == 0x1) ? ginsn_new_add : ginsn_new_sub;
135 /* op %reg, symbol or even other cases where destination involves indirect
136 access are unnecessary for SCFI correctness. TBD_GINSN_GEN_NOT_SCFI. */
137 if (i.mem_operands)
138 return ginsn;
140 /* Skip detection of 8/16/32-bit op size; 'add/sub reg, reg/mem' ops always
141 make the dest reg untraceable for SCFI. */
143 /* op reg, reg/mem. */
144 src1_dw2_regnum = ginsn_dw2_regnum (i.op[0].regs);
145 /* Of interest only when second opnd is not memory. */
146 if (i.reg_operands == 2)
148 dw2_regnum = ginsn_dw2_regnum (i.op[1].regs);
149 ginsn = ginsn_func (insn_end_sym, true,
150 GINSN_SRC_REG, src1_dw2_regnum, 0,
151 GINSN_SRC_REG, dw2_regnum, 0,
152 GINSN_DST_REG, dw2_regnum, 0);
153 ginsn_set_where (ginsn);
156 return ginsn;
159 static ginsnS *
160 x86_ginsn_addsub_mem_reg (const symbolS *insn_end_sym)
162 unsigned int dw2_regnum;
163 unsigned int src1_dw2_regnum;
164 const reg_entry *mem_reg;
165 int32_t gdisp = 0;
166 ginsnS *ginsn = NULL;
167 ginsnS * (*ginsn_func) (const symbolS *, bool,
168 enum ginsn_src_type, unsigned int, offsetT,
169 enum ginsn_src_type, unsigned int, offsetT,
170 enum ginsn_dst_type, unsigned int, offsetT);
171 uint16_t opcode = i.tm.base_opcode;
173 gas_assert (i.tm.opcode_space == SPACE_BASE
174 && (opcode == 0x3 || opcode == 0x2b));
175 ginsn_func = (opcode == 0x3) ? ginsn_new_add : ginsn_new_sub;
177 /* op symbol, %reg. */
178 if (i.mem_operands && !i.base_reg && !i.index_reg)
179 return ginsn;
181 /* Skip detection of 8/16/32-bit op size; 'add/sub reg/mem, reg' ops always
182 make the dest reg untraceable for SCFI. */
184 /* op reg/mem, %reg. */
185 dw2_regnum = ginsn_dw2_regnum (i.op[1].regs);
187 if (i.reg_operands == 2)
189 src1_dw2_regnum = ginsn_dw2_regnum (i.op[0].regs);
190 ginsn = ginsn_func (insn_end_sym, true,
191 GINSN_SRC_REG, src1_dw2_regnum, 0,
192 GINSN_SRC_REG, dw2_regnum, 0,
193 GINSN_DST_REG, dw2_regnum, 0);
194 ginsn_set_where (ginsn);
196 else if (i.mem_operands)
198 mem_reg = (i.base_reg) ? i.base_reg : i.index_reg;
199 src1_dw2_regnum = ginsn_dw2_regnum (mem_reg);
200 if (i.disp_operands == 1)
201 gdisp = i.op[0].disps->X_add_number;
202 ginsn = ginsn_func (insn_end_sym, true,
203 GINSN_SRC_INDIRECT, src1_dw2_regnum, gdisp,
204 GINSN_SRC_REG, dw2_regnum, 0,
205 GINSN_DST_REG, dw2_regnum, 0);
206 ginsn_set_where (ginsn);
209 return ginsn;
212 static ginsnS *
213 x86_ginsn_alu_imm (const symbolS *insn_end_sym)
215 offsetT src_imm;
216 unsigned int dw2_regnum;
217 ginsnS *ginsn = NULL;
218 enum ginsn_src_type src_type = GINSN_SRC_REG;
219 enum ginsn_dst_type dst_type = GINSN_DST_REG;
221 ginsnS * (*ginsn_func) (const symbolS *, bool,
222 enum ginsn_src_type, unsigned int, offsetT,
223 enum ginsn_src_type, unsigned int, offsetT,
224 enum ginsn_dst_type, unsigned int, offsetT);
226 /* FIXME - create ginsn where dest is REG_SP / REG_FP only ? */
227 /* Map for insn.tm.extension_opcode
228 000 ADD 100 AND
229 001 OR 101 SUB
230 010 ADC 110 XOR
231 011 SBB 111 CMP */
233 /* add/sub/and imm, %reg only at this time for SCFI.
234 Although all three ('and', 'or' , 'xor') make the destination reg
235 untraceable, 'and' op is handled but not 'or' / 'xor' because we will look
236 into supporting the DRAP pattern at some point. Other opcodes ('adc',
237 'sbb' and 'cmp') are not generated here either. The ginsn representation
238 does not have support for the latter three opcodes; GINSN_TYPE_OTHER may
239 be added for these after x86_ginsn_unhandled () invocation if the
240 destination register is REG_SP or REG_FP. */
241 if (i.tm.extension_opcode == 5)
242 ginsn_func = ginsn_new_sub;
243 else if (i.tm.extension_opcode == 4)
244 ginsn_func = ginsn_new_and;
245 else if (i.tm.extension_opcode == 0)
246 ginsn_func = ginsn_new_add;
247 else
248 return ginsn;
250 /* TBD_GINSN_REPRESENTATION_LIMIT: There is no representation for when a
251 symbol is used as an operand, like so:
252 addq $simd_cmp_op+8, %rdx
253 Skip generating any ginsn for this. */
254 if (i.imm_operands == 1
255 && i.op[0].imms->X_op != O_constant)
256 return ginsn;
258 /* addq $1, symbol
259 addq $1, -16(%rbp)
260 These are not of interest for SCFI. Also, TBD_GINSN_GEN_NOT_SCFI. */
261 if (i.mem_operands == 1)
262 return ginsn;
264 /* 8/16/32-bit op size makes the destination reg untraceable for SCFI.
265 Deal with this via the x86_ginsn_unhandled () code path. */
266 if (i.suffix != QWORD_MNEM_SUFFIX)
267 return ginsn;
269 gas_assert (i.imm_operands == 1);
270 src_imm = i.op[0].imms->X_add_number;
271 /* The second operand may be a register or indirect access. For SCFI, only
272 the case when the second opnd is a register is interesting. Revisit this
273 if generating ginsns for a different gen mode TBD_GINSN_GEN_NOT_SCFI. */
274 if (i.reg_operands == 1)
276 dw2_regnum = ginsn_dw2_regnum (i.op[1].regs);
277 /* For ginsn, keep the imm as second src operand. */
278 ginsn = ginsn_func (insn_end_sym, true,
279 src_type, dw2_regnum, 0,
280 GINSN_SRC_IMM, 0, src_imm,
281 dst_type, dw2_regnum, 0);
283 ginsn_set_where (ginsn);
286 return ginsn;
289 /* Create ginsn(s) for MOV operations.
291 The generated ginsns corresponding to mov with indirect access to memory
292 (src or dest) suffer with loss of information: when both index and base
293 registers are at play, only base register gets conveyed in ginsn. Note
294 this TBD_GINSN_GEN_NOT_SCFI. */
296 static ginsnS *
297 x86_ginsn_move (const symbolS *insn_end_sym)
299 ginsnS *ginsn = NULL;
300 unsigned int dst_reg;
301 unsigned int src_reg;
302 offsetT src_disp = 0;
303 offsetT dst_disp = 0;
304 const reg_entry *dst = NULL;
305 const reg_entry *src = NULL;
306 uint16_t opcode = i.tm.base_opcode;
307 enum ginsn_src_type src_type = GINSN_SRC_REG;
308 enum ginsn_dst_type dst_type = GINSN_DST_REG;
310 /* mov %reg, symbol or mov symbol, %reg.
311 Not of interest for SCFI. Also, TBD_GINSN_GEN_NOT_SCFI. */
312 if (i.mem_operands == 1 && !i.base_reg && !i.index_reg)
313 return ginsn;
315 /* 8/16/32-bit op size makes the destination reg untraceable for SCFI.
316 Handle mov reg, reg only. mov to or from a memory operand will make
317 dest reg, when present, untraceable, irrespective of the op size. */
318 if (i.reg_operands == 2 && i.suffix != QWORD_MNEM_SUFFIX)
319 return ginsn;
321 gas_assert (i.tm.opcode_space == SPACE_BASE);
322 if (opcode == 0x8b || opcode == 0x8a)
324 /* mov disp(%reg), %reg. */
325 if (i.mem_operands)
327 src = (i.base_reg) ? i.base_reg : i.index_reg;
328 if (i.disp_operands == 1)
329 src_disp = i.op[0].disps->X_add_number;
330 src_type = GINSN_SRC_INDIRECT;
332 else
333 src = i.op[0].regs;
335 dst = i.op[1].regs;
337 else if (opcode == 0x89 || opcode == 0x88)
339 /* mov %reg, disp(%reg). */
340 src = i.op[0].regs;
341 if (i.mem_operands)
343 dst = (i.base_reg) ? i.base_reg : i.index_reg;
344 if (i.disp_operands == 1)
345 dst_disp = i.op[1].disps->X_add_number;
346 dst_type = GINSN_DST_INDIRECT;
348 else
349 dst = i.op[1].regs;
352 src_reg = ginsn_dw2_regnum (src);
353 dst_reg = ginsn_dw2_regnum (dst);
355 ginsn = ginsn_new_mov (insn_end_sym, true,
356 src_type, src_reg, src_disp,
357 dst_type, dst_reg, dst_disp);
358 ginsn_set_where (ginsn);
360 return ginsn;
363 /* Generate appropriate ginsn for lea.
365 Unhandled sub-cases (marked with TBD_GINSN_GEN_NOT_SCFI) also suffer with
366 some loss of information in the final ginsn chosen eventually (type
367 GINSN_TYPE_OTHER). But this is fine for now for GINSN_GEN_SCFI generation
368 mode. */
370 static ginsnS *
371 x86_ginsn_lea (const symbolS *insn_end_sym)
373 offsetT src_disp = 0;
374 ginsnS *ginsn = NULL;
375 unsigned int src1_reg;
376 const reg_entry *src1;
377 offsetT index_scale;
378 unsigned int dst_reg;
379 bool index_regiz_p;
381 if ((!i.base_reg) != (!i.index_reg || i.index_reg->reg_num == RegIZ))
383 /* lea disp(%base), %dst or lea disp(,%index,imm), %dst.
384 Either index_reg or base_reg exists, but not both. Further, as per
385 above, the case when just %index exists but is equal to RegIZ is
386 excluded. If not excluded, a GINSN_TYPE_MOV of %rsi
387 (GINSN_DW2_REGNUM_RSI_DUMMY) to %dst will be generated by this block.
388 Such a mov ginsn is imprecise; so, exclude now and generate
389 GINSN_TYPE_OTHER instead later via the x86_ginsn_unhandled ().
390 Excluding other cases is required due to
391 TBD_GINSN_REPRESENTATION_LIMIT. */
393 index_scale = i.log2_scale_factor;
394 index_regiz_p = i.index_reg && i.index_reg->reg_num == RegIZ;
395 src1 = i.base_reg ? i.base_reg : i.index_reg;
396 src1_reg = ginsn_dw2_regnum (src1);
397 dst_reg = ginsn_dw2_regnum (i.op[1].regs);
398 /* It makes sense to represent a scale factor of 1 precisely here
399 (i.e., not using GINSN_TYPE_OTHER, but rather similar to the
400 base-without-index case). A non-zero scale factor is still OK if
401 the index reg is zero reg.
402 However, skip from here the case when disp has a symbol instead.
403 TBD_GINSN_REPRESENTATION_LIMIT. */
404 if ((!index_scale || index_regiz_p)
405 && (!i.disp_operands || i.op[0].disps->X_op == O_constant))
407 if (i.disp_operands)
408 src_disp = i.op[0].disps->X_add_number;
410 if (src_disp)
411 /* Generate an ADD ginsn. */
412 ginsn = ginsn_new_add (insn_end_sym, true,
413 GINSN_SRC_REG, src1_reg, 0,
414 GINSN_SRC_IMM, 0, src_disp,
415 GINSN_DST_REG, dst_reg, 0);
416 else
417 /* Generate a MOV ginsn. */
418 ginsn = ginsn_new_mov (insn_end_sym, true,
419 GINSN_SRC_REG, src1_reg, 0,
420 GINSN_DST_REG, dst_reg, 0);
422 ginsn_set_where (ginsn);
425 /* Skip handling other cases here,
426 - when (i.index_reg && i.base_reg) is true,
427 e.g., lea disp(%base,%index,imm), %dst
428 We do not have a ginsn representation for multiply.
429 - or, when (!i.index_reg && !i.base_reg) is true,
430 e.g., lea symbol, %dst
431 Not a frequent pattern. If %dst is a register of interest, the user is
432 likely to use a MOV op anyway.
433 Deal with these via the x86_ginsn_unhandled () code path to generate
434 GINSN_TYPE_OTHER when necessary. TBD_GINSN_GEN_NOT_SCFI. */
436 return ginsn;
439 static ginsnS *
440 x86_ginsn_jump (const symbolS *insn_end_sym, bool cond_p)
442 ginsnS *ginsn = NULL;
443 const symbolS *src_symbol;
444 ginsnS * (*ginsn_func) (const symbolS *sym, bool real_p,
445 enum ginsn_src_type src_type, unsigned int src_reg,
446 const symbolS *src_ginsn_sym);
448 gas_assert (i.disp_operands == 1);
450 ginsn_func = cond_p ? ginsn_new_jump_cond : ginsn_new_jump;
451 if (i.op[0].disps->X_op == O_symbol && !i.op[0].disps->X_add_number)
453 src_symbol = i.op[0].disps->X_add_symbol;
454 ginsn = ginsn_func (insn_end_sym, true,
455 GINSN_SRC_SYMBOL, 0, src_symbol);
457 ginsn_set_where (ginsn);
459 else
461 /* A non-zero addend in jump/JCC target makes control-flow tracking
462 difficult. Skip SCFI for now. */
463 as_bad (_("SCFI: `%s' insn with non-zero addend to sym not supported"),
464 cond_p ? "JCC" : "jmp");
465 return ginsn;
468 return ginsn;
471 static ginsnS *
472 x86_ginsn_indirect_branch (const symbolS *insn_end_sym)
474 ginsnS *ginsn = NULL;
475 const reg_entry *mem_reg;
476 unsigned int dw2_regnum;
478 ginsnS * (*ginsn_func) (const symbolS *sym, bool real_p,
479 enum ginsn_src_type src_type, unsigned int src_reg,
480 const symbolS *src_ginsn_sym);
482 /* Other cases are not expected. */
483 gas_assert (i.tm.extension_opcode == 4 || i.tm.extension_opcode == 2);
485 if (i.tm.extension_opcode == 4)
486 /* 0xFF /4 (jmp r/m). */
487 ginsn_func = ginsn_new_jump;
488 else if (i.tm.extension_opcode == 2)
489 /* 0xFF /2 (call r/m). */
490 ginsn_func = ginsn_new_call;
492 if (i.reg_operands)
494 dw2_regnum = ginsn_dw2_regnum (i.op[0].regs);
495 ginsn = ginsn_func (insn_end_sym, true,
496 GINSN_SRC_REG, dw2_regnum, NULL);
497 ginsn_set_where (ginsn);
499 else if (i.mem_operands)
501 /* Handle jump/call near, absolute indirect, address.
502 E.g., jmp/call *imm(%rN), jmp/call *sym(,%rN,imm)
503 or jmp/call *sym(%rN) etc. */
504 mem_reg = i.base_reg ? i.base_reg : i.index_reg;
505 /* Generate a ginsn, even if it is with TBD_GINSN_INFO_LOSS. Otherwise,
506 the user gets the impression of missing functionality due to this
507 being a COFI and alerted for via the x86_ginsn_unhandled () workflow
508 as unhandled operation (which can be misleading for users).
510 Indirect branches make the code block ineligible for SCFI; Hence, an
511 approximate ginsn will not affect SCFI correctness:
512 - Use dummy register if no base or index
513 - Skip symbol information, if any.
514 Note this case of TBD_GINSN_GEN_NOT_SCFI. */
515 dw2_regnum = (mem_reg
516 ? ginsn_dw2_regnum (mem_reg)
517 : GINSN_DW2_REGNUM_RSI_DUMMY);
518 ginsn = ginsn_func (insn_end_sym, true,
519 GINSN_SRC_REG, dw2_regnum, NULL);
520 ginsn_set_where (ginsn);
523 return ginsn;
526 static ginsnS *
527 x86_ginsn_enter (const symbolS *insn_end_sym)
529 ginsnS *ginsn = NULL;
530 ginsnS *ginsn_next = NULL;
531 ginsnS *ginsn_last = NULL;
532 /* In 64-bit mode, the default stack update size is 8 bytes. */
533 int stack_opnd_size = 8;
535 gas_assert (i.imm_operands == 2);
537 /* For non-zero size operands, bail out as untraceable for SCFI. */
538 if (i.op[0].imms->X_op != O_constant || i.op[0].imms->X_add_symbol != 0
539 || i.op[1].imms->X_op != O_constant || i.op[1].imms->X_add_symbol != 0)
541 as_bad ("SCFI: enter insn with non-zero operand not supported");
542 return ginsn;
545 /* Check if this is a 16-bit op. */
546 if (ginsn_opsize_prefix_p ())
547 stack_opnd_size = 2;
549 /* If the nesting level is 0, the processor pushes the frame pointer from
550 the BP/EBP/RBP register onto the stack, copies the current stack
551 pointer from the SP/ESP/RSP register into the BP/EBP/RBP register, and
552 loads the SP/ESP/RSP register with the current stack-pointer value
553 minus the value in the size operand. */
554 ginsn = ginsn_new_sub (insn_end_sym, false,
555 GINSN_SRC_REG, REG_SP, 0,
556 GINSN_SRC_IMM, 0, stack_opnd_size,
557 GINSN_DST_REG, REG_SP, 0);
558 ginsn_set_where (ginsn);
559 ginsn_next = ginsn_new_store (insn_end_sym, false,
560 GINSN_SRC_REG, REG_FP,
561 GINSN_DST_INDIRECT, REG_SP, 0);
562 ginsn_set_where (ginsn_next);
563 gas_assert (!ginsn_link_next (ginsn, ginsn_next));
564 ginsn_last = ginsn_new_mov (insn_end_sym, false,
565 GINSN_SRC_REG, REG_SP, 0,
566 GINSN_DST_REG, REG_FP, 0);
567 ginsn_set_where (ginsn_last);
568 gas_assert (!ginsn_link_next (ginsn_next, ginsn_last));
570 return ginsn;
573 static ginsnS *
574 x86_ginsn_leave (const symbolS *insn_end_sym)
576 ginsnS *ginsn = NULL;
577 ginsnS *ginsn_next = NULL;
578 ginsnS *ginsn_last = NULL;
579 /* In 64-bit mode, the default stack update size is 8 bytes. */
580 int stack_opnd_size = 8;
582 /* Check if this is a 16-bit op. */
583 if (ginsn_opsize_prefix_p ())
584 stack_opnd_size = 2;
586 /* The 'leave' instruction copies the contents of the RBP register
587 into the RSP register to release all stack space allocated to the
588 procedure. */
589 ginsn = ginsn_new_mov (insn_end_sym, false,
590 GINSN_SRC_REG, REG_FP, 0,
591 GINSN_DST_REG, REG_SP, 0);
592 ginsn_set_where (ginsn);
593 /* Then it restores the old value of the RBP register from the stack. */
594 ginsn_next = ginsn_new_load (insn_end_sym, false,
595 GINSN_SRC_INDIRECT, REG_SP, 0,
596 GINSN_DST_REG, REG_FP);
597 ginsn_set_where (ginsn_next);
598 gas_assert (!ginsn_link_next (ginsn, ginsn_next));
599 ginsn_last = ginsn_new_add (insn_end_sym, false,
600 GINSN_SRC_REG, REG_SP, 0,
601 GINSN_SRC_IMM, 0, stack_opnd_size,
602 GINSN_DST_REG, REG_SP, 0);
603 ginsn_set_where (ginsn_next);
604 gas_assert (!ginsn_link_next (ginsn_next, ginsn_last));
606 return ginsn;
609 /* Check if an instruction is whitelisted.
611 Some instructions may appear with REG_SP or REG_FP as destination, because
612 which they are deemed 'interesting' for SCFI. Whitelist them here if they
613 do not affect SCFI correctness. */
615 static bool
616 x86_ginsn_safe_to_skip_p (void)
618 bool skip_p = false;
619 uint16_t opcode = i.tm.base_opcode;
621 switch (opcode)
623 case 0x80:
624 case 0x81:
625 case 0x83:
626 if (i.tm.opcode_space != SPACE_BASE)
627 break;
628 /* cmp imm, reg/rem. */
629 if (i.tm.extension_opcode == 7)
630 skip_p = true;
631 break;
633 case 0x38:
634 case 0x39:
635 case 0x3a:
636 case 0x3b:
637 if (i.tm.opcode_space != SPACE_BASE)
638 break;
639 /* cmp imm/reg/mem, reg/rem. */
640 skip_p = true;
641 break;
643 case 0xf6:
644 case 0xf7:
645 case 0x84:
646 case 0x85:
647 /* test imm/reg/mem, reg/mem. */
648 if (i.tm.opcode_space != SPACE_BASE)
649 break;
650 skip_p = true;
651 break;
653 default:
654 break;
657 return skip_p;
660 #define X86_GINSN_UNHANDLED_NONE 0
661 #define X86_GINSN_UNHANDLED_DEST_REG 1
662 #define X86_GINSN_UNHANDLED_CFG 2
663 #define X86_GINSN_UNHANDLED_STACKOP 3
664 #define X86_GINSN_UNHANDLED_UNEXPECTED 4
666 /* Check the input insn for its impact on the correctness of the synthesized
667 CFI. Returns an error code to the caller. */
669 static int
670 x86_ginsn_unhandled (void)
672 int err = X86_GINSN_UNHANDLED_NONE;
673 const reg_entry *reg_op;
674 unsigned int dw2_regnum;
676 /* Keep an eye out for instructions affecting control flow. */
677 if (i.tm.opcode_modifier.jump)
678 err = X86_GINSN_UNHANDLED_CFG;
679 /* Also, for any instructions involving an implicit update to the stack
680 pointer. */
681 else if (i.tm.opcode_modifier.operandconstraint == IMPLICIT_STACK_OP)
682 err = X86_GINSN_UNHANDLED_STACKOP;
683 /* Finally, also check if the missed instructions are affecting REG_SP or
684 REG_FP. The destination operand is the last at all stages of assembly
685 (due to following AT&T syntax layout in the internal representation). In
686 case of Intel syntax input, this still remains true as swap_operands ()
687 is done by now.
688 PS: These checks do not involve index / base reg, as indirect memory
689 accesses via REG_SP or REG_FP do not affect SCFI correctness.
690 (Also note these instructions are candidates for other ginsn generation
691 modes in future. TBD_GINSN_GEN_NOT_SCFI.) */
692 else if (i.operands && i.reg_operands
693 && !(i.flags[i.operands - 1] & Operand_Mem))
695 reg_op = i.op[i.operands - 1].regs;
696 if (reg_op)
698 dw2_regnum = ginsn_dw2_regnum (reg_op);
699 if (dw2_regnum == REG_SP || dw2_regnum == REG_FP)
700 err = X86_GINSN_UNHANDLED_DEST_REG;
702 else
703 /* Something unexpected. Indicate to caller. */
704 err = X86_GINSN_UNHANDLED_UNEXPECTED;
707 return err;
710 /* Generate one or more generic GAS instructions, a.k.a, ginsns for the current
711 machine instruction.
713 Returns the head of linked list of ginsn(s) added, if success; Returns NULL
714 if failure.
716 The input ginsn_gen_mode GMODE determines the set of minimal necessary
717 ginsns necessary for correctness of any passes applicable for that mode.
718 For supporting the GINSN_GEN_SCFI generation mode, following is the list of
719 machine instructions that must be translated into the corresponding ginsns
720 to ensure correctness of SCFI:
721 - All instructions affecting the two registers that could potentially
722 be used as the base register for CFA tracking. For SCFI, the base
723 register for CFA tracking is limited to REG_SP and REG_FP only for
724 now.
725 - All change of flow instructions: conditional and unconditional branches,
726 call and return from functions.
727 - All instructions that can potentially be a register save / restore
728 operation.
729 - All instructions that perform stack manipulation implicitly: the CALL,
730 RET, PUSH, POP, ENTER, and LEAVE instructions.
732 The function currently supports GINSN_GEN_SCFI ginsn generation mode only.
733 To support other generation modes will require work on this target-specific
734 process of creation of ginsns:
735 - Some of such places are tagged with TBD_GINSN_GEN_NOT_SCFI to serve as
736 possible starting points.
737 - Also note that ginsn representation may need enhancements. Specifically,
738 note some TBD_GINSN_INFO_LOSS and TBD_GINSN_REPRESENTATION_LIMIT markers.
741 static ginsnS *
742 x86_ginsn_new (const symbolS *insn_end_sym, enum ginsn_gen_mode gmode)
744 int err = 0;
745 uint16_t opcode;
746 unsigned int dw2_regnum;
747 const reg_entry *mem_reg;
748 ginsnS *ginsn = NULL;
749 ginsnS *ginsn_next = NULL;
750 /* In 64-bit mode, the default stack update size is 8 bytes. */
751 int stack_opnd_size = 8;
753 /* Currently supports generation of selected ginsns, sufficient for
754 the use-case of SCFI only. */
755 if (gmode != GINSN_GEN_SCFI)
756 return ginsn;
758 opcode = i.tm.base_opcode;
760 /* Until it is clear how to handle APX NDD and other new opcodes, disallow
761 them from SCFI. */
762 if (is_apx_rex2_encoding ()
763 || (i.tm.opcode_modifier.evex && is_apx_evex_encoding ()))
765 as_bad (_("SCFI: unsupported APX op %#x may cause incorrect CFI"),
766 opcode);
767 return ginsn;
770 switch (opcode)
773 /* Add opcodes 0x0/0x2 and sub opcodes 0x28/0x2a (with opcode_space
774 SPACE_BASE) are 8-bit ops. While they are relevant for SCFI
775 correctness, skip handling them here and use the x86_ginsn_unhandled
776 code path to generate GINSN_TYPE_OTHER when necessary. */
778 case 0x1: /* add reg, reg/mem. */
779 case 0x29: /* sub reg, reg/mem. */
780 if (i.tm.opcode_space != SPACE_BASE)
781 break;
782 ginsn = x86_ginsn_addsub_reg_mem (insn_end_sym);
783 break;
785 case 0x3: /* add reg/mem, reg. */
786 case 0x2b: /* sub reg/mem, reg. */
787 if (i.tm.opcode_space != SPACE_BASE)
788 break;
789 ginsn = x86_ginsn_addsub_mem_reg (insn_end_sym);
790 break;
792 case 0xa0: /* push fs. */
793 case 0xa8: /* push gs. */
794 /* push fs / push gs have opcode_space == SPACE_0F. */
795 if (i.tm.opcode_space != SPACE_0F)
796 break;
797 dw2_regnum = ginsn_dw2_regnum (i.op[0].regs);
798 /* Check if operation size is 16-bit. */
799 if (ginsn_opsize_prefix_p ())
800 stack_opnd_size = 2;
801 ginsn = ginsn_new_sub (insn_end_sym, false,
802 GINSN_SRC_REG, REG_SP, 0,
803 GINSN_SRC_IMM, 0, stack_opnd_size,
804 GINSN_DST_REG, REG_SP, 0);
805 ginsn_set_where (ginsn);
806 ginsn_next = ginsn_new_store (insn_end_sym, false,
807 GINSN_SRC_REG, dw2_regnum,
808 GINSN_DST_INDIRECT, REG_SP, 0);
809 ginsn_set_where (ginsn_next);
810 gas_assert (!ginsn_link_next (ginsn, ginsn_next));
811 break;
813 case 0xa1: /* pop fs. */
814 case 0xa9: /* pop gs. */
815 /* pop fs / pop gs have opcode_space == SPACE_0F. */
816 if (i.tm.opcode_space != SPACE_0F)
817 break;
818 dw2_regnum = ginsn_dw2_regnum (i.op[0].regs);
819 /* Check if operation size is 16-bit. */
820 if (ginsn_opsize_prefix_p ())
821 stack_opnd_size = 2;
822 ginsn = ginsn_new_load (insn_end_sym, false,
823 GINSN_SRC_INDIRECT, REG_SP, 0,
824 GINSN_DST_REG, dw2_regnum);
825 ginsn_set_where (ginsn);
826 ginsn_next = ginsn_new_add (insn_end_sym, false,
827 GINSN_SRC_REG, REG_SP, 0,
828 GINSN_SRC_IMM, 0, stack_opnd_size,
829 GINSN_DST_REG, REG_SP, 0);
830 ginsn_set_where (ginsn_next);
831 gas_assert (!ginsn_link_next (ginsn, ginsn_next));
832 break;
834 case 0x50 ... 0x57:
835 if (i.tm.opcode_space != SPACE_BASE)
836 break;
837 /* push reg. */
838 dw2_regnum = ginsn_dw2_regnum (i.op[0].regs);
839 /* Check if operation size is 16-bit. */
840 if (ginsn_opsize_prefix_p ())
841 stack_opnd_size = 2;
842 ginsn = ginsn_new_sub (insn_end_sym, false,
843 GINSN_SRC_REG, REG_SP, 0,
844 GINSN_SRC_IMM, 0, stack_opnd_size,
845 GINSN_DST_REG, REG_SP, 0);
846 ginsn_set_where (ginsn);
847 ginsn_next = ginsn_new_store (insn_end_sym, false,
848 GINSN_SRC_REG, dw2_regnum,
849 GINSN_DST_INDIRECT, REG_SP, 0);
850 ginsn_set_where (ginsn_next);
851 gas_assert (!ginsn_link_next (ginsn, ginsn_next));
852 break;
854 case 0x58 ... 0x5f:
855 if (i.tm.opcode_space != SPACE_BASE)
856 break;
857 /* pop reg. */
858 dw2_regnum = ginsn_dw2_regnum (i.op[0].regs);
859 ginsn = ginsn_new_load (insn_end_sym, false,
860 GINSN_SRC_INDIRECT, REG_SP, 0,
861 GINSN_DST_REG, dw2_regnum);
862 ginsn_set_where (ginsn);
863 /* Check if operation size is 16-bit. */
864 if (ginsn_opsize_prefix_p ())
865 stack_opnd_size = 2;
866 ginsn_next = ginsn_new_add (insn_end_sym, false,
867 GINSN_SRC_REG, REG_SP, 0,
868 GINSN_SRC_IMM, 0, stack_opnd_size,
869 GINSN_DST_REG, REG_SP, 0);
870 ginsn_set_where (ginsn_next);
871 gas_assert (!ginsn_link_next (ginsn, ginsn_next));
872 break;
874 case 0x6a: /* push imm8. */
875 case 0x68: /* push imm16/imm32. */
876 if (i.tm.opcode_space != SPACE_BASE)
877 break;
878 /* Check if operation size is 16-bit. */
879 if (ginsn_opsize_prefix_p ())
880 stack_opnd_size = 2;
881 /* Skip getting the value of imm from machine instruction
882 because this is not important for SCFI. */
883 ginsn = ginsn_new_sub (insn_end_sym, false,
884 GINSN_SRC_REG, REG_SP, 0,
885 GINSN_SRC_IMM, 0, stack_opnd_size,
886 GINSN_DST_REG, REG_SP, 0);
887 ginsn_set_where (ginsn);
888 ginsn_next = ginsn_new_store (insn_end_sym, false,
889 GINSN_SRC_IMM, 0,
890 GINSN_DST_INDIRECT, REG_SP, 0);
891 ginsn_set_where (ginsn_next);
892 gas_assert (!ginsn_link_next (ginsn, ginsn_next));
893 break;
895 /* PS: Opcodes 0x80 ... 0x8f with opcode_space SPACE_0F are present
896 only after relaxation. They do not need to be handled for ginsn
897 creation. */
898 case 0x70 ... 0x7f:
899 if (i.tm.opcode_space != SPACE_BASE)
900 break;
901 ginsn = x86_ginsn_jump (insn_end_sym, true);
902 break;
904 case 0x80:
905 case 0x81:
906 case 0x83:
907 if (i.tm.opcode_space != SPACE_BASE)
908 break;
909 ginsn = x86_ginsn_alu_imm (insn_end_sym);
910 break;
912 case 0x8a: /* mov r/m8, r8. */
913 case 0x8b: /* mov r/m(16/32/64), r(16/32/64). */
914 case 0x88: /* mov r8, r/m8. */
915 case 0x89: /* mov r(16/32/64), r/m(16/32/64). */
916 if (i.tm.opcode_space != SPACE_BASE)
917 break;
918 ginsn = x86_ginsn_move (insn_end_sym);
919 break;
921 case 0x8d:
922 if (i.tm.opcode_space != SPACE_BASE)
923 break;
924 /* lea disp(%base,%index,imm), %dst. */
925 ginsn = x86_ginsn_lea (insn_end_sym);
926 break;
928 case 0x8f:
929 if (i.tm.opcode_space != SPACE_BASE)
930 break;
931 /* pop to reg/mem. */
932 if (i.mem_operands)
934 mem_reg = (i.base_reg) ? i.base_reg : i.index_reg;
935 /* Use dummy register if no base or index. Unlike other opcodes,
936 ginsns must be generated as this affect stack pointer. */
937 dw2_regnum = (mem_reg
938 ? ginsn_dw2_regnum (mem_reg)
939 : GINSN_DW2_REGNUM_RSI_DUMMY);
941 else
942 dw2_regnum = ginsn_dw2_regnum (i.op[0].regs);
943 ginsn = ginsn_new_load (insn_end_sym, false,
944 GINSN_SRC_INDIRECT, REG_SP, 0,
945 GINSN_DST_INDIRECT, dw2_regnum);
946 ginsn_set_where (ginsn);
947 /* Check if operation size is 16-bit. */
948 if (ginsn_opsize_prefix_p ())
949 stack_opnd_size = 2;
950 ginsn_next = ginsn_new_add (insn_end_sym, false,
951 GINSN_SRC_REG, REG_SP, 0,
952 GINSN_SRC_IMM, 0, stack_opnd_size,
953 GINSN_DST_REG, REG_SP, 0);
954 ginsn_set_where (ginsn_next);
955 gas_assert (!ginsn_link_next (ginsn, ginsn_next));
956 break;
958 case 0x9c:
959 if (i.tm.opcode_space != SPACE_BASE)
960 break;
961 /* pushf / pushfq. */
962 /* Check if operation size is 16-bit. */
963 if (ginsn_opsize_prefix_p ())
964 stack_opnd_size = 2;
965 ginsn = ginsn_new_sub (insn_end_sym, false,
966 GINSN_SRC_REG, REG_SP, 0,
967 GINSN_SRC_IMM, 0, stack_opnd_size,
968 GINSN_DST_REG, REG_SP, 0);
969 ginsn_set_where (ginsn);
970 /* FIXME - hardcode the actual DWARF reg number value. As for SCFI
971 correctness, although this behaves simply a placeholder value; its
972 just clearer if the value is correct. */
973 dw2_regnum = GINSN_DW2_REGNUM_EFLAGS;
974 ginsn_next = ginsn_new_store (insn_end_sym, false,
975 GINSN_SRC_REG, dw2_regnum,
976 GINSN_DST_INDIRECT, REG_SP, 0);
977 ginsn_set_where (ginsn_next);
978 gas_assert (!ginsn_link_next (ginsn, ginsn_next));
979 break;
981 case 0x9d:
982 if (i.tm.opcode_space != SPACE_BASE)
983 break;
984 /* popf / popfq. */
985 /* Check if operation size is 16-bit. */
986 if (ginsn_opsize_prefix_p ())
987 stack_opnd_size = 2;
988 /* FIXME - hardcode the actual DWARF reg number value. As for SCFI
989 correctness, although this behaves simply a placeholder value; its
990 just clearer if the value is correct. */
991 dw2_regnum = GINSN_DW2_REGNUM_EFLAGS;
992 ginsn = ginsn_new_load (insn_end_sym, false,
993 GINSN_SRC_INDIRECT, REG_SP, 0,
994 GINSN_DST_REG, dw2_regnum);
995 ginsn_set_where (ginsn);
996 ginsn_next = ginsn_new_add (insn_end_sym, false,
997 GINSN_SRC_REG, REG_SP, 0,
998 GINSN_SRC_IMM, 0, stack_opnd_size,
999 GINSN_DST_REG, REG_SP, 0);
1000 ginsn_set_where (ginsn_next);
1001 gas_assert (!ginsn_link_next (ginsn, ginsn_next));
1002 break;
1004 case 0xff:
1005 if (i.tm.opcode_space != SPACE_BASE)
1006 break;
1007 /* push from reg/mem. */
1008 if (i.tm.extension_opcode == 6)
1010 /* Check if operation size is 16-bit. */
1011 if (ginsn_opsize_prefix_p ())
1012 stack_opnd_size = 2;
1013 ginsn = ginsn_new_sub (insn_end_sym, false,
1014 GINSN_SRC_REG, REG_SP, 0,
1015 GINSN_SRC_IMM, 0, stack_opnd_size,
1016 GINSN_DST_REG, REG_SP, 0);
1017 ginsn_set_where (ginsn);
1018 if (i.mem_operands)
1020 mem_reg = (i.base_reg) ? i.base_reg : i.index_reg;
1021 /* Use dummy register if no base or index. Unlike other opcodes,
1022 ginsns must be generated as this affect stack pointer. */
1023 dw2_regnum = (mem_reg
1024 ? ginsn_dw2_regnum (mem_reg)
1025 : GINSN_DW2_REGNUM_RSI_DUMMY);
1027 else
1028 dw2_regnum = ginsn_dw2_regnum (i.op[0].regs);
1029 ginsn_next = ginsn_new_store (insn_end_sym, false,
1030 GINSN_SRC_INDIRECT, dw2_regnum,
1031 GINSN_DST_INDIRECT, REG_SP, 0);
1032 ginsn_set_where (ginsn_next);
1033 gas_assert (!ginsn_link_next (ginsn, ginsn_next));
1035 else if (i.tm.extension_opcode == 4 || i.tm.extension_opcode == 2)
1036 ginsn = x86_ginsn_indirect_branch (insn_end_sym);
1037 break;
1039 case 0xc2: /* ret imm16. */
1040 case 0xc3: /* ret. */
1041 if (i.tm.opcode_space != SPACE_BASE)
1042 break;
1043 /* Near ret. */
1044 ginsn = ginsn_new_return (insn_end_sym, true);
1045 ginsn_set_where (ginsn);
1046 break;
1048 case 0xc8:
1049 if (i.tm.opcode_space != SPACE_BASE)
1050 break;
1051 /* enter. */
1052 ginsn = x86_ginsn_enter (insn_end_sym);
1053 break;
1055 case 0xc9:
1056 if (i.tm.opcode_space != SPACE_BASE)
1057 break;
1058 /* leave. */
1059 ginsn = x86_ginsn_leave (insn_end_sym);
1060 break;
1062 case 0xe0 ... 0xe2: /* loop / loope / loopne. */
1063 case 0xe3: /* jecxz / jrcxz. */
1064 if (i.tm.opcode_space != SPACE_BASE)
1065 break;
1066 ginsn = x86_ginsn_jump (insn_end_sym, true);
1067 ginsn_set_where (ginsn);
1068 break;
1070 case 0xe8:
1071 if (i.tm.opcode_space != SPACE_BASE)
1072 break;
1073 /* PS: SCFI machinery does not care about which func is being
1074 called. OK to skip that info. */
1075 ginsn = ginsn_new_call (insn_end_sym, true,
1076 GINSN_SRC_SYMBOL, 0, NULL);
1077 ginsn_set_where (ginsn);
1078 break;
1080 /* PS: opcode 0xe9 appears only after relaxation. Skip here. */
1081 case 0xeb:
1082 /* If opcode_space != SPACE_BASE, this is not a jmp insn. Skip it
1083 for GINSN_GEN_SCFI. */
1084 if (i.tm.opcode_space != SPACE_BASE)
1085 break;
1086 /* Unconditional jmp. */
1087 ginsn = x86_ginsn_jump (insn_end_sym, false);
1088 ginsn_set_where (ginsn);
1089 break;
1091 default:
1092 /* TBD_GINSN_GEN_NOT_SCFI: Skip all other opcodes uninteresting for
1093 GINSN_GEN_SCFI mode. */
1094 break;
1097 if (!ginsn && !x86_ginsn_safe_to_skip_p ())
1099 /* For all unhandled insns that are not whitelisted, check that they do
1100 not impact SCFI correctness. */
1101 err = x86_ginsn_unhandled ();
1102 switch (err)
1104 case X86_GINSN_UNHANDLED_NONE:
1105 break;
1106 case X86_GINSN_UNHANDLED_DEST_REG:
1107 /* Not all writes to REG_FP are harmful in context of SCFI. Simply
1108 generate a GINSN_TYPE_OTHER with destination set to the
1109 appropriate register. The SCFI machinery will bail out if this
1110 ginsn affects SCFI correctness. */
1111 dw2_regnum = ginsn_dw2_regnum (i.op[i.operands - 1].regs);
1112 ginsn = ginsn_new_other (insn_end_sym, true,
1113 GINSN_SRC_IMM, 0,
1114 GINSN_SRC_IMM, 0,
1115 GINSN_DST_REG, dw2_regnum);
1116 ginsn_set_where (ginsn);
1117 break;
1118 case X86_GINSN_UNHANDLED_CFG:
1119 case X86_GINSN_UNHANDLED_STACKOP:
1120 as_bad (_("SCFI: unhandled op %#x may cause incorrect CFI"), opcode);
1121 break;
1122 case X86_GINSN_UNHANDLED_UNEXPECTED:
1123 as_bad (_("SCFI: unexpected op %#x may cause incorrect CFI"),
1124 opcode);
1125 break;
1126 default:
1127 abort ();
1128 break;
1132 return ginsn;