Coverage Report

Created: 2025-06-24 06:45

/src/binutils-gdb/gas/config/tc-i386-ginsn.c
Line
Count
Source (jump to first uncovered line)
1
/* tc-i386-ginsn.c -- Ginsn generation for the x86-64 ISA
2
3
   Copyright (C) 2024-2025 Free Software Foundation, Inc.
4
5
   This file is part of GAS.
6
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.
11
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.
16
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/>.  */
20
21
/* This file contains the implementation of the ginsn creation for x86-64
22
   instructions.  */
23
24
/* DWARF register number for EFLAGS.  Used for pushf/popf insns.  */
25
0
#define GINSN_DW2_REGNUM_EFLAGS     49
26
/* DWARF register number for RSI.  Used as dummy value when RegIP/RegIZ.  */
27
0
#define GINSN_DW2_REGNUM_RSI_DUMMY  4
28
29
/* Identify the callee-saved registers in System V AMD64 ABI.  */
30
31
bool
32
x86_scfi_callee_saved_p (unsigned int dw2reg_num)
33
0
{
34
0
  if (dw2reg_num == 3 /* rbx.  */
35
0
      || dw2reg_num == REG_FP /* rbp.  */
36
0
      || dw2reg_num == REG_SP /* rsp.  */
37
0
      || (dw2reg_num >= 12 && dw2reg_num <= 15) /* r12 - r15.  */)
38
0
    return true;
39
40
0
  return false;
41
0
}
42
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.
46
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).  */
51
52
static bool
53
ginsn_opsize_prefix_p (void)
54
0
{
55
0
  return (!(i.prefix[REX_PREFIX] & REX_W) && i.prefix[DATA_PREFIX]);
56
0
}
57
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.
62
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.  */
66
67
static unsigned int
68
ginsn_dw2_regnum (const reg_entry *ireg)
69
0
{
70
0
  const reg_entry *temp = ireg;
71
0
  unsigned int dwarf_reg = Dw2Inval, idx = 0;
72
73
  /* ginsn creation is available for AMD64 abi only ATM.  Other flag_code
74
     are not expected.  */
75
0
  gas_assert (ireg && flag_code == CODE_64BIT);
76
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
0
  if (ireg->reg_num == RegIP || ireg->reg_num == RegIZ)
82
0
    return GINSN_DW2_REGNUM_RSI_DUMMY;
83
84
0
  dwarf_reg = ireg->dw2_regnum[object_64bit];
85
86
0
  if (dwarf_reg == Dw2Inval)
87
0
    {
88
0
      if (ireg <= &i386_regtab[3])
89
  /* For al, cl, dl, bl, bump over to axl, cxl, dxl, bxl respectively by
90
     adding 8.  */
91
0
  temp = ireg + 8;
92
0
      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
0
  temp = ireg + 4;
96
0
      else
97
0
  {
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
0
    gas_assert ((temp - &i386_regtab[0]) >= 0);
103
0
    idx = temp - &i386_regtab[0];
104
0
    gas_assert (idx + 32 < i386_regtab_size - 1);
105
106
0
    temp = temp + 32;
107
0
  }
108
109
0
      dwarf_reg = ginsn_dw2_regnum (temp);
110
0
    }
111
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
0
  gas_assert (dwarf_reg < Dw2Inval);
115
116
0
  return dwarf_reg;
117
0
}
118
119
static ginsnS *
120
x86_ginsn_addsub_reg_mem (const symbolS *insn_end_sym)
121
0
{
122
0
  unsigned int dw2_regnum;
123
0
  unsigned int src1_dw2_regnum;
124
0
  ginsnS *ginsn = NULL;
125
0
  ginsnS * (*ginsn_func) (const symbolS *, bool,
126
0
        enum ginsn_src_type, unsigned int, offsetT,
127
0
        enum ginsn_src_type, unsigned int, offsetT,
128
0
        enum ginsn_dst_type, unsigned int, offsetT);
129
0
  uint16_t opcode = i.tm.base_opcode;
130
131
0
  gas_assert (i.tm.opcode_space == SPACE_BASE
132
0
        && (opcode == 0x1 || opcode == 0x29));
133
0
  ginsn_func = (opcode == 0x1) ? ginsn_new_add : ginsn_new_sub;
134
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
0
  if (i.mem_operands)
138
0
    return ginsn;
139
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.  */
142
143
  /* op reg, reg/mem.  */
144
0
  src1_dw2_regnum = ginsn_dw2_regnum (i.op[0].regs);
145
  /* Of interest only when second opnd is not memory.  */
146
0
  if (i.reg_operands == 2)
147
0
    {
148
0
      dw2_regnum = ginsn_dw2_regnum (i.op[1].regs);
149
0
      ginsn = ginsn_func (insn_end_sym, true,
150
0
        GINSN_SRC_REG, src1_dw2_regnum, 0,
151
0
        GINSN_SRC_REG, dw2_regnum, 0,
152
0
        GINSN_DST_REG, dw2_regnum, 0);
153
0
      ginsn_set_where (ginsn);
154
0
    }
155
156
0
  return ginsn;
157
0
}
158
159
static ginsnS *
160
x86_ginsn_addsub_mem_reg (const symbolS *insn_end_sym)
161
0
{
162
0
  unsigned int dw2_regnum;
163
0
  unsigned int src1_dw2_regnum;
164
0
  const reg_entry *mem_reg;
165
0
  int32_t gdisp = 0;
166
0
  ginsnS *ginsn = NULL;
167
0
  ginsnS * (*ginsn_func) (const symbolS *, bool,
168
0
        enum ginsn_src_type, unsigned int, offsetT,
169
0
        enum ginsn_src_type, unsigned int, offsetT,
170
0
        enum ginsn_dst_type, unsigned int, offsetT);
171
0
  uint16_t opcode = i.tm.base_opcode;
172
173
0
  gas_assert (i.tm.opcode_space == SPACE_BASE
174
0
        && (opcode == 0x3 || opcode == 0x2b));
175
0
  ginsn_func = (opcode == 0x3) ? ginsn_new_add : ginsn_new_sub;
176
177
  /* op symbol, %reg.  */
178
0
  if (i.mem_operands && !i.base_reg && !i.index_reg)
179
0
    return ginsn;
180
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.  */
183
184
  /* op reg/mem, %reg.  */
185
0
  dw2_regnum = ginsn_dw2_regnum (i.op[1].regs);
186
187
0
  if (i.reg_operands == 2)
188
0
    {
189
0
      src1_dw2_regnum = ginsn_dw2_regnum (i.op[0].regs);
190
0
      ginsn = ginsn_func (insn_end_sym, true,
191
0
        GINSN_SRC_REG, src1_dw2_regnum, 0,
192
0
        GINSN_SRC_REG, dw2_regnum, 0,
193
0
        GINSN_DST_REG, dw2_regnum, 0);
194
0
      ginsn_set_where (ginsn);
195
0
    }
196
0
  else if (i.mem_operands)
197
0
    {
198
0
      mem_reg = (i.base_reg) ? i.base_reg : i.index_reg;
199
0
      src1_dw2_regnum = ginsn_dw2_regnum (mem_reg);
200
0
      if (i.disp_operands == 1)
201
0
  gdisp = i.op[0].disps->X_add_number;
202
0
      ginsn = ginsn_func (insn_end_sym, true,
203
0
        GINSN_SRC_INDIRECT, src1_dw2_regnum, gdisp,
204
0
        GINSN_SRC_REG, dw2_regnum, 0,
205
0
        GINSN_DST_REG, dw2_regnum, 0);
206
0
      ginsn_set_where (ginsn);
207
0
    }
208
209
0
  return ginsn;
210
0
}
211
212
static ginsnS *
213
x86_ginsn_alu_imm (const symbolS *insn_end_sym)
214
0
{
215
0
  offsetT src_imm;
216
0
  unsigned int dw2_regnum;
217
0
  ginsnS *ginsn = NULL;
218
0
  enum ginsn_src_type src_type = GINSN_SRC_REG;
219
0
  enum ginsn_dst_type dst_type = GINSN_DST_REG;
220
221
0
  ginsnS * (*ginsn_func) (const symbolS *, bool,
222
0
        enum ginsn_src_type, unsigned int, offsetT,
223
0
        enum ginsn_src_type, unsigned int, offsetT,
224
0
        enum ginsn_dst_type, unsigned int, offsetT);
225
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  */
232
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
0
  if (i.tm.extension_opcode == 5)
242
0
    ginsn_func = ginsn_new_sub;
243
0
  else if (i.tm.extension_opcode == 4)
244
0
    ginsn_func = ginsn_new_and;
245
0
  else if (i.tm.extension_opcode == 0)
246
0
    ginsn_func = ginsn_new_add;
247
0
  else
248
0
    return ginsn;
249
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
0
  if (i.imm_operands == 1
255
0
      && i.op[0].imms->X_op != O_constant)
256
0
    return ginsn;
257
258
  /* addq    $1, symbol
259
     addq    $1, -16(%rbp)
260
     These are not of interest for SCFI.  Also, TBD_GINSN_GEN_NOT_SCFI.  */
261
0
  if (i.mem_operands == 1)
262
0
    return ginsn;
263
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
0
  if (i.suffix != QWORD_MNEM_SUFFIX)
267
0
    return ginsn;
268
269
0
  gas_assert (i.imm_operands == 1);
270
0
  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
0
  if (i.reg_operands == 1)
275
0
    {
276
0
      dw2_regnum = ginsn_dw2_regnum (i.op[1].regs);
277
      /* For ginsn, keep the imm as second src operand.  */
278
0
      ginsn = ginsn_func (insn_end_sym, true,
279
0
        src_type, dw2_regnum, 0,
280
0
        GINSN_SRC_IMM, 0, src_imm,
281
0
        dst_type, dw2_regnum, 0);
282
283
0
      ginsn_set_where (ginsn);
284
0
    }
285
286
0
  return ginsn;
287
0
}
288
289
/* Create ginsn(s) for MOV operations.
290
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.  */
295
296
static ginsnS *
297
x86_ginsn_move (const symbolS *insn_end_sym)
298
0
{
299
0
  ginsnS *ginsn = NULL;
300
0
  unsigned int dst_reg;
301
0
  unsigned int src_reg;
302
0
  offsetT src_disp = 0;
303
0
  offsetT dst_disp = 0;
304
0
  const reg_entry *dst = NULL;
305
0
  const reg_entry *src = NULL;
306
0
  uint16_t opcode = i.tm.base_opcode;
307
0
  enum ginsn_src_type src_type = GINSN_SRC_REG;
308
0
  enum ginsn_dst_type dst_type = GINSN_DST_REG;
309
310
  /* mov %reg, symbol or mov symbol, %reg.
311
     Not of interest for SCFI.  Also, TBD_GINSN_GEN_NOT_SCFI.  */
312
0
  if (i.mem_operands == 1 && !i.base_reg && !i.index_reg)
313
0
    return ginsn;
314
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
0
  if (i.reg_operands == 2 && i.suffix != QWORD_MNEM_SUFFIX)
319
0
    return ginsn;
320
321
0
  gas_assert (i.tm.opcode_space == SPACE_BASE);
322
0
  if (opcode == 0x8b || opcode == 0x8a)
323
0
    {
324
      /* mov  disp(%reg), %reg.  */
325
0
      if (i.mem_operands)
326
0
  {
327
0
    src = (i.base_reg) ? i.base_reg : i.index_reg;
328
0
    if (i.disp_operands == 1)
329
0
      src_disp = i.op[0].disps->X_add_number;
330
0
    src_type = GINSN_SRC_INDIRECT;
331
0
  }
332
0
      else
333
0
  src = i.op[0].regs;
334
335
0
      dst = i.op[1].regs;
336
0
    }
337
0
  else if (opcode == 0x89 || opcode == 0x88)
338
0
    {
339
      /* mov %reg, disp(%reg).  */
340
0
      src = i.op[0].regs;
341
0
      if (i.mem_operands)
342
0
  {
343
0
    dst = (i.base_reg) ? i.base_reg : i.index_reg;
344
0
    if (i.disp_operands == 1)
345
0
      dst_disp = i.op[1].disps->X_add_number;
346
0
    dst_type = GINSN_DST_INDIRECT;
347
0
  }
348
0
      else
349
0
  dst = i.op[1].regs;
350
0
    }
351
352
0
  src_reg = ginsn_dw2_regnum (src);
353
0
  dst_reg = ginsn_dw2_regnum (dst);
354
355
0
  ginsn = ginsn_new_mov (insn_end_sym, true,
356
0
       src_type, src_reg, src_disp,
357
0
       dst_type, dst_reg, dst_disp);
358
0
  ginsn_set_where (ginsn);
359
360
0
  return ginsn;
361
0
}
362
363
/* Generate appropriate ginsn for lea.
364
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.  */
369
370
static ginsnS *
371
x86_ginsn_lea (const symbolS *insn_end_sym)
372
0
{
373
0
  offsetT src_disp = 0;
374
0
  ginsnS *ginsn = NULL;
375
0
  unsigned int src1_reg;
376
0
  const reg_entry *src1;
377
0
  offsetT index_scale;
378
0
  unsigned int dst_reg;
379
0
  bool index_regiz_p;
380
381
0
  if ((!i.base_reg) != (!i.index_reg || i.index_reg->reg_num == RegIZ))
382
0
    {
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.  */
392
393
0
      index_scale = i.log2_scale_factor;
394
0
      index_regiz_p = i.index_reg && i.index_reg->reg_num == RegIZ;
395
0
      src1 = i.base_reg ? i.base_reg : i.index_reg;
396
0
      src1_reg = ginsn_dw2_regnum (src1);
397
0
      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
0
      if ((!index_scale || index_regiz_p)
405
0
    && (!i.disp_operands || i.op[0].disps->X_op == O_constant))
406
0
  {
407
0
    if (i.disp_operands)
408
0
      src_disp = i.op[0].disps->X_add_number;
409
410
0
    if (src_disp)
411
      /* Generate an ADD ginsn.  */
412
0
      ginsn = ginsn_new_add (insn_end_sym, true,
413
0
           GINSN_SRC_REG, src1_reg, 0,
414
0
           GINSN_SRC_IMM, 0, src_disp,
415
0
           GINSN_DST_REG, dst_reg, 0);
416
0
    else
417
      /* Generate a MOV ginsn.  */
418
0
      ginsn = ginsn_new_mov (insn_end_sym, true,
419
0
           GINSN_SRC_REG, src1_reg, 0,
420
0
           GINSN_DST_REG, dst_reg, 0);
421
422
0
    ginsn_set_where (ginsn);
423
0
  }
424
0
    }
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.  */
435
436
0
  return ginsn;
437
0
}
438
439
static ginsnS *
440
x86_ginsn_jump (const symbolS *insn_end_sym, bool cond_p)
441
0
{
442
0
  ginsnS *ginsn = NULL;
443
0
  const symbolS *src_symbol;
444
0
  ginsnS * (*ginsn_func) (const symbolS *sym, bool real_p,
445
0
        enum ginsn_src_type src_type, unsigned int src_reg,
446
0
        const symbolS *src_ginsn_sym);
447
448
0
  gas_assert (i.disp_operands == 1);
449
450
0
  ginsn_func = cond_p ? ginsn_new_jump_cond : ginsn_new_jump;
451
0
  if (i.op[0].disps->X_op == O_symbol && !i.op[0].disps->X_add_number)
452
0
    {
453
0
      src_symbol = i.op[0].disps->X_add_symbol;
454
0
      ginsn = ginsn_func (insn_end_sym, true,
455
0
        GINSN_SRC_SYMBOL, 0, src_symbol);
456
457
0
      ginsn_set_where (ginsn);
458
0
    }
459
0
  else
460
0
    {
461
      /* A non-zero addend in jump/JCC target makes control-flow tracking
462
   difficult.  Skip SCFI for now.  */
463
0
      as_bad (_("SCFI: `%s' insn with non-zero addend to sym not supported"),
464
0
        cond_p ? "JCC" : "jmp");
465
0
      return ginsn;
466
0
    }
467
468
0
  return ginsn;
469
0
}
470
471
static ginsnS *
472
x86_ginsn_indirect_branch (const symbolS *insn_end_sym)
473
0
{
474
0
  ginsnS *ginsn = NULL;
475
0
  const reg_entry *mem_reg;
476
0
  unsigned int dw2_regnum;
477
478
0
  ginsnS * (*ginsn_func) (const symbolS *sym, bool real_p,
479
0
        enum ginsn_src_type src_type, unsigned int src_reg,
480
0
        const symbolS *src_ginsn_sym);
481
482
  /* Other cases are not expected.  */
483
0
  gas_assert (i.tm.extension_opcode == 4 || i.tm.extension_opcode == 2);
484
485
0
  if (i.tm.extension_opcode == 4)
486
    /* 0xFF /4 (jmp r/m).  */
487
0
    ginsn_func = ginsn_new_jump;
488
0
  else if (i.tm.extension_opcode == 2)
489
    /* 0xFF /2 (call r/m).  */
490
0
    ginsn_func = ginsn_new_call;
491
0
  else
492
0
    return ginsn;
493
494
0
  if (i.reg_operands)
495
0
    {
496
0
      dw2_regnum = ginsn_dw2_regnum (i.op[0].regs);
497
0
      ginsn = ginsn_func (insn_end_sym, true,
498
0
        GINSN_SRC_REG, dw2_regnum, NULL);
499
0
      ginsn_set_where (ginsn);
500
0
    }
501
0
  else if (i.mem_operands)
502
0
    {
503
      /* Handle jump/call near, absolute indirect, address.
504
   E.g., jmp/call *imm(%rN),  jmp/call *sym(,%rN,imm)
505
   or  jmp/call *sym(%rN) etc.  */
506
0
      mem_reg = i.base_reg ? i.base_reg : i.index_reg;
507
      /* Generate a ginsn, even if it is with TBD_GINSN_INFO_LOSS.  Otherwise,
508
   the user gets the impression of missing functionality due to this
509
   being a COFI and alerted for via the x86_ginsn_unhandled () workflow
510
   as unhandled operation (which can be misleading for users).
511
512
   Indirect branches make the code block ineligible for SCFI; Hence, an
513
   approximate ginsn will not affect SCFI correctness:
514
     - Use dummy register if no base or index
515
     - Skip symbol information, if any.
516
   Note this case of TBD_GINSN_GEN_NOT_SCFI.  */
517
0
      dw2_regnum = (mem_reg
518
0
        ? ginsn_dw2_regnum (mem_reg)
519
0
        : GINSN_DW2_REGNUM_RSI_DUMMY);
520
0
      ginsn = ginsn_func (insn_end_sym, true,
521
0
        GINSN_SRC_REG, dw2_regnum, NULL);
522
0
      ginsn_set_where (ginsn);
523
0
    }
524
525
0
  return ginsn;
526
0
}
527
528
static ginsnS *
529
x86_ginsn_enter (const symbolS *insn_end_sym)
530
0
{
531
0
  ginsnS *ginsn = NULL;
532
0
  ginsnS *ginsn_next = NULL;
533
0
  ginsnS *ginsn_last = NULL;
534
  /* In 64-bit mode, the default stack update size is 8 bytes.  */
535
0
  int stack_opnd_size = 8;
536
537
0
  gas_assert (i.imm_operands == 2);
538
539
  /* For non-zero size operands, bail out as untraceable for SCFI.  */
540
0
  if (i.op[0].imms->X_op != O_constant || i.op[0].imms->X_add_symbol != 0
541
0
      || i.op[1].imms->X_op != O_constant || i.op[1].imms->X_add_symbol != 0)
542
0
    {
543
0
      as_bad ("SCFI: enter insn with non-zero operand not supported");
544
0
      return ginsn;
545
0
    }
546
547
  /* Check if this is a 16-bit op.  */
548
0
  if (ginsn_opsize_prefix_p ())
549
0
    stack_opnd_size = 2;
550
551
  /* If the nesting level is 0, the processor pushes the frame pointer from
552
     the BP/EBP/RBP register onto the stack, copies the current stack
553
     pointer from the SP/ESP/RSP register into the BP/EBP/RBP register, and
554
     loads the SP/ESP/RSP register with the current stack-pointer value
555
     minus the value in the size operand.  */
556
0
  ginsn = ginsn_new_sub (insn_end_sym, false,
557
0
       GINSN_SRC_REG, REG_SP, 0,
558
0
       GINSN_SRC_IMM, 0, stack_opnd_size,
559
0
       GINSN_DST_REG, REG_SP, 0);
560
0
  ginsn_set_where (ginsn);
561
0
  ginsn_next = ginsn_new_store (insn_end_sym, false,
562
0
        GINSN_SRC_REG, REG_FP,
563
0
        GINSN_DST_INDIRECT, REG_SP, 0);
564
0
  ginsn_set_where (ginsn_next);
565
0
  gas_assert (!ginsn_link_next (ginsn, ginsn_next));
566
0
  ginsn_last = ginsn_new_mov (insn_end_sym, false,
567
0
            GINSN_SRC_REG, REG_SP, 0,
568
0
            GINSN_DST_REG, REG_FP, 0);
569
0
  ginsn_set_where (ginsn_last);
570
0
  gas_assert (!ginsn_link_next (ginsn_next, ginsn_last));
571
572
0
  return ginsn;
573
0
}
574
575
static ginsnS *
576
x86_ginsn_leave (const symbolS *insn_end_sym)
577
0
{
578
0
  ginsnS *ginsn = NULL;
579
0
  ginsnS *ginsn_next = NULL;
580
0
  ginsnS *ginsn_last = NULL;
581
  /* In 64-bit mode, the default stack update size is 8 bytes.  */
582
0
  int stack_opnd_size = 8;
583
584
  /* Check if this is a 16-bit op.  */
585
0
  if (ginsn_opsize_prefix_p ())
586
0
    stack_opnd_size = 2;
587
588
  /* The 'leave' instruction copies the contents of the RBP register
589
     into the RSP register to release all stack space allocated to the
590
     procedure.  */
591
0
  ginsn = ginsn_new_mov (insn_end_sym, false,
592
0
       GINSN_SRC_REG, REG_FP, 0,
593
0
       GINSN_DST_REG, REG_SP, 0);
594
0
  ginsn_set_where (ginsn);
595
  /* Then it restores the old value of the RBP register from the stack.  */
596
0
  ginsn_next = ginsn_new_load (insn_end_sym, false,
597
0
             GINSN_SRC_INDIRECT, REG_SP, 0,
598
0
             GINSN_DST_REG, REG_FP);
599
0
  ginsn_set_where (ginsn_next);
600
0
  gas_assert (!ginsn_link_next (ginsn, ginsn_next));
601
0
  ginsn_last = ginsn_new_add (insn_end_sym, false,
602
0
            GINSN_SRC_REG, REG_SP, 0,
603
0
            GINSN_SRC_IMM, 0, stack_opnd_size,
604
0
            GINSN_DST_REG, REG_SP, 0);
605
0
  ginsn_set_where (ginsn_next);
606
0
  gas_assert (!ginsn_link_next (ginsn_next, ginsn_last));
607
608
0
  return ginsn;
609
0
}
610
611
/* Check if an instruction is whitelisted.
612
613
   Some instructions may appear with REG_SP or REG_FP as destination, because
614
   which they are deemed 'interesting' for SCFI.  Whitelist them here if they
615
   do not affect SCFI correctness.  */
616
617
static bool
618
x86_ginsn_safe_to_skip_p (void)
619
0
{
620
0
  bool skip_p = false;
621
0
  uint16_t opcode = i.tm.base_opcode;
622
623
0
  switch (opcode)
624
0
    {
625
0
    case 0x80:
626
0
    case 0x81:
627
0
    case 0x83:
628
0
      if (i.tm.opcode_space != SPACE_BASE)
629
0
  break;
630
      /* cmp imm, reg/rem.  */
631
0
      if (i.tm.extension_opcode == 7)
632
0
  skip_p = true;
633
0
      break;
634
635
0
    case 0x38:
636
0
    case 0x39:
637
0
    case 0x3a:
638
0
    case 0x3b:
639
0
      if (i.tm.opcode_space != SPACE_BASE)
640
0
  break;
641
      /* cmp imm/reg/mem, reg/rem.  */
642
0
      skip_p = true;
643
0
      break;
644
645
0
    case 0xf6:
646
0
    case 0xf7:
647
0
    case 0x84:
648
0
    case 0x85:
649
      /* test imm/reg/mem, reg/mem.  */
650
0
      if (i.tm.opcode_space != SPACE_BASE)
651
0
  break;
652
0
      skip_p = true;
653
0
      break;
654
655
0
    default:
656
0
      break;
657
0
    }
658
659
0
  return skip_p;
660
0
}
661
662
0
#define X86_GINSN_UNHANDLED_NONE        0
663
0
#define X86_GINSN_UNHANDLED_DEST_REG    1
664
0
#define X86_GINSN_UNHANDLED_CFG         2
665
0
#define X86_GINSN_UNHANDLED_STACKOP     3
666
0
#define X86_GINSN_UNHANDLED_UNEXPECTED  4
667
668
/* Check the input insn for its impact on the correctness of the synthesized
669
   CFI.  Returns an error code to the caller.  */
670
671
static int
672
x86_ginsn_unhandled (void)
673
0
{
674
0
  int err = X86_GINSN_UNHANDLED_NONE;
675
0
  const reg_entry *reg_op;
676
0
  unsigned int dw2_regnum;
677
678
  /* Keep an eye out for instructions affecting control flow.  */
679
0
  if (i.tm.opcode_modifier.jump)
680
0
    err = X86_GINSN_UNHANDLED_CFG;
681
  /* Also, for any instructions involving an implicit update to the stack
682
     pointer.  */
683
0
  else if (i.tm.opcode_modifier.operandconstraint == IMPLICIT_STACK_OP)
684
0
    err = X86_GINSN_UNHANDLED_STACKOP;
685
  /* Finally, also check if the missed instructions are affecting REG_SP or
686
     REG_FP.  The destination operand is the last at all stages of assembly
687
     (due to following AT&T syntax layout in the internal representation).  In
688
     case of Intel syntax input, this still remains true as swap_operands ()
689
     is done by now.
690
     PS: These checks do not involve index / base reg, as indirect memory
691
     accesses via REG_SP or REG_FP do not affect SCFI correctness.
692
     (Also note these instructions are candidates for other ginsn generation
693
     modes in future.  TBD_GINSN_GEN_NOT_SCFI.)  */
694
0
  else if (i.operands && i.reg_operands
695
0
     && !(i.flags[i.operands - 1] & Operand_Mem))
696
0
    {
697
0
      reg_op = i.op[i.operands - 1].regs;
698
0
      if (reg_op)
699
0
  {
700
0
    dw2_regnum = ginsn_dw2_regnum (reg_op);
701
0
    if (dw2_regnum == REG_SP || dw2_regnum == REG_FP)
702
0
      err = X86_GINSN_UNHANDLED_DEST_REG;
703
0
  }
704
0
      else
705
  /* Something unexpected.  Indicate to caller.  */
706
0
  err = X86_GINSN_UNHANDLED_UNEXPECTED;
707
0
    }
708
709
0
  return err;
710
0
}
711
712
/* Generate one or more generic GAS instructions, a.k.a, ginsns for the current
713
   machine instruction.
714
715
   Returns the head of linked list of ginsn(s) added, if success; Returns NULL
716
   if failure.
717
718
   The input ginsn_gen_mode GMODE determines the set of minimal necessary
719
   ginsns necessary for correctness of any passes applicable for that mode.
720
   For supporting the GINSN_GEN_SCFI generation mode, following is the list of
721
   machine instructions that must be translated into the corresponding ginsns
722
   to ensure correctness of SCFI:
723
     - All instructions affecting the two registers that could potentially
724
       be used as the base register for CFA tracking.  For SCFI, the base
725
       register for CFA tracking is limited to REG_SP and REG_FP only for
726
       now.
727
     - All change of flow instructions: conditional and unconditional branches,
728
       call and return from functions.
729
     - All instructions that can potentially be a register save / restore
730
       operation.
731
     - All instructions that perform stack manipulation implicitly: the CALL,
732
       RET, PUSH, POP, ENTER, and LEAVE instructions.
733
734
   The function currently supports GINSN_GEN_SCFI ginsn generation mode only.
735
   To support other generation modes will require work on this target-specific
736
   process of creation of ginsns:
737
     - Some of such places are tagged with TBD_GINSN_GEN_NOT_SCFI to serve as
738
       possible starting points.
739
     - Also note that ginsn representation may need enhancements.  Specifically,
740
       note some TBD_GINSN_INFO_LOSS and TBD_GINSN_REPRESENTATION_LIMIT markers.
741
   */
742
743
static ginsnS *
744
x86_ginsn_new (const symbolS *insn_end_sym, enum ginsn_gen_mode gmode)
745
0
{
746
0
  int err = 0;
747
0
  uint16_t opcode;
748
0
  unsigned int dw2_regnum;
749
0
  const reg_entry *mem_reg;
750
0
  ginsnS *ginsn = NULL;
751
0
  ginsnS *ginsn_next = NULL;
752
  /* In 64-bit mode, the default stack update size is 8 bytes.  */
753
0
  int stack_opnd_size = 8;
754
755
  /* Currently supports generation of selected ginsns, sufficient for
756
     the use-case of SCFI only.  */
757
0
  if (gmode != GINSN_GEN_SCFI)
758
0
    return ginsn;
759
760
0
  opcode = i.tm.base_opcode;
761
762
  /* Until it is clear how to handle APX NDD and other new opcodes, disallow
763
     them from SCFI.  */
764
0
  if (is_apx_rex2_encoding ()
765
0
      || (i.tm.opcode_modifier.evex && is_apx_evex_encoding ()))
766
0
    {
767
0
      as_bad (_("SCFI: unsupported APX op %#x may cause incorrect CFI"),
768
0
        opcode);
769
0
      return ginsn;
770
0
    }
771
772
0
  switch (opcode)
773
0
    {
774
775
    /* Add opcodes 0x0/0x2 and sub opcodes 0x28/0x2a (with opcode_space
776
       SPACE_BASE) are 8-bit ops.  While they are relevant for SCFI
777
       correctness,  skip handling them here and use the x86_ginsn_unhandled
778
       code path to generate GINSN_TYPE_OTHER when necessary.  */
779
780
0
    case 0x1:  /* add reg, reg/mem.  */
781
0
    case 0x29: /* sub reg, reg/mem.  */
782
0
      if (i.tm.opcode_space != SPACE_BASE)
783
0
  break;
784
0
      ginsn = x86_ginsn_addsub_reg_mem (insn_end_sym);
785
0
      break;
786
787
0
    case 0x3:  /* add reg/mem, reg.  */
788
0
    case 0x2b: /* sub reg/mem, reg.  */
789
0
      if (i.tm.opcode_space != SPACE_BASE)
790
0
  break;
791
0
      ginsn = x86_ginsn_addsub_mem_reg (insn_end_sym);
792
0
      break;
793
794
0
    case 0xa0: /* push fs.  */
795
0
    case 0xa8: /* push gs.  */
796
      /* push fs / push gs have opcode_space == SPACE_0F.  */
797
0
      if (i.tm.opcode_space != SPACE_0F)
798
0
  break;
799
0
      dw2_regnum = ginsn_dw2_regnum (i.op[0].regs);
800
      /* Check if operation size is 16-bit.  */
801
0
      if (ginsn_opsize_prefix_p ())
802
0
  stack_opnd_size = 2;
803
0
      ginsn = ginsn_new_sub (insn_end_sym, false,
804
0
           GINSN_SRC_REG, REG_SP, 0,
805
0
           GINSN_SRC_IMM, 0, stack_opnd_size,
806
0
           GINSN_DST_REG, REG_SP, 0);
807
0
      ginsn_set_where (ginsn);
808
0
      ginsn_next = ginsn_new_store (insn_end_sym, false,
809
0
            GINSN_SRC_REG, dw2_regnum,
810
0
            GINSN_DST_INDIRECT, REG_SP, 0);
811
0
      ginsn_set_where (ginsn_next);
812
0
      gas_assert (!ginsn_link_next (ginsn, ginsn_next));
813
0
      break;
814
815
0
    case 0xa1: /* pop fs.  */
816
0
    case 0xa9: /* pop gs.  */
817
      /* pop fs / pop gs have opcode_space == SPACE_0F.  */
818
0
      if (i.tm.opcode_space != SPACE_0F)
819
0
  break;
820
0
      dw2_regnum = ginsn_dw2_regnum (i.op[0].regs);
821
      /* Check if operation size is 16-bit.  */
822
0
      if (ginsn_opsize_prefix_p ())
823
0
  stack_opnd_size = 2;
824
0
      ginsn = ginsn_new_load (insn_end_sym, false,
825
0
            GINSN_SRC_INDIRECT, REG_SP, 0,
826
0
            GINSN_DST_REG, dw2_regnum);
827
0
      ginsn_set_where (ginsn);
828
0
      ginsn_next = ginsn_new_add (insn_end_sym, false,
829
0
          GINSN_SRC_REG, REG_SP, 0,
830
0
          GINSN_SRC_IMM, 0, stack_opnd_size,
831
0
          GINSN_DST_REG, REG_SP, 0);
832
0
      ginsn_set_where (ginsn_next);
833
0
      gas_assert (!ginsn_link_next (ginsn, ginsn_next));
834
0
      break;
835
836
0
    case 0x50 ... 0x57:
837
0
      if (i.tm.opcode_space != SPACE_BASE)
838
0
  break;
839
      /* push reg.  */
840
0
      dw2_regnum = ginsn_dw2_regnum (i.op[0].regs);
841
      /* Check if operation size is 16-bit.  */
842
0
      if (ginsn_opsize_prefix_p ())
843
0
  stack_opnd_size = 2;
844
0
      ginsn = ginsn_new_sub (insn_end_sym, false,
845
0
           GINSN_SRC_REG, REG_SP, 0,
846
0
           GINSN_SRC_IMM, 0, stack_opnd_size,
847
0
           GINSN_DST_REG, REG_SP, 0);
848
0
      ginsn_set_where (ginsn);
849
0
      ginsn_next = ginsn_new_store (insn_end_sym, false,
850
0
            GINSN_SRC_REG, dw2_regnum,
851
0
            GINSN_DST_INDIRECT, REG_SP, 0);
852
0
      ginsn_set_where (ginsn_next);
853
0
      gas_assert (!ginsn_link_next (ginsn, ginsn_next));
854
0
      break;
855
856
0
    case 0x58 ... 0x5f:
857
0
      if (i.tm.opcode_space != SPACE_BASE)
858
0
  break;
859
      /* pop reg.  */
860
0
      dw2_regnum = ginsn_dw2_regnum (i.op[0].regs);
861
0
      ginsn = ginsn_new_load (insn_end_sym, false,
862
0
            GINSN_SRC_INDIRECT, REG_SP, 0,
863
0
            GINSN_DST_REG, dw2_regnum);
864
0
      ginsn_set_where (ginsn);
865
      /* Check if operation size is 16-bit.  */
866
0
      if (ginsn_opsize_prefix_p ())
867
0
  stack_opnd_size = 2;
868
0
      ginsn_next = ginsn_new_add (insn_end_sym, false,
869
0
          GINSN_SRC_REG, REG_SP, 0,
870
0
          GINSN_SRC_IMM, 0, stack_opnd_size,
871
0
          GINSN_DST_REG, REG_SP, 0);
872
0
      ginsn_set_where (ginsn_next);
873
0
      gas_assert (!ginsn_link_next (ginsn, ginsn_next));
874
0
      break;
875
876
0
    case 0x6a: /* push imm8.  */
877
0
    case 0x68: /* push imm16/imm32.  */
878
0
      if (i.tm.opcode_space != SPACE_BASE)
879
0
  break;
880
      /* Check if operation size is 16-bit.  */
881
0
      if (ginsn_opsize_prefix_p ())
882
0
  stack_opnd_size = 2;
883
      /* Skip getting the value of imm from machine instruction
884
   because this is not important for SCFI.  */
885
0
      ginsn = ginsn_new_sub (insn_end_sym, false,
886
0
           GINSN_SRC_REG, REG_SP, 0,
887
0
           GINSN_SRC_IMM, 0, stack_opnd_size,
888
0
           GINSN_DST_REG, REG_SP, 0);
889
0
      ginsn_set_where (ginsn);
890
0
      ginsn_next = ginsn_new_store (insn_end_sym, false,
891
0
            GINSN_SRC_IMM, 0,
892
0
            GINSN_DST_INDIRECT, REG_SP, 0);
893
0
      ginsn_set_where (ginsn_next);
894
0
      gas_assert (!ginsn_link_next (ginsn, ginsn_next));
895
0
      break;
896
897
    /* PS: Opcodes 0x80 ... 0x8f with opcode_space SPACE_0F are present
898
       only after relaxation.  They do not need to be handled for ginsn
899
       creation.  */
900
0
    case 0x70 ... 0x7f:
901
0
      if (i.tm.opcode_space != SPACE_BASE)
902
0
  break;
903
0
      ginsn = x86_ginsn_jump (insn_end_sym, true);
904
0
      break;
905
906
0
    case 0x80:
907
0
    case 0x81:
908
0
    case 0x83:
909
0
      if (i.tm.opcode_space != SPACE_BASE)
910
0
  break;
911
0
      ginsn = x86_ginsn_alu_imm (insn_end_sym);
912
0
      break;
913
914
0
    case 0x8a: /* mov r/m8, r8.  */
915
0
    case 0x8b: /* mov r/m(16/32/64), r(16/32/64).  */
916
0
    case 0x88: /* mov r8, r/m8.  */
917
0
    case 0x89: /* mov r(16/32/64), r/m(16/32/64).  */
918
0
      if (i.tm.opcode_space != SPACE_BASE)
919
0
  break;
920
0
      ginsn = x86_ginsn_move (insn_end_sym);
921
0
      break;
922
923
0
    case 0x8d:
924
0
      if (i.tm.opcode_space != SPACE_BASE)
925
0
  break;
926
      /* lea disp(%base,%index,imm), %dst.  */
927
0
      ginsn = x86_ginsn_lea (insn_end_sym);
928
0
      break;
929
930
0
    case 0x8f:
931
0
      if (i.tm.opcode_space != SPACE_BASE)
932
0
  break;
933
      /* pop to reg/mem.  */
934
0
      if (i.mem_operands)
935
0
  {
936
0
    mem_reg = (i.base_reg) ? i.base_reg : i.index_reg;
937
    /* Use dummy register if no base or index.  Unlike other opcodes,
938
       ginsns must be generated as this affect stack pointer.  */
939
0
    dw2_regnum = (mem_reg
940
0
      ? ginsn_dw2_regnum (mem_reg)
941
0
      : GINSN_DW2_REGNUM_RSI_DUMMY);
942
0
  }
943
0
      else
944
0
  dw2_regnum = ginsn_dw2_regnum (i.op[0].regs);
945
0
      ginsn = ginsn_new_load (insn_end_sym, false,
946
0
            GINSN_SRC_INDIRECT, REG_SP, 0,
947
0
            GINSN_DST_INDIRECT, dw2_regnum);
948
0
      ginsn_set_where (ginsn);
949
      /* Check if operation size is 16-bit.  */
950
0
      if (ginsn_opsize_prefix_p ())
951
0
  stack_opnd_size = 2;
952
0
      ginsn_next = ginsn_new_add (insn_end_sym, false,
953
0
          GINSN_SRC_REG, REG_SP, 0,
954
0
          GINSN_SRC_IMM, 0, stack_opnd_size,
955
0
          GINSN_DST_REG, REG_SP, 0);
956
0
      ginsn_set_where (ginsn_next);
957
0
      gas_assert (!ginsn_link_next (ginsn, ginsn_next));
958
0
      break;
959
960
0
    case 0x9c:
961
0
      if (i.tm.opcode_space != SPACE_BASE)
962
0
  break;
963
      /* pushf / pushfq.  */
964
      /* Check if operation size is 16-bit.  */
965
0
      if (ginsn_opsize_prefix_p ())
966
0
  stack_opnd_size = 2;
967
0
      ginsn = ginsn_new_sub (insn_end_sym, false,
968
0
           GINSN_SRC_REG, REG_SP, 0,
969
0
           GINSN_SRC_IMM, 0, stack_opnd_size,
970
0
           GINSN_DST_REG, REG_SP, 0);
971
0
      ginsn_set_where (ginsn);
972
      /* FIXME - hardcode the actual DWARF reg number value.  As for SCFI
973
   correctness, although this behaves simply a placeholder value; its
974
   just clearer if the value is correct.  */
975
0
      dw2_regnum = GINSN_DW2_REGNUM_EFLAGS;
976
0
      ginsn_next = ginsn_new_store (insn_end_sym, false,
977
0
            GINSN_SRC_REG, dw2_regnum,
978
0
            GINSN_DST_INDIRECT, REG_SP, 0);
979
0
      ginsn_set_where (ginsn_next);
980
0
      gas_assert (!ginsn_link_next (ginsn, ginsn_next));
981
0
      break;
982
983
0
    case 0x9d:
984
0
      if (i.tm.opcode_space != SPACE_BASE)
985
0
  break;
986
      /* popf / popfq.  */
987
      /* Check if operation size is 16-bit.  */
988
0
      if (ginsn_opsize_prefix_p ())
989
0
  stack_opnd_size = 2;
990
      /* FIXME - hardcode the actual DWARF reg number value.  As for SCFI
991
   correctness, although this behaves simply a placeholder value; its
992
   just clearer if the value is correct.  */
993
0
      dw2_regnum = GINSN_DW2_REGNUM_EFLAGS;
994
0
      ginsn = ginsn_new_load (insn_end_sym, false,
995
0
            GINSN_SRC_INDIRECT, REG_SP, 0,
996
0
            GINSN_DST_REG, dw2_regnum);
997
0
      ginsn_set_where (ginsn);
998
0
      ginsn_next = ginsn_new_add (insn_end_sym, false,
999
0
          GINSN_SRC_REG, REG_SP, 0,
1000
0
          GINSN_SRC_IMM, 0, stack_opnd_size,
1001
0
          GINSN_DST_REG, REG_SP, 0);
1002
0
      ginsn_set_where (ginsn_next);
1003
0
      gas_assert (!ginsn_link_next (ginsn, ginsn_next));
1004
0
      break;
1005
1006
0
    case 0xff:
1007
0
      if (i.tm.opcode_space != SPACE_BASE)
1008
0
  break;
1009
      /* push from reg/mem.  */
1010
0
      if (i.tm.extension_opcode == 6)
1011
0
  {
1012
    /* Check if operation size is 16-bit.  */
1013
0
    if (ginsn_opsize_prefix_p ())
1014
0
      stack_opnd_size = 2;
1015
0
    ginsn = ginsn_new_sub (insn_end_sym, false,
1016
0
         GINSN_SRC_REG, REG_SP, 0,
1017
0
         GINSN_SRC_IMM, 0, stack_opnd_size,
1018
0
         GINSN_DST_REG, REG_SP, 0);
1019
0
    ginsn_set_where (ginsn);
1020
0
    if (i.mem_operands)
1021
0
      {
1022
0
        mem_reg = (i.base_reg) ? i.base_reg : i.index_reg;
1023
        /* Use dummy register if no base or index.  Unlike other opcodes,
1024
     ginsns must be generated as this affect stack pointer.  */
1025
0
        dw2_regnum = (mem_reg
1026
0
          ? ginsn_dw2_regnum (mem_reg)
1027
0
          : GINSN_DW2_REGNUM_RSI_DUMMY);
1028
0
      }
1029
0
    else
1030
0
      dw2_regnum = ginsn_dw2_regnum (i.op[0].regs);
1031
0
    ginsn_next = ginsn_new_store (insn_end_sym, false,
1032
0
          GINSN_SRC_INDIRECT, dw2_regnum,
1033
0
          GINSN_DST_INDIRECT, REG_SP, 0);
1034
0
    ginsn_set_where (ginsn_next);
1035
0
    gas_assert (!ginsn_link_next (ginsn, ginsn_next));
1036
0
  }
1037
0
      else if (i.tm.extension_opcode == 4 || i.tm.extension_opcode == 2)
1038
0
  ginsn = x86_ginsn_indirect_branch (insn_end_sym);
1039
0
      break;
1040
1041
0
    case 0xc2: /* ret imm16.  */
1042
0
    case 0xc3: /* ret.  */
1043
0
      if (i.tm.opcode_space != SPACE_BASE)
1044
0
  break;
1045
      /* Near ret.  */
1046
0
      ginsn = ginsn_new_return (insn_end_sym, true);
1047
0
      ginsn_set_where (ginsn);
1048
0
      break;
1049
1050
0
    case 0xc8:
1051
0
      if (i.tm.opcode_space != SPACE_BASE)
1052
0
  break;
1053
      /* enter.  */
1054
0
      ginsn = x86_ginsn_enter (insn_end_sym);
1055
0
      break;
1056
1057
0
    case 0xc9:
1058
0
      if (i.tm.opcode_space != SPACE_BASE)
1059
0
  break;
1060
      /* leave.  */
1061
0
      ginsn = x86_ginsn_leave (insn_end_sym);
1062
0
      break;
1063
1064
0
    case 0xe0 ... 0xe2: /* loop / loope / loopne.  */
1065
0
    case 0xe3:          /* jecxz / jrcxz.  */
1066
0
      if (i.tm.opcode_space != SPACE_BASE)
1067
0
  break;
1068
0
      ginsn = x86_ginsn_jump (insn_end_sym, true);
1069
0
      ginsn_set_where (ginsn);
1070
0
      break;
1071
1072
0
    case 0xe8:
1073
0
      if (i.tm.opcode_space != SPACE_BASE)
1074
0
  break;
1075
      /* PS: SCFI machinery does not care about which func is being
1076
   called.  OK to skip that info.  */
1077
0
      ginsn = ginsn_new_call (insn_end_sym, true,
1078
0
            GINSN_SRC_SYMBOL, 0, NULL);
1079
0
      ginsn_set_where (ginsn);
1080
0
      break;
1081
1082
    /* PS: opcode 0xe9 appears only after relaxation.  Skip here.  */
1083
0
    case 0xeb:
1084
      /* If opcode_space != SPACE_BASE, this is not a jmp insn.  Skip it
1085
   for GINSN_GEN_SCFI.  */
1086
0
      if (i.tm.opcode_space != SPACE_BASE)
1087
0
  break;
1088
      /* Unconditional jmp.  */
1089
0
      ginsn = x86_ginsn_jump (insn_end_sym, false);
1090
0
      ginsn_set_where (ginsn);
1091
0
      break;
1092
1093
0
    default:
1094
      /* TBD_GINSN_GEN_NOT_SCFI: Skip all other opcodes uninteresting for
1095
   GINSN_GEN_SCFI mode.  */
1096
0
      break;
1097
0
    }
1098
1099
0
  if (!ginsn && !x86_ginsn_safe_to_skip_p ())
1100
0
    {
1101
      /* For all unhandled insns that are not whitelisted, check that they do
1102
   not impact SCFI correctness.  */
1103
0
      err = x86_ginsn_unhandled ();
1104
0
      switch (err)
1105
0
  {
1106
0
  case X86_GINSN_UNHANDLED_NONE:
1107
0
    break;
1108
0
  case X86_GINSN_UNHANDLED_DEST_REG:
1109
    /* Not all writes to REG_FP are harmful in context of SCFI.  Simply
1110
       generate a GINSN_TYPE_OTHER with destination set to the
1111
       appropriate register.  The SCFI machinery will bail out if this
1112
       ginsn affects SCFI correctness.  */
1113
0
    dw2_regnum = ginsn_dw2_regnum (i.op[i.operands - 1].regs);
1114
0
    ginsn = ginsn_new_other (insn_end_sym, true,
1115
0
           GINSN_SRC_IMM, 0,
1116
0
           GINSN_SRC_IMM, 0,
1117
0
           GINSN_DST_REG, dw2_regnum);
1118
0
    ginsn_set_where (ginsn);
1119
0
    break;
1120
0
  case X86_GINSN_UNHANDLED_CFG:
1121
0
  case X86_GINSN_UNHANDLED_STACKOP:
1122
0
    as_bad (_("SCFI: unhandled op %#x may cause incorrect CFI"), opcode);
1123
0
    break;
1124
0
  case X86_GINSN_UNHANDLED_UNEXPECTED:
1125
0
    as_bad (_("SCFI: unexpected op %#x may cause incorrect CFI"),
1126
0
      opcode);
1127
0
    break;
1128
0
  default:
1129
0
    abort ();
1130
0
    break;
1131
0
  }
1132
0
    }
1133
1134
0
  return ginsn;
1135
0
}