[V2,09/10] gas: testsuite: add a x86_64 testsuite for SCFI

Message ID 20231030165137.2570939-10-indu.bhagat@oracle.com
State New
Headers
Series Synthesize CFI for hand-written asm |

Checks

Context Check Description
linaro-tcwg-bot/tcwg_binutils_build--master-arm success Testing passed
linaro-tcwg-bot/tcwg_binutils_build--master-aarch64 success Testing passed
linaro-tcwg-bot/tcwg_binutils_check--master-aarch64 success Testing passed
linaro-tcwg-bot/tcwg_binutils_check--master-arm success Testing passed

Commit Message

Indu Bhagat Oct. 30, 2023, 4:51 p.m. UTC
  [Changes from the RFC patch set]
  - New testcases based on the fixes in the previous patches
  - New testcase for not ignoring .cfi_label
  - New testcases scfi-asm-marker-* which test for some patterns of
    .type and .size attributes in the input asm for --scfi=all.
  - Recall that all assembler testcases here include the .cfi_*
    directives corresponding to the asm.  GAS now issues a warning if
    --scfi is invoked with input assembly which includes .cfi_*
    directives:
    "Warning: --scfi=all ignores some user-specified CFI directives"
  - But the SCFI algorithm in GAS issues other SCFI specific warnings too.
    Hence, many of the tests are run twice, like so:
    + run_dump_test "scfi-add-1", which runs the test with a -W and checks
      the objdump output of the .eh_frame (or sometimes .sframe) section.
    + run_list_test "scfi-add-1" "--scfi --warn", which runs the test
      with warnings enabled, and explicitly checks all warning messages
      per test.
[End of changes]

The testsuite for SCFI contains target-specific tests.

As all the tests are executed with --scfi command line option, the CFI
annotations in the test .s files are skipped altogether by the GAS for
processing.  The CFI directives in the assembly files are added with the
intention to aid maintainence only: CFI annotations in .s files help
convey the expected EH Frame / SFrame data in a format-oblivious way.

Some testcases are used to highlight those asm constructs that the SCFI
machinery in GAS currently does not support:

  - Only AMD64 ABI is supported for now. Using --m32 with --scfi results
    in hard error.
    See scfi-unsupported-1.s.

  - Untraceable stack-pointer manipulation in function epilougue and prologue.
    See scfi-unsupported-2.s.

  - Using Dynamically Realigned Arguement Pointer (DRAP) register to
    realign the stack.  For SCFI, the CFA must be only REG_SP or REG_FP
    based.  See scfi-unsupported-drap-1.s

Some testcases are used to highlight some diagnostics that the SCFI
machinery in GAS currently issues, with an intent to help user correct
inadvertent errors in their hand-written asm.  An error is issued in a
situation where GAS is not sure it will be able to synthesize valid CFI.

  - (#1) "Warning: SCFI: Asymetrical register restore"
  - (#2) "Error: SCFI: usage of REG_FP as scratch not supported"
  - (#3) "Error: SCFI: unsupported stack manipulation pattern"

In case of (#2) and (#3), SCFI generation is skipped for the respective
function.  Above is a subset of the warnings/errors implemented in the
code.

gas/testsuite/:
	* gas/scfi/README: New test.
	* gas/scfi/x86_64/scfi-add-1.d: New test.
	* gas/scfi/x86_64/scfi-add-1.l: New test.
	* gas/scfi/x86_64/scfi-add-1.s: New test.
	* gas/scfi/x86_64/scfi-add-2.d: New test.
	* gas/scfi/x86_64/scfi-add-2.l: New test.
	* gas/scfi/x86_64/scfi-add-2.s: New test.
	* gas/scfi/x86_64/scfi-asm-marker-1.d: New test.
	* gas/scfi/x86_64/scfi-asm-marker-1.l: New test.
	* gas/scfi/x86_64/scfi-asm-marker-1.s: New test.
	* gas/scfi/x86_64/scfi-asm-marker-2.d: New test.
	* gas/scfi/x86_64/scfi-asm-marker-2.l: New test.
	* gas/scfi/x86_64/scfi-asm-marker-2.s: New test.
	* gas/scfi/x86_64/scfi-asm-marker-3.d: New test.
	* gas/scfi/x86_64/scfi-asm-marker-3.l: New test.
	* gas/scfi/x86_64/scfi-asm-marker-3.s: New test.
	* gas/scfi/x86_64/scfi-bp-sp-1.d: New test.
	* gas/scfi/x86_64/scfi-bp-sp-1.l: New test.
	* gas/scfi/x86_64/scfi-bp-sp-1.s: New test.
	* gas/scfi/x86_64/scfi-bp-sp-2.d: New test.
	* gas/scfi/x86_64/scfi-bp-sp-2.l: New test.
	* gas/scfi/x86_64/scfi-bp-sp-2.s: New test.
	* gas/scfi/x86_64/scfi-callee-saved-1.d: New test.
	* gas/scfi/x86_64/scfi-callee-saved-1.l: New test.
	* gas/scfi/x86_64/scfi-callee-saved-1.s: New test.
	* gas/scfi/x86_64/scfi-callee-saved-2.d: New test.
	* gas/scfi/x86_64/scfi-callee-saved-2.l: New test.
	* gas/scfi/x86_64/scfi-callee-saved-2.s: New test.
	* gas/scfi/x86_64/scfi-callee-saved-3.d: New test.
	* gas/scfi/x86_64/scfi-callee-saved-3.l: New test.
	* gas/scfi/x86_64/scfi-callee-saved-3.s: New test.
	* gas/scfi/x86_64/scfi-callee-saved-4.d: New test.
	* gas/scfi/x86_64/scfi-callee-saved-4.l: New test.
	* gas/scfi/x86_64/scfi-callee-saved-4.s: New test.
	* gas/scfi/x86_64/scfi-cfg-1.d: New test.
	* gas/scfi/x86_64/scfi-cfg-1.l: New test.
	* gas/scfi/x86_64/scfi-cfg-1.s: New test.
	* gas/scfi/x86_64/scfi-cfg-2.d: New test.
	* gas/scfi/x86_64/scfi-cfg-2.l: New test.
	* gas/scfi/x86_64/scfi-cfg-2.s: New test.
	* gas/scfi/x86_64/scfi-cfi-label-1.d: New test.
	* gas/scfi/x86_64/scfi-cfi-label-1.l: New test.
	* gas/scfi/x86_64/scfi-cfi-label-1.s: New test.
	* gas/scfi/x86_64/scfi-cofi-1.d: New test.
	* gas/scfi/x86_64/scfi-cofi-1.l: New test.
	* gas/scfi/x86_64/scfi-cofi-1.s: New test.
	* gas/scfi/x86_64/scfi-diag-1.l: New test.
	* gas/scfi/x86_64/scfi-diag-1.s: New test.
	* gas/scfi/x86_64/scfi-diag-2.l: New test.
	* gas/scfi/x86_64/scfi-diag-2.s: New test.
	* gas/scfi/x86_64/scfi-dyn-stack-1.d: New test.
	* gas/scfi/x86_64/scfi-dyn-stack-1.l: New test.
	* gas/scfi/x86_64/scfi-dyn-stack-1.s: New test.
	* gas/scfi/x86_64/scfi-fp-diag-2.l: New test.
	* gas/scfi/x86_64/scfi-fp-diag-2.s: New test.
	* gas/scfi/x86_64/scfi-ignore-1.d: New test.
	* gas/scfi/x86_64/scfi-ignore-1.l: New test.
	* gas/scfi/x86_64/scfi-ignore-1.s: New test.
	* gas/scfi/x86_64/scfi-indirect-mov-1.d: New test.
	* gas/scfi/x86_64/scfi-indirect-mov-1.l: New test.
	* gas/scfi/x86_64/scfi-indirect-mov-1.s: New test.
	* gas/scfi/x86_64/scfi-indirect-mov-2.d: New test.
	* gas/scfi/x86_64/scfi-indirect-mov-2.l: New test.
	* gas/scfi/x86_64/scfi-indirect-mov-2.s: New test.
	* gas/scfi/x86_64/scfi-indirect-mov-3.d: New test.
	* gas/scfi/x86_64/scfi-indirect-mov-3.l: New test.
	* gas/scfi/x86_64/scfi-indirect-mov-3.s: New test.
	* gas/scfi/x86_64/scfi-indirect-mov-4.d: New test.
	* gas/scfi/x86_64/scfi-indirect-mov-4.l: New test.
	* gas/scfi/x86_64/scfi-indirect-mov-4.s: New test.
	* gas/scfi/x86_64/scfi-lea-1.d: New test.
	* gas/scfi/x86_64/scfi-lea-1.l: New test.
	* gas/scfi/x86_64/scfi-lea-1.s: New test.
	* gas/scfi/x86_64/scfi-leave-1.d: New test.
	* gas/scfi/x86_64/scfi-leave-1.l: New test.
	* gas/scfi/x86_64/scfi-leave-1.s: New test.
	* gas/scfi/x86_64/scfi-pushq-1.d: New test.
	* gas/scfi/x86_64/scfi-pushq-1.l: New test.
	* gas/scfi/x86_64/scfi-pushq-1.s: New test.
	* gas/scfi/x86_64/scfi-pushsection-1.d: New test.
	* gas/scfi/x86_64/scfi-pushsection-1.l: New test.
	* gas/scfi/x86_64/scfi-pushsection-1.s: New test.
	* gas/scfi/x86_64/scfi-pushsection-2.d: New test.
	* gas/scfi/x86_64/scfi-pushsection-2.l: New test.
	* gas/scfi/x86_64/scfi-pushsection-2.s: New test.
	* gas/scfi/x86_64/scfi-selfalign-func-1.d: New test.
	* gas/scfi/x86_64/scfi-selfalign-func-1.l: New test.
	* gas/scfi/x86_64/scfi-selfalign-func-1.s: New test.
	* gas/scfi/x86_64/scfi-simple-1.d: New test.
	* gas/scfi/x86_64/scfi-simple-1.l: New test.
	* gas/scfi/x86_64/scfi-simple-1.s: New test.
	* gas/scfi/x86_64/scfi-simple-2.d: New test.
	* gas/scfi/x86_64/scfi-simple-2.l: New test.
	* gas/scfi/x86_64/scfi-simple-2.s: New test.
	* gas/scfi/x86_64/scfi-sub-1.d: New test.
	* gas/scfi/x86_64/scfi-sub-1.l: New test.
	* gas/scfi/x86_64/scfi-sub-1.s: New test.
	* gas/scfi/x86_64/scfi-sub-2.d: New test.
	* gas/scfi/x86_64/scfi-sub-2.l: New test.
	* gas/scfi/x86_64/scfi-sub-2.s: New test.
	* gas/scfi/x86_64/scfi-unsupported-1.l: New test.
	* gas/scfi/x86_64/scfi-unsupported-1.s: New test.
	* gas/scfi/x86_64/scfi-unsupported-2.l: New test.
	* gas/scfi/x86_64/scfi-unsupported-2.s: New test.
	* gas/scfi/x86_64/scfi-unsupported-3.l: New test.
	* gas/scfi/x86_64/scfi-unsupported-3.s: New test.
	* gas/scfi/x86_64/scfi-unsupported-4.l: New test.
	* gas/scfi/x86_64/scfi-unsupported-4.s: New test.
	* gas/scfi/x86_64/scfi-unsupported-cfg-1.l: New test.
	* gas/scfi/x86_64/scfi-unsupported-cfg-1.s: New test.
	* gas/scfi/x86_64/scfi-unsupported-drap-1.l: New test.
	* gas/scfi/x86_64/scfi-unsupported-drap-1.s: New test.
	* gas/scfi/x86_64/scfi-x86-64.exp: New test.
---
 gas/testsuite/gas/scfi/README                 |  17 +++
 gas/testsuite/gas/scfi/x86_64/scfi-add-1.d    |  25 +++++
 gas/testsuite/gas/scfi/x86_64/scfi-add-1.l    |   2 +
 gas/testsuite/gas/scfi/x86_64/scfi-add-1.s    |  13 +++
 gas/testsuite/gas/scfi/x86_64/scfi-add-2.d    |  36 ++++++
 gas/testsuite/gas/scfi/x86_64/scfi-add-2.l    |   2 +
 gas/testsuite/gas/scfi/x86_64/scfi-add-2.s    |  48 ++++++++
 .../gas/scfi/x86_64/scfi-asm-marker-1.d       |  28 +++++
 .../gas/scfi/x86_64/scfi-asm-marker-1.l       |   3 +
 .../gas/scfi/x86_64/scfi-asm-marker-1.s       |  27 +++++
 .../gas/scfi/x86_64/scfi-asm-marker-2.d       |  24 ++++
 .../gas/scfi/x86_64/scfi-asm-marker-2.l       |   3 +
 .../gas/scfi/x86_64/scfi-asm-marker-2.s       |  11 ++
 .../gas/scfi/x86_64/scfi-asm-marker-3.d       |  31 ++++++
 .../gas/scfi/x86_64/scfi-asm-marker-3.l       |   2 +
 .../gas/scfi/x86_64/scfi-asm-marker-3.s       |  38 +++++++
 gas/testsuite/gas/scfi/x86_64/scfi-bp-sp-1.d  |  31 ++++++
 gas/testsuite/gas/scfi/x86_64/scfi-bp-sp-1.l  |   2 +
 gas/testsuite/gas/scfi/x86_64/scfi-bp-sp-1.s  |  22 ++++
 gas/testsuite/gas/scfi/x86_64/scfi-bp-sp-2.d  |  57 ++++++++++
 gas/testsuite/gas/scfi/x86_64/scfi-bp-sp-2.l  |   2 +
 gas/testsuite/gas/scfi/x86_64/scfi-bp-sp-2.s  |  49 +++++++++
 .../gas/scfi/x86_64/scfi-callee-saved-1.d     |  40 +++++++
 .../gas/scfi/x86_64/scfi-callee-saved-1.l     |   2 +
 .../gas/scfi/x86_64/scfi-callee-saved-1.s     |  26 +++++
 .../gas/scfi/x86_64/scfi-callee-saved-2.d     |  41 +++++++
 .../gas/scfi/x86_64/scfi-callee-saved-2.l     |   2 +
 .../gas/scfi/x86_64/scfi-callee-saved-2.s     |  42 +++++++
 .../gas/scfi/x86_64/scfi-callee-saved-3.d     |  42 +++++++
 .../gas/scfi/x86_64/scfi-callee-saved-3.l     |   3 +
 .../gas/scfi/x86_64/scfi-callee-saved-3.s     |  40 +++++++
 .../gas/scfi/x86_64/scfi-callee-saved-4.d     |  40 +++++++
 .../gas/scfi/x86_64/scfi-callee-saved-4.l     |   3 +
 .../gas/scfi/x86_64/scfi-callee-saved-4.s     |  55 ++++++++++
 gas/testsuite/gas/scfi/x86_64/scfi-cfg-1.d    |  36 ++++++
 gas/testsuite/gas/scfi/x86_64/scfi-cfg-1.l    |   2 +
 gas/testsuite/gas/scfi/x86_64/scfi-cfg-1.s    |  47 ++++++++
 gas/testsuite/gas/scfi/x86_64/scfi-cfg-2.d    |  28 +++++
 gas/testsuite/gas/scfi/x86_64/scfi-cfg-2.l    |   2 +
 gas/testsuite/gas/scfi/x86_64/scfi-cfg-2.s    |  21 ++++
 .../gas/scfi/x86_64/scfi-cfi-label-1.d        |  37 +++++++
 .../gas/scfi/x86_64/scfi-cfi-label-1.l        |   2 +
 .../gas/scfi/x86_64/scfi-cfi-label-1.s        |  19 ++++
 gas/testsuite/gas/scfi/x86_64/scfi-cofi-1.d   |   5 +
 gas/testsuite/gas/scfi/x86_64/scfi-cofi-1.l   |   3 +
 gas/testsuite/gas/scfi/x86_64/scfi-cofi-1.s   |  23 ++++
 gas/testsuite/gas/scfi/x86_64/scfi-diag-1.l   |   4 +
 gas/testsuite/gas/scfi/x86_64/scfi-diag-1.s   |  23 ++++
 gas/testsuite/gas/scfi/x86_64/scfi-diag-2.l   |   4 +
 gas/testsuite/gas/scfi/x86_64/scfi-diag-2.s   |  28 +++++
 .../gas/scfi/x86_64/scfi-dyn-stack-1.d        |  23 ++++
 .../gas/scfi/x86_64/scfi-dyn-stack-1.l        |   2 +
 .../gas/scfi/x86_64/scfi-dyn-stack-1.s        |  50 +++++++++
 .../gas/scfi/x86_64/scfi-fp-diag-2.l          |   3 +
 .../gas/scfi/x86_64/scfi-fp-diag-2.s          |  55 ++++++++++
 gas/testsuite/gas/scfi/x86_64/scfi-ignore-1.d |  26 +++++
 gas/testsuite/gas/scfi/x86_64/scfi-ignore-1.l |   2 +
 gas/testsuite/gas/scfi/x86_64/scfi-ignore-1.s |  13 +++
 .../gas/scfi/x86_64/scfi-indirect-mov-1.d     |  51 +++++++++
 .../gas/scfi/x86_64/scfi-indirect-mov-1.l     |   2 +
 .../gas/scfi/x86_64/scfi-indirect-mov-1.s     |  48 ++++++++
 .../gas/scfi/x86_64/scfi-indirect-mov-2.d     |  41 +++++++
 .../gas/scfi/x86_64/scfi-indirect-mov-2.l     |   2 +
 .../gas/scfi/x86_64/scfi-indirect-mov-2.s     |  38 +++++++
 .../gas/scfi/x86_64/scfi-indirect-mov-3.d     |  41 +++++++
 .../gas/scfi/x86_64/scfi-indirect-mov-3.l     |   2 +
 .../gas/scfi/x86_64/scfi-indirect-mov-3.s     |  38 +++++++
 .../gas/scfi/x86_64/scfi-indirect-mov-4.d     |  63 +++++++++++
 .../gas/scfi/x86_64/scfi-indirect-mov-4.l     |   3 +
 .../gas/scfi/x86_64/scfi-indirect-mov-4.s     |  68 ++++++++++++
 gas/testsuite/gas/scfi/x86_64/scfi-lea-1.d    |  37 +++++++
 gas/testsuite/gas/scfi/x86_64/scfi-lea-1.l    |   2 +
 gas/testsuite/gas/scfi/x86_64/scfi-lea-1.s    |  40 +++++++
 gas/testsuite/gas/scfi/x86_64/scfi-leave-1.d  |  36 ++++++
 gas/testsuite/gas/scfi/x86_64/scfi-leave-1.l  |   2 +
 gas/testsuite/gas/scfi/x86_64/scfi-leave-1.s  |  26 +++++
 gas/testsuite/gas/scfi/x86_64/scfi-pushq-1.d  |  35 ++++++
 gas/testsuite/gas/scfi/x86_64/scfi-pushq-1.l  |   2 +
 gas/testsuite/gas/scfi/x86_64/scfi-pushq-1.s  |  24 ++++
 .../gas/scfi/x86_64/scfi-pushsection-1.d      |  43 ++++++++
 .../gas/scfi/x86_64/scfi-pushsection-1.l      |   2 +
 .../gas/scfi/x86_64/scfi-pushsection-1.s      |  40 +++++++
 .../gas/scfi/x86_64/scfi-pushsection-2.d      |  39 +++++++
 .../gas/scfi/x86_64/scfi-pushsection-2.l      |   2 +
 .../gas/scfi/x86_64/scfi-pushsection-2.s      |  38 +++++++
 .../gas/scfi/x86_64/scfi-selfalign-func-1.d   |  31 ++++++
 .../gas/scfi/x86_64/scfi-selfalign-func-1.l   |   2 +
 .../gas/scfi/x86_64/scfi-selfalign-func-1.s   |  36 ++++++
 gas/testsuite/gas/scfi/x86_64/scfi-simple-1.d |  26 +++++
 gas/testsuite/gas/scfi/x86_64/scfi-simple-1.l |   2 +
 gas/testsuite/gas/scfi/x86_64/scfi-simple-1.s |  15 +++
 gas/testsuite/gas/scfi/x86_64/scfi-simple-2.d |  30 +++++
 gas/testsuite/gas/scfi/x86_64/scfi-simple-2.l |   2 +
 gas/testsuite/gas/scfi/x86_64/scfi-simple-2.s |  16 +++
 gas/testsuite/gas/scfi/x86_64/scfi-sub-1.d    |  25 +++++
 gas/testsuite/gas/scfi/x86_64/scfi-sub-1.l    |   2 +
 gas/testsuite/gas/scfi/x86_64/scfi-sub-1.s    |  12 ++
 gas/testsuite/gas/scfi/x86_64/scfi-sub-2.d    |  31 ++++++
 gas/testsuite/gas/scfi/x86_64/scfi-sub-2.l    |   2 +
 gas/testsuite/gas/scfi/x86_64/scfi-sub-2.s    |  29 +++++
 .../gas/scfi/x86_64/scfi-unsupported-1.l      |   2 +
 .../gas/scfi/x86_64/scfi-unsupported-1.s      |  10 ++
 .../gas/scfi/x86_64/scfi-unsupported-2.l      |   3 +
 .../gas/scfi/x86_64/scfi-unsupported-2.s      |  14 +++
 .../gas/scfi/x86_64/scfi-unsupported-3.l      |   3 +
 .../gas/scfi/x86_64/scfi-unsupported-3.s      |  14 +++
 .../gas/scfi/x86_64/scfi-unsupported-4.l      |   4 +
 .../gas/scfi/x86_64/scfi-unsupported-4.s      |  23 ++++
 .../gas/scfi/x86_64/scfi-unsupported-cfg-1.l  |   3 +
 .../gas/scfi/x86_64/scfi-unsupported-cfg-1.s  |  53 +++++++++
 .../gas/scfi/x86_64/scfi-unsupported-drap-1.l |   4 +
 .../gas/scfi/x86_64/scfi-unsupported-drap-1.s |  75 +++++++++++++
 gas/testsuite/gas/scfi/x86_64/scfi-x86-64.exp | 103 ++++++++++++++++++
 113 files changed, 2604 insertions(+)
 create mode 100644 gas/testsuite/gas/scfi/README
 create mode 100644 gas/testsuite/gas/scfi/x86_64/scfi-add-1.d
 create mode 100644 gas/testsuite/gas/scfi/x86_64/scfi-add-1.l
 create mode 100644 gas/testsuite/gas/scfi/x86_64/scfi-add-1.s
 create mode 100644 gas/testsuite/gas/scfi/x86_64/scfi-add-2.d
 create mode 100644 gas/testsuite/gas/scfi/x86_64/scfi-add-2.l
 create mode 100644 gas/testsuite/gas/scfi/x86_64/scfi-add-2.s
 create mode 100644 gas/testsuite/gas/scfi/x86_64/scfi-asm-marker-1.d
 create mode 100644 gas/testsuite/gas/scfi/x86_64/scfi-asm-marker-1.l
 create mode 100644 gas/testsuite/gas/scfi/x86_64/scfi-asm-marker-1.s
 create mode 100644 gas/testsuite/gas/scfi/x86_64/scfi-asm-marker-2.d
 create mode 100644 gas/testsuite/gas/scfi/x86_64/scfi-asm-marker-2.l
 create mode 100644 gas/testsuite/gas/scfi/x86_64/scfi-asm-marker-2.s
 create mode 100644 gas/testsuite/gas/scfi/x86_64/scfi-asm-marker-3.d
 create mode 100644 gas/testsuite/gas/scfi/x86_64/scfi-asm-marker-3.l
 create mode 100644 gas/testsuite/gas/scfi/x86_64/scfi-asm-marker-3.s
 create mode 100644 gas/testsuite/gas/scfi/x86_64/scfi-bp-sp-1.d
 create mode 100644 gas/testsuite/gas/scfi/x86_64/scfi-bp-sp-1.l
 create mode 100644 gas/testsuite/gas/scfi/x86_64/scfi-bp-sp-1.s
 create mode 100644 gas/testsuite/gas/scfi/x86_64/scfi-bp-sp-2.d
 create mode 100644 gas/testsuite/gas/scfi/x86_64/scfi-bp-sp-2.l
 create mode 100644 gas/testsuite/gas/scfi/x86_64/scfi-bp-sp-2.s
 create mode 100644 gas/testsuite/gas/scfi/x86_64/scfi-callee-saved-1.d
 create mode 100644 gas/testsuite/gas/scfi/x86_64/scfi-callee-saved-1.l
 create mode 100644 gas/testsuite/gas/scfi/x86_64/scfi-callee-saved-1.s
 create mode 100644 gas/testsuite/gas/scfi/x86_64/scfi-callee-saved-2.d
 create mode 100644 gas/testsuite/gas/scfi/x86_64/scfi-callee-saved-2.l
 create mode 100644 gas/testsuite/gas/scfi/x86_64/scfi-callee-saved-2.s
 create mode 100644 gas/testsuite/gas/scfi/x86_64/scfi-callee-saved-3.d
 create mode 100644 gas/testsuite/gas/scfi/x86_64/scfi-callee-saved-3.l
 create mode 100644 gas/testsuite/gas/scfi/x86_64/scfi-callee-saved-3.s
 create mode 100644 gas/testsuite/gas/scfi/x86_64/scfi-callee-saved-4.d
 create mode 100644 gas/testsuite/gas/scfi/x86_64/scfi-callee-saved-4.l
 create mode 100644 gas/testsuite/gas/scfi/x86_64/scfi-callee-saved-4.s
 create mode 100644 gas/testsuite/gas/scfi/x86_64/scfi-cfg-1.d
 create mode 100644 gas/testsuite/gas/scfi/x86_64/scfi-cfg-1.l
 create mode 100644 gas/testsuite/gas/scfi/x86_64/scfi-cfg-1.s
 create mode 100644 gas/testsuite/gas/scfi/x86_64/scfi-cfg-2.d
 create mode 100644 gas/testsuite/gas/scfi/x86_64/scfi-cfg-2.l
 create mode 100644 gas/testsuite/gas/scfi/x86_64/scfi-cfg-2.s
 create mode 100644 gas/testsuite/gas/scfi/x86_64/scfi-cfi-label-1.d
 create mode 100644 gas/testsuite/gas/scfi/x86_64/scfi-cfi-label-1.l
 create mode 100644 gas/testsuite/gas/scfi/x86_64/scfi-cfi-label-1.s
 create mode 100644 gas/testsuite/gas/scfi/x86_64/scfi-cofi-1.d
 create mode 100644 gas/testsuite/gas/scfi/x86_64/scfi-cofi-1.l
 create mode 100644 gas/testsuite/gas/scfi/x86_64/scfi-cofi-1.s
 create mode 100644 gas/testsuite/gas/scfi/x86_64/scfi-diag-1.l
 create mode 100644 gas/testsuite/gas/scfi/x86_64/scfi-diag-1.s
 create mode 100644 gas/testsuite/gas/scfi/x86_64/scfi-diag-2.l
 create mode 100644 gas/testsuite/gas/scfi/x86_64/scfi-diag-2.s
 create mode 100644 gas/testsuite/gas/scfi/x86_64/scfi-dyn-stack-1.d
 create mode 100644 gas/testsuite/gas/scfi/x86_64/scfi-dyn-stack-1.l
 create mode 100644 gas/testsuite/gas/scfi/x86_64/scfi-dyn-stack-1.s
 create mode 100644 gas/testsuite/gas/scfi/x86_64/scfi-fp-diag-2.l
 create mode 100644 gas/testsuite/gas/scfi/x86_64/scfi-fp-diag-2.s
 create mode 100644 gas/testsuite/gas/scfi/x86_64/scfi-ignore-1.d
 create mode 100644 gas/testsuite/gas/scfi/x86_64/scfi-ignore-1.l
 create mode 100644 gas/testsuite/gas/scfi/x86_64/scfi-ignore-1.s
 create mode 100644 gas/testsuite/gas/scfi/x86_64/scfi-indirect-mov-1.d
 create mode 100644 gas/testsuite/gas/scfi/x86_64/scfi-indirect-mov-1.l
 create mode 100644 gas/testsuite/gas/scfi/x86_64/scfi-indirect-mov-1.s
 create mode 100644 gas/testsuite/gas/scfi/x86_64/scfi-indirect-mov-2.d
 create mode 100644 gas/testsuite/gas/scfi/x86_64/scfi-indirect-mov-2.l
 create mode 100644 gas/testsuite/gas/scfi/x86_64/scfi-indirect-mov-2.s
 create mode 100644 gas/testsuite/gas/scfi/x86_64/scfi-indirect-mov-3.d
 create mode 100644 gas/testsuite/gas/scfi/x86_64/scfi-indirect-mov-3.l
 create mode 100644 gas/testsuite/gas/scfi/x86_64/scfi-indirect-mov-3.s
 create mode 100644 gas/testsuite/gas/scfi/x86_64/scfi-indirect-mov-4.d
 create mode 100644 gas/testsuite/gas/scfi/x86_64/scfi-indirect-mov-4.l
 create mode 100644 gas/testsuite/gas/scfi/x86_64/scfi-indirect-mov-4.s
 create mode 100644 gas/testsuite/gas/scfi/x86_64/scfi-lea-1.d
 create mode 100644 gas/testsuite/gas/scfi/x86_64/scfi-lea-1.l
 create mode 100644 gas/testsuite/gas/scfi/x86_64/scfi-lea-1.s
 create mode 100644 gas/testsuite/gas/scfi/x86_64/scfi-leave-1.d
 create mode 100644 gas/testsuite/gas/scfi/x86_64/scfi-leave-1.l
 create mode 100644 gas/testsuite/gas/scfi/x86_64/scfi-leave-1.s
 create mode 100644 gas/testsuite/gas/scfi/x86_64/scfi-pushq-1.d
 create mode 100644 gas/testsuite/gas/scfi/x86_64/scfi-pushq-1.l
 create mode 100644 gas/testsuite/gas/scfi/x86_64/scfi-pushq-1.s
 create mode 100644 gas/testsuite/gas/scfi/x86_64/scfi-pushsection-1.d
 create mode 100644 gas/testsuite/gas/scfi/x86_64/scfi-pushsection-1.l
 create mode 100644 gas/testsuite/gas/scfi/x86_64/scfi-pushsection-1.s
 create mode 100644 gas/testsuite/gas/scfi/x86_64/scfi-pushsection-2.d
 create mode 100644 gas/testsuite/gas/scfi/x86_64/scfi-pushsection-2.l
 create mode 100644 gas/testsuite/gas/scfi/x86_64/scfi-pushsection-2.s
 create mode 100644 gas/testsuite/gas/scfi/x86_64/scfi-selfalign-func-1.d
 create mode 100644 gas/testsuite/gas/scfi/x86_64/scfi-selfalign-func-1.l
 create mode 100644 gas/testsuite/gas/scfi/x86_64/scfi-selfalign-func-1.s
 create mode 100644 gas/testsuite/gas/scfi/x86_64/scfi-simple-1.d
 create mode 100644 gas/testsuite/gas/scfi/x86_64/scfi-simple-1.l
 create mode 100644 gas/testsuite/gas/scfi/x86_64/scfi-simple-1.s
 create mode 100644 gas/testsuite/gas/scfi/x86_64/scfi-simple-2.d
 create mode 100644 gas/testsuite/gas/scfi/x86_64/scfi-simple-2.l
 create mode 100644 gas/testsuite/gas/scfi/x86_64/scfi-simple-2.s
 create mode 100644 gas/testsuite/gas/scfi/x86_64/scfi-sub-1.d
 create mode 100644 gas/testsuite/gas/scfi/x86_64/scfi-sub-1.l
 create mode 100644 gas/testsuite/gas/scfi/x86_64/scfi-sub-1.s
 create mode 100644 gas/testsuite/gas/scfi/x86_64/scfi-sub-2.d
 create mode 100644 gas/testsuite/gas/scfi/x86_64/scfi-sub-2.l
 create mode 100644 gas/testsuite/gas/scfi/x86_64/scfi-sub-2.s
 create mode 100644 gas/testsuite/gas/scfi/x86_64/scfi-unsupported-1.l
 create mode 100644 gas/testsuite/gas/scfi/x86_64/scfi-unsupported-1.s
 create mode 100644 gas/testsuite/gas/scfi/x86_64/scfi-unsupported-2.l
 create mode 100644 gas/testsuite/gas/scfi/x86_64/scfi-unsupported-2.s
 create mode 100644 gas/testsuite/gas/scfi/x86_64/scfi-unsupported-3.l
 create mode 100644 gas/testsuite/gas/scfi/x86_64/scfi-unsupported-3.s
 create mode 100644 gas/testsuite/gas/scfi/x86_64/scfi-unsupported-4.l
 create mode 100644 gas/testsuite/gas/scfi/x86_64/scfi-unsupported-4.s
 create mode 100644 gas/testsuite/gas/scfi/x86_64/scfi-unsupported-cfg-1.l
 create mode 100644 gas/testsuite/gas/scfi/x86_64/scfi-unsupported-cfg-1.s
 create mode 100644 gas/testsuite/gas/scfi/x86_64/scfi-unsupported-drap-1.l
 create mode 100644 gas/testsuite/gas/scfi/x86_64/scfi-unsupported-drap-1.s
 create mode 100644 gas/testsuite/gas/scfi/x86_64/scfi-x86-64.exp
  

Comments

Jan Beulich Oct. 31, 2023, 4:13 p.m. UTC | #1
On 30.10.2023 17:51, Indu Bhagat wrote:
> --- /dev/null
> +++ b/gas/testsuite/gas/scfi/x86_64/scfi-add-2.s
> @@ -0,0 +1,48 @@
> +        .section        .rodata
> +	.type	simd_cmp_op, @object
> +	.size	simd_cmp_op, 8
> +simd_cmp_op:
> +	.long	2
> +	.zero	4
> +
> +# Testcase for add instruction.
> +# add reg, reg instruction
> +	.text
> +	.globl	foo
> +	.type	foo, @function
> +foo:
> +	.cfi_startproc
> +	pushq	%rbp
> +	.cfi_def_cfa_offset 16
> +	.cfi_offset 6, -16
> +	movq    %rsp, %rbp
> +	.cfi_def_cfa_register 6
> +	pushq	%r12
> +	.cfi_offset 12, -24
> +	mov	%rsp, %r12

You copy %rsp to %r12 here, and ...

> +# Stack manipulation is permitted if the base register for
> +# tracking CFA has been changed to FP.
> +	addq    %rdx, %rsp
> +	addq	%rsp, %rax
> +# Some add instructions may access the stack indirectly.  Such
> +# accesses do not make REG_FP untraceable.
> +	addl    %eax, -84(%rbp)
> +# Other kind of add instructions should not error out in the
> +# x86_64 -> ginsn translator
> +	addq    $simd_cmp_op+8, %rdx
> +	addl    %edx, -32(%rsp)
> +	addl    $1, fb_low_counter(,%rbx,4)
> +	mov	%r12, %rsp

... you restore it here, but both without any .cfi_* annotation.
It is therefore unclear whether this is in any way related to ...

> +# Popping a callee-saved register.
> +# RSP must be traceable.
> +	pop     %r12
> +	.cfi_restore 12

... what the comment says about these.

> +	leave
> +	.cfi_def_cfa_register 7
> +	.cfi_restore 6

Using numbers here isn't very helpful, I'm afraid.

> --- /dev/null
> +++ b/gas/testsuite/gas/scfi/x86_64/scfi-asm-marker-1.s
> @@ -0,0 +1,27 @@
> +# Testcase where a user may define hot and cold areas of function
> +# Note how the .type, and .size directives may be placed differently
> +# than a regular function.
> +
> +	.globl  foo
> +	.type   foo, @function
> +foo:
> +        .cfi_startproc
> +        testl   %edi, %edi
> +        je      .L3
> +        movl    b(%rip), %eax
> +        ret
> +        .cfi_endproc
> +        .section        .text.unlikely
> +        .cfi_startproc
> +        .type   foo.cold, @function
> +foo.cold:
> +.L3:
> +        pushq   %rax
> +        .cfi_def_cfa_offset 16
> +        call    abort
> +       .cfi_endproc
> +.LFE11:
> +        .text
> +        .size   foo, .-foo
> +        .section        .text.unlikely
> +        .size   foo.cold, .-foo.cold

Related to the comment: Is it "may" or is it rather "need to"?
(In the latter case it would be yet another constraint on when this
new machinery is actually usable.)

> --- /dev/null
> +++ b/gas/testsuite/gas/scfi/x86_64/scfi-asm-marker-2.s
> @@ -0,0 +1,11 @@
> +# A programmer may not bother to set the size of the 
> +# function symbols via an explicit .size directive.
> +	.globl  foo
> +	.type   foo, @function
> +foo:
> +        .cfi_startproc
> +        testl   %edi, %edi
> +        je      .L3
> +        movl    b(%rip), %eax
> +        ret
> +       .cfi_endproc

Wasn't it said elsewhere that .size needs using after the function?

> --- /dev/null
> +++ b/gas/testsuite/gas/scfi/x86_64/scfi-asm-marker-3.l
> @@ -0,0 +1,2 @@
> +.*Assembler messages:
> +.*9: Warning: --scfi=all ignores some user-specified CFI directives

Is repeating this for (about?) every test really necessary / useful?
If multiple passes for every test were to make sense to me, I'd expect
one pass with SCFI and one pass without, where the directives then
take effect. And then the same set of expectations should match.

> --- /dev/null
> +++ b/gas/testsuite/gas/scfi/x86_64/scfi-bp-sp-2.s
> @@ -0,0 +1,49 @@
> +# Testcase for switching between sp/fp based CFA.
> +	.text
> +	.globl	foo
> +	.type	foo, @function
> +foo:
> +        .cfi_startproc
> +        pushq   %r14
> +        .cfi_def_cfa_offset 16
> +        .cfi_offset 14, -16
> +        pushq   %r13
> +        .cfi_def_cfa_offset 24
> +        .cfi_offset 13, -24
> +        pushq   %r12
> +        .cfi_def_cfa_offset 32
> +        .cfi_offset 12, -32
> +        pushq   %rbp
> +        .cfi_def_cfa_offset 40
> +        .cfi_offset 6, -40
> +        pushq   %rbx
> +        .cfi_def_cfa_offset 48
> +        .cfi_offset 3, -48
> +        movq    %rdi, %rbx
> +        subq    $32, %rsp
> +        .cfi_def_cfa_offset 80
> +# This mov does not switch CFA tracking to REG_FP, because there has already
> +# been stack usage between here and the push %rbp
> +        movq    %rsp, %rbp

Yet another constraint?

> +        xorl    %eax, %eax
> +        addq    $32, %rsp
> +        .cfi_def_cfa_offset 48
> +        popq    %rbx
> +	.cfi_restore 3

Nit: inconsistent indentation (also elsewhere).

> --- /dev/null
> +++ b/gas/testsuite/gas/scfi/x86_64/scfi-callee-saved-1.s
> @@ -0,0 +1,26 @@
> +	.text
> +	.globl	foo
> +	.type	foo, @function
> +foo:
> +#	.cfi_startproc
> +	pushq	%rax
> +	.cfi_def_cfa_offset 16
> +	push	%rbx
> +	.cfi_def_cfa_offset 24
> +	.cfi_offset 3, -24
> +	pushq	%rbp
> +        .cfi_def_cfa_offset 32
> +        .cfi_offset 6, -32
> +	popq	%rbp
> +	.cfi_def_cfa_offset 24
> +	.cfi_restore 6
> +	popq	%rbx
> +	.cfi_def_cfa_offset 16
> +	.cfi_restore 3
> +	popq	%rax
> +        .cfi_def_cfa_offset 8
> +	ret
> +#	.cfi_endproc

Why are startproc/endproc commented out here?

> --- /dev/null
> +++ b/gas/testsuite/gas/scfi/x86_64/scfi-callee-saved-2.s
> @@ -0,0 +1,42 @@
> +# Testcase for save reg ops for callee-saved registers
> +# These latter two pushq's of callee-saved regs must NOT generate
> +# .cfi_offset.
> +
> +	.text
> +	.globl	foo
> +	.type	foo, @function
> +foo:
> +	.cfi_startproc
> +	pushq	%r12
> +	.cfi_def_cfa_offset 16
> +	.cfi_offset 12, -16
> +	pushq	%r13
> +	.cfi_def_cfa_offset 24
> +	.cfi_offset 13, -24
> +# The function may use callee-saved registers for its use, and may even
> +# chose to spill them to stack if necessary.
> +	addq    %rax, %r13
> +	subq 	$8, %r13
> +# These two pushq's of callee-saved regs must NOT generate
> +# .cfi_offset.
> +	pushq	%r13
> +	.cfi_def_cfa_offset 32
> +	pushq	%rax
> +	.cfi_def_cfa_offset 40

Why "two" in the comment? %rax isn't callee-saved, is it? (Same in
variant 3 of this kind of test then.)

> --- /dev/null
> +++ b/gas/testsuite/gas/scfi/x86_64/scfi-callee-saved-4.s
> @@ -0,0 +1,55 @@
> +	.type	byte_insert_op1, @function
> +byte_insert_op1:
> +.LFB10:
> +	.cfi_startproc
> +	endbr64
> +	pushq	%rbp
> +	.cfi_def_cfa_offset 16
> +	.cfi_offset 6, -16
> +	movq	%rsp, %rbp
> +	.cfi_def_cfa_register 6
> +	pushq	%r12
> +	.cfi_offset 12, -24
> +	pushq	%rbx
> +	.cfi_offset 3, -32
> +	subq	$24, %rsp
> +	movl	%edi, -20(%rbp)
> +	movq	%rsi, -32(%rbp)
> +	movl	%edx, -24(%rbp)
> +	movq	%rcx, -40(%rbp)
> +# The program may use callee-saved registers for its use, and may even
> +# chose to read them from stack if necessary.  The following use should
> +# not be treated as reg restore for SCFI purposes (because rbx has been
> +# saved to -16(%rbp).

But even if the value was read back from -16(%rbp) you wouldn't know for
sure that that's the ultimate restore. Yet another constraint?

> --- /dev/null
> +++ b/gas/testsuite/gas/scfi/x86_64/scfi-cfg-1.d
> @@ -0,0 +1,36 @@
> +#as: --scfi -W
> +#objdump: -Wf
> +#name: Synthesize CFI in presence of control flow 1
> +#...
> +Contents of the .eh_frame section:
> +
> +00000000 0+0014 0+0000 CIE
> +  Version:               1
> +  Augmentation:          "zR"
> +  Code alignment factor: 1
> +  Data alignment factor: -8
> +  Return address column: 16
> +  Augmentation data:     [01][abc]
> +  DW_CFA_def_cfa: r7 \(rsp\) ofs 8
> +  DW_CFA_offset: r16 \(rip\) at cfa-8
> +  DW_CFA_nop
> +  DW_CFA_nop
> +
> +0+0018 0+0024 0000001c FDE cie=00000000 pc=0+0000..0+003a
> +  DW_CFA_advance_loc: 1 to 0+0001
> +  DW_CFA_def_cfa_offset: 16
> +  DW_CFA_offset: r3 \(rbx\) at cfa-16
> +  DW_CFA_advance_loc: 37 to 0+0026
> +  DW_CFA_remember_state
> +  DW_CFA_advance_loc: 1 to 0+0027
> +  DW_CFA_restore: r3 \(rbx\)
> +  DW_CFA_def_cfa_offset: 8
> +  DW_CFA_advance_loc: 1 to 0+0028
> +  DW_CFA_restore_state
> +  DW_CFA_advance_loc: 9 to 0+0031
> +  DW_CFA_restore: r3 \(rbx\)
> +  DW_CFA_def_cfa_offset: 8
> +  DW_CFA_nop
> +#...
> +
> +#pass

Seeing this recurring pattern (the last three lines): Why not just #pass?

> --- /dev/null
> +++ b/gas/testsuite/gas/scfi/x86_64/scfi-cfg-1.s
> @@ -0,0 +1,47 @@
> +# Testcase with one dominator bb and two exit bbs
> +# Something like for: return ferror (f) || fclose (f) != 0;
> +	.text
> +	.section	.rodata.str1.1,"aMS",@progbits,1
> +.LC0:
> +	.string	"w"
> +.LC1:
> +	.string	"conftest.out"
> +	.section	.text.startup,"ax",@progbits
> +	.p2align 4
> +	.globl	main
> +	.type	main, @function
> +main:
> +.LFB11:

Coming back to "hand-written assembly": The above looks very much like it
was compiler output (earlier tests did, too, but it's perhaps more
prominent here). That's not necessarily what a human might write, and
hence I wonder about the overall coverage that can be gained that way.

> --- /dev/null
> +++ b/gas/testsuite/gas/scfi/x86_64/scfi-cofi-1.d
> @@ -0,0 +1,5 @@
> +#as: --scfi -W
> +#objdump: -Wf
> +#name: Synthesize CFI for add insn
> +
> +#pass
> --- /dev/null
> +++ b/gas/testsuite/gas/scfi/x86_64/scfi-cofi-1.l
> @@ -0,0 +1,3 @@
> +.*Assembler messages:
> +.*12: Warning: --scfi=all ignores some user-specified CFI directives
> +.*22: Warning: Untraceable control flow for func 'foo'; Skipping SCFI
> --- /dev/null
> +++ b/gas/testsuite/gas/scfi/x86_64/scfi-cofi-1.s
> @@ -0,0 +1,23 @@
> +# Testcase with a variety of "change of flow instructions"
> +#
> +# Must be run with -W so it remains warning free.
> +#
> +# This test does not have much going on wrt synthesis of CFI;
> +# it just aims to ensure x8_64 -> ginsn decoding must behave
> +# gracefully for these "change of flow instructions"
> +	.text
> +	.globl	foo
> +	.type	foo, @function
> +foo:
> +	.cfi_startproc
> +	addq    %rdx, %rax
> +	notrack jmp     *%rax
> +	call   *%r8
> +	jmp     *48(%rdi)
> +	jo      .L179
> +.L179:
> +	ret
> +	.cfi_endproc
> +.LFE0:
> +	.size	foo, .-foo

What exactly is being tested here? The .d file is effectively empty,
and the .l file expects a warning on the .size directive (which tells
about nothing regarding the reason for the failure to produce SCFI).

> --- /dev/null
> +++ b/gas/testsuite/gas/scfi/x86_64/scfi-diag-1.s
> @@ -0,0 +1,23 @@
> +# Testcase for REG_FP based CFA
> +# and using REG_FP as scratch.
> +	.text
> +	.globl	foo
> +	.type	foo, @function
> +foo:
> +	.cfi_startproc
> +	pushq	%rbp
> +	.cfi_def_cfa_offset 16
> +	.cfi_offset 6, -16
> +	movq    %rsp, %rbp
> +	.cfi_def_cfa_register 6
> +# The following add causes REG_FP to become untraceable
> +	addq	%rax, %rbp

But this isn't a problem as long as FP isn't further used. Indeed ...

> +	.cfi_def_cfa_register 7
> +	pop	%rbp

... its original value is restored right afterwards. Yet another constraint?

> --- /dev/null
> +++ b/gas/testsuite/gas/scfi/x86_64/scfi-fp-diag-2.s
> @@ -0,0 +1,55 @@
> +# Testcase for a diagnostic around assymetrical restore
> +# Testcase inspired by byte_insert_op1 in libiberty
> +# False positive for the diagnostic
> +.type	foo, @function
> +foo:
> +.LFB10:
> +	.cfi_startproc
> +	endbr64
> +	pushq	%rbp
> +	.cfi_def_cfa_offset 16
> +	.cfi_offset 6, -16
> +	movq	%rsp, %rbp
> +	.cfi_def_cfa_register 6
> +	pushq	%r12
> +	pushq	%rbx
> +	subq	$24, %rsp
> +	.cfi_offset 12, -24
> +	.cfi_offset 3, -32
> +	movl	%edi, -20(%rbp)
> +	movq	%rsi, -32(%rbp)
> +	movl	%edx, -24(%rbp)
> +	movq	%rcx, -40(%rbp)
> +# The assembler cannot differentiate that the following
> +# mov to %rbx is not a true restore operation, but simply
> +# %rbx register usage as a scratch reg of some sort.
> +# The assembler merely warns of a possible assymetric restore operation
> +# In this case, its noise for the user unfortunately.
> +	movq	-40(%rbp), %rbx
> +	movq	-40(%rbp), %rax
> +	leaq	3(%rax), %r12
> +	jmp	.L563
> +.L564:
> +	subq	$1, %rbx
> +	subq	$1, %r12
> +	movzbl	(%rbx), %eax
> +	movb	%al, (%r12)
> +.L563:
> +	cmpq	-32(%rbp), %rbx
> +	jne	.L564

But this is pretty common usage. Imo this (the false positive warning)
cannot remain like this.

> --- /dev/null
> +++ b/gas/testsuite/gas/scfi/x86_64/scfi-ignore-1.s
> @@ -0,0 +1,13 @@
> +	.text
> +	.globl	foo
> +	.type	foo, @function
> +foo:
> +	.cfi_startproc
> +	pushq	%rbp
> +        .cfi_def_cfa_offset 16
> +        .cfi_offset 6, -16
> +	ret
> +	.cfi_endproc
> +.LFE0:
> +	.size	foo, .-foo

This, otoh, imo wants diagnosing. The framework ought to recognize that
the RET doesn't use the correct stack slot.

Additionally, isn't scfi-simple-1.s effectively testing the same? The
code at least looks extremely similar.

> --- /dev/null
> +++ b/gas/testsuite/gas/scfi/x86_64/scfi-unsupported-1.l
> @@ -0,0 +1,2 @@
> +Assembler messages:
> +Fatal error: Synthesizing CFI is not supported for this ABI
> diff --git a/gas/testsuite/gas/scfi/x86_64/scfi-unsupported-1.s b/gas/testsuite/gas/scfi/x86_64/scfi-unsupported-1.s
> new file mode 100644
> index 00000000000..87d2a4971a1
> --- /dev/null
> +++ b/gas/testsuite/gas/scfi/x86_64/scfi-unsupported-1.s
> @@ -0,0 +1,10 @@
> +# Testcase run with --m32 (Not supported).
> +	.text
> +	.globl	foo
> +	.type	foo, @function
> +foo:
> +	pushq	%rbp

This code, being built with --32, is bogus anyway. I wonder why this file
has any insns in the first place.

> --- /dev/null
> +++ b/gas/testsuite/gas/scfi/x86_64/scfi-x86-64.exp
> @@ -0,0 +1,103 @@
> +# Copyright (C) 2022-2023 Free Software Foundation, Inc.
> +
> +# This program is free software; you can redistribute it and/or modify
> +# it under the terms of the GNU General Public License as published by
> +# the Free Software Foundation; either version 3 of the License, or
> +# (at your option) any later version.
> +#
> +# This program is distributed in the hope that it will be useful,
> +# but WITHOUT ANY WARRANTY; without even the implied warranty of
> +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> +# GNU General Public License for more details.
> +#
> +# You should have received a copy of the GNU General Public License
> +# along with this program; if not, write to the Free Software
> +# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
> +
> +if { ![is_elf_format] } then {
> +    return
> +}
> +
> +# common tests
> +if  { ([istarget "x86_64-*-*"]) } then {
> +
> +    global ASFLAGS
> +    set old_ASFLAGS "$ASFLAGS"
> +
> +    run_dump_test "scfi-cfi-label-1"
> +    run_list_test "scfi-cfi-label-1" "--scfi --warn"
> +
> +    run_list_test "scfi-diag-1" "--scfi"
> +    run_list_test "scfi-fp-diag-2" "--scfi"
> +    run_list_test "scfi-diag-2" "--scfi"
> +
> +    run_list_test "scfi-unsupported-1" "--32 --scfi"

Perhaps a 2nd run with --x32, unless (see above) you choose to support
that ABI as well?

Jan
  
Indu Bhagat Nov. 1, 2023, 6:24 a.m. UTC | #2
Hi Jan,

Thanks for reviewing.

On 10/31/23 09:13, Jan Beulich wrote:
> On 30.10.2023 17:51, Indu Bhagat wrote:
>> --- /dev/null
>> +++ b/gas/testsuite/gas/scfi/x86_64/scfi-add-2.s
>> @@ -0,0 +1,48 @@
>> +        .section        .rodata
>> +	.type	simd_cmp_op, @object
>> +	.size	simd_cmp_op, 8
>> +simd_cmp_op:
>> +	.long	2
>> +	.zero	4
>> +
>> +# Testcase for add instruction.
>> +# add reg, reg instruction
>> +	.text
>> +	.globl	foo
>> +	.type	foo, @function
>> +foo:
>> +	.cfi_startproc
>> +	pushq	%rbp
>> +	.cfi_def_cfa_offset 16
>> +	.cfi_offset 6, -16
>> +	movq    %rsp, %rbp
>> +	.cfi_def_cfa_register 6
>> +	pushq	%r12
>> +	.cfi_offset 12, -24
>> +	mov	%rsp, %r12
> 
> You copy %rsp to %r12 here, and ...
> 
>> +# Stack manipulation is permitted if the base register for
>> +# tracking CFA has been changed to FP.
>> +	addq    %rdx, %rsp
>> +	addq	%rsp, %rax
>> +# Some add instructions may access the stack indirectly.  Such
>> +# accesses do not make REG_FP untraceable.
>> +	addl    %eax, -84(%rbp)
>> +# Other kind of add instructions should not error out in the
>> +# x86_64 -> ginsn translator
>> +	addq    $simd_cmp_op+8, %rdx
>> +	addl    %edx, -32(%rsp)
>> +	addl    $1, fb_low_counter(,%rbx,4)
>> +	mov	%r12, %rsp
> 
> ... you restore it here, but both without any .cfi_* annotation.
> It is therefore unclear whether this is in any way related to ...
> 

There are no .cfi_* annotations for the %rsp updates here because the 
CFA tracking has already been switched to REG_FP based tracking.  From 
the perspective of DWARF CFI, this usages of the stack do not need to 
tracked.  If unwinding happens from any instruction in the above 
sequence, we already have the correct and complete unwind information.

>> +# Popping a callee-saved register.
>> +# RSP must be traceable.
>> +	pop     %r12
>> +	.cfi_restore 12
> 
> ... what the comment says about these.
> 

The comment here means that hand-written programs may use stack for 
their local usage etc. but must ensure that before or in the epilogue, 
rsp is restored to the desired value (before register restores via pop 
instructions).

This is not a special handling in the SCFI machinery but it is what is 
needed to ensure correctness of the function.  For asm not adhering to 
the ABI/calling conventions, SCFI cannot be used.

>> +	leave
>> +	.cfi_def_cfa_register 7
>> +	.cfi_restore 6
> 
> Using numbers here isn't very helpful, I'm afraid.
> 

I am not sure I understand.  The DWARF register numbers and the offset 
values are required by the semantics of those CFI directives.

>> --- /dev/null
>> +++ b/gas/testsuite/gas/scfi/x86_64/scfi-asm-marker-1.s
>> @@ -0,0 +1,27 @@
>> +# Testcase where a user may define hot and cold areas of function
>> +# Note how the .type, and .size directives may be placed differently
>> +# than a regular function.
>> +
>> +	.globl  foo
>> +	.type   foo, @function
>> +foo:
>> +        .cfi_startproc
>> +        testl   %edi, %edi
>> +        je      .L3
>> +        movl    b(%rip), %eax
>> +        ret
>> +        .cfi_endproc
>> +        .section        .text.unlikely
>> +        .cfi_startproc
>> +        .type   foo.cold, @function
>> +foo.cold:
>> +.L3:
>> +        pushq   %rax
>> +        .cfi_def_cfa_offset 16
>> +        call    abort
>> +       .cfi_endproc
>> +.LFE11:
>> +        .text
>> +        .size   foo, .-foo
>> +        .section        .text.unlikely
>> +        .size   foo.cold, .-foo.cold
> 
> Related to the comment: Is it "may" or is it rather "need to"?
> (In the latter case it would be yet another constraint on when this
> new machinery is actually usable.)
> 

The .size directives are not necessary for SCFI.  They are recommended.
In this test, removing the code after .LFE11 should still work, I will 
check this.

>> --- /dev/null
>> +++ b/gas/testsuite/gas/scfi/x86_64/scfi-asm-marker-2.s
>> @@ -0,0 +1,11 @@
>> +# A programmer may not bother to set the size of the
>> +# function symbols via an explicit .size directive.
>> +	.globl  foo
>> +	.type   foo, @function
>> +foo:
>> +        .cfi_startproc
>> +        testl   %edi, %edi
>> +        je      .L3
>> +        movl    b(%rip), %eax
>> +        ret
>> +       .cfi_endproc
> 
> Wasn't it said elsewhere that .size needs using after the function?
> 

Only in the RFC series, the implementation of SCFI required that the 
blocks be closed by using a .size directive.  In the V1 onwards 
implementation, this restriction has been lifted.  This was based on the 
feedback that users may have hand-written asm without the .size directives.

I have tried to correct the code comments and git commit log to reflect 
that .size directive is recommended but not necessary, but perhaps some 
stale text/statement has slipped through. I will fix if I see it.

>> --- /dev/null
>> +++ b/gas/testsuite/gas/scfi/x86_64/scfi-asm-marker-3.l
>> @@ -0,0 +1,2 @@
>> +.*Assembler messages:
>> +.*9: Warning: --scfi=all ignores some user-specified CFI directives
> 
> Is repeating this for (about?) every test really necessary / useful?
> If multiple passes for every test were to make sense to me, I'd expect
> one pass with SCFI and one pass without, where the directives then
> take effect. And then the same set of expectations should match.
> 

re: is repeating this useful? Strictly speaking no. _But_, I think as 
the code evolves, we may add more diagnostics to the SCFI machinery. 
Explicitly checking for the set of warnings helps us ensure no new 
warnings show up where they are not expected. In a way, it is a stricter 
check and ensures no unintented slippage.

>> --- /dev/null
>> +++ b/gas/testsuite/gas/scfi/x86_64/scfi-bp-sp-2.s
>> @@ -0,0 +1,49 @@
>> +# Testcase for switching between sp/fp based CFA.
>> +	.text
>> +	.globl	foo
>> +	.type	foo, @function
>> +foo:
>> +        .cfi_startproc
>> +        pushq   %r14
>> +        .cfi_def_cfa_offset 16
>> +        .cfi_offset 14, -16
>> +        pushq   %r13
>> +        .cfi_def_cfa_offset 24
>> +        .cfi_offset 13, -24
>> +        pushq   %r12
>> +        .cfi_def_cfa_offset 32
>> +        .cfi_offset 12, -32
>> +        pushq   %rbp
>> +        .cfi_def_cfa_offset 40
>> +        .cfi_offset 6, -40
>> +        pushq   %rbx
>> +        .cfi_def_cfa_offset 48
>> +        .cfi_offset 3, -48
>> +        movq    %rdi, %rbx
>> +        subq    $32, %rsp
>> +        .cfi_def_cfa_offset 80
>> +# This mov does not switch CFA tracking to REG_FP, because there has already
>> +# been stack usage between here and the push %rbp
>> +        movq    %rsp, %rbp
> 
> Yet another constraint?
> 

Not sure I understand. This is not a constraint for SCFI.  A pattern 
where the user does:
     push %rbp
     .. more stack usage..
     movq %rsp, %rbp
is not using frame pointer for stack tracing, but simply as a scratch 
register.

So the SCFI machinery simply acknowledges this and does not switch to 
REG_FP based CFA tracking.


>> +        xorl    %eax, %eax
>> +        addq    $32, %rsp
>> +        .cfi_def_cfa_offset 48
>> +        popq    %rbx
>> +	.cfi_restore 3
> 
> Nit: inconsistent indentation (also elsewhere).
> 

I found lots of instances of this issue. Will fix it.

>> --- /dev/null
>> +++ b/gas/testsuite/gas/scfi/x86_64/scfi-callee-saved-1.s
>> @@ -0,0 +1,26 @@
>> +	.text
>> +	.globl	foo
>> +	.type	foo, @function
>> +foo:
>> +#	.cfi_startproc
>> +	pushq	%rax
>> +	.cfi_def_cfa_offset 16
>> +	push	%rbx
>> +	.cfi_def_cfa_offset 24
>> +	.cfi_offset 3, -24
>> +	pushq	%rbp
>> +        .cfi_def_cfa_offset 32
>> +        .cfi_offset 6, -32
>> +	popq	%rbp
>> +	.cfi_def_cfa_offset 24
>> +	.cfi_restore 6
>> +	popq	%rbx
>> +	.cfi_def_cfa_offset 16
>> +	.cfi_restore 3
>> +	popq	%rax
>> +        .cfi_def_cfa_offset 8
>> +	ret
>> +#	.cfi_endproc
> 
> Why are startproc/endproc commented out here?
> 

They are reminiscent of some previous state I had the tests in. I will 
add them back in here and other instances.

>> --- /dev/null
>> +++ b/gas/testsuite/gas/scfi/x86_64/scfi-callee-saved-2.s
>> @@ -0,0 +1,42 @@
>> +# Testcase for save reg ops for callee-saved registers
>> +# These latter two pushq's of callee-saved regs must NOT generate
>> +# .cfi_offset.
>> +
>> +	.text
>> +	.globl	foo
>> +	.type	foo, @function
>> +foo:
>> +	.cfi_startproc
>> +	pushq	%r12
>> +	.cfi_def_cfa_offset 16
>> +	.cfi_offset 12, -16
>> +	pushq	%r13
>> +	.cfi_def_cfa_offset 24
>> +	.cfi_offset 13, -24
>> +# The function may use callee-saved registers for its use, and may even
>> +# chose to spill them to stack if necessary.
>> +	addq    %rax, %r13
>> +	subq 	$8, %r13
>> +# These two pushq's of callee-saved regs must NOT generate
>> +# .cfi_offset.
>> +	pushq	%r13
>> +	.cfi_def_cfa_offset 32
>> +	pushq	%rax
>> +	.cfi_def_cfa_offset 40
> 
> Why "two" in the comment? %rax isn't callee-saved, is it? (Same in
> variant 3 of this kind of test then.)
> 

Correct, %rax is not calee-saved. I will fix the comment.

>> --- /dev/null
>> +++ b/gas/testsuite/gas/scfi/x86_64/scfi-callee-saved-4.s
>> @@ -0,0 +1,55 @@
>> +	.type	byte_insert_op1, @function
>> +byte_insert_op1:
>> +.LFB10:
>> +	.cfi_startproc
>> +	endbr64
>> +	pushq	%rbp
>> +	.cfi_def_cfa_offset 16
>> +	.cfi_offset 6, -16
>> +	movq	%rsp, %rbp
>> +	.cfi_def_cfa_register 6
>> +	pushq	%r12
>> +	.cfi_offset 12, -24
>> +	pushq	%rbx
>> +	.cfi_offset 3, -32
>> +	subq	$24, %rsp
>> +	movl	%edi, -20(%rbp)
>> +	movq	%rsi, -32(%rbp)
>> +	movl	%edx, -24(%rbp)
>> +	movq	%rcx, -40(%rbp)
>> +# The program may use callee-saved registers for its use, and may even
>> +# chose to read them from stack if necessary.  The following use should
>> +# not be treated as reg restore for SCFI purposes (because rbx has been
>> +# saved to -16(%rbp).
> 
> But even if the value was read back from -16(%rbp) you wouldn't know for
> sure that that's the ultimate restore. Yet another constraint?
> 

Correct, we cannot know in GAS that it's the ultimate restore before 
return.  I ask later as well, but the usage of "Yet another constraint" 
expression is not clear to me.

>> --- /dev/null
>> +++ b/gas/testsuite/gas/scfi/x86_64/scfi-cfg-1.d
>> @@ -0,0 +1,36 @@
>> +#as: --scfi -W
>> +#objdump: -Wf
>> +#name: Synthesize CFI in presence of control flow 1
>> +#...
>> +Contents of the .eh_frame section:
>> +
>> +00000000 0+0014 0+0000 CIE
>> +  Version:               1
>> +  Augmentation:          "zR"
>> +  Code alignment factor: 1
>> +  Data alignment factor: -8
>> +  Return address column: 16
>> +  Augmentation data:     [01][abc]
>> +  DW_CFA_def_cfa: r7 \(rsp\) ofs 8
>> +  DW_CFA_offset: r16 \(rip\) at cfa-8
>> +  DW_CFA_nop
>> +  DW_CFA_nop
>> +
>> +0+0018 0+0024 0000001c FDE cie=00000000 pc=0+0000..0+003a
>> +  DW_CFA_advance_loc: 1 to 0+0001
>> +  DW_CFA_def_cfa_offset: 16
>> +  DW_CFA_offset: r3 \(rbx\) at cfa-16
>> +  DW_CFA_advance_loc: 37 to 0+0026
>> +  DW_CFA_remember_state
>> +  DW_CFA_advance_loc: 1 to 0+0027
>> +  DW_CFA_restore: r3 \(rbx\)
>> +  DW_CFA_def_cfa_offset: 8
>> +  DW_CFA_advance_loc: 1 to 0+0028
>> +  DW_CFA_restore_state
>> +  DW_CFA_advance_loc: 9 to 0+0031
>> +  DW_CFA_restore: r3 \(rbx\)
>> +  DW_CFA_def_cfa_offset: 8
>> +  DW_CFA_nop
>> +#...
>> +
>> +#pass
> 
> Seeing this recurring pattern (the last three lines): Why not just #pass?
> 

I thought adding #... is clearer as it indicates that the test knowingly 
skips lines thereafter.

>> --- /dev/null
>> +++ b/gas/testsuite/gas/scfi/x86_64/scfi-cfg-1.s
>> @@ -0,0 +1,47 @@
>> +# Testcase with one dominator bb and two exit bbs
>> +# Something like for: return ferror (f) || fclose (f) != 0;
>> +	.text
>> +	.section	.rodata.str1.1,"aMS",@progbits,1
>> +.LC0:
>> +	.string	"w"
>> +.LC1:
>> +	.string	"conftest.out"
>> +	.section	.text.startup,"ax",@progbits
>> +	.p2align 4
>> +	.globl	main
>> +	.type	main, @function
>> +main:
>> +.LFB11:
> 
> Coming back to "hand-written assembly": The above looks very much like it
> was compiler output (earlier tests did, too, but it's perhaps more
> prominent here). That's not necessarily what a human might write, and
> hence I wonder about the overall coverage that can be gained that way.
> 

Yes, its inspired by compiler generated output. I ran into this when 
running some tests. Its still a good basic cfg test for SCFI - a 
function with two return paths.

>> --- /dev/null
>> +++ b/gas/testsuite/gas/scfi/x86_64/scfi-cofi-1.d
>> @@ -0,0 +1,5 @@
>> +#as: --scfi -W
>> +#objdump: -Wf
>> +#name: Synthesize CFI for add insn
>> +
>> +#pass
>> --- /dev/null
>> +++ b/gas/testsuite/gas/scfi/x86_64/scfi-cofi-1.l
>> @@ -0,0 +1,3 @@
>> +.*Assembler messages:
>> +.*12: Warning: --scfi=all ignores some user-specified CFI directives
>> +.*22: Warning: Untraceable control flow for func 'foo'; Skipping SCFI
>> --- /dev/null
>> +++ b/gas/testsuite/gas/scfi/x86_64/scfi-cofi-1.s
>> @@ -0,0 +1,23 @@
>> +# Testcase with a variety of "change of flow instructions"
>> +#
>> +# Must be run with -W so it remains warning free.
>> +#
>> +# This test does not have much going on wrt synthesis of CFI;
>> +# it just aims to ensure x8_64 -> ginsn decoding must behave
>> +# gracefully for these "change of flow instructions"
>> +	.text
>> +	.globl	foo
>> +	.type	foo, @function
>> +foo:
>> +	.cfi_startproc
>> +	addq    %rdx, %rax
>> +	notrack jmp     *%rax
>> +	call   *%r8
>> +	jmp     *48(%rdi)
>> +	jo      .L179
>> +.L179:
>> +	ret
>> +	.cfi_endproc
>> +.LFE0:
>> +	.size	foo, .-foo
> 
> What exactly is being tested here? The .d file is effectively empty,
> and the .l file expects a warning on the .size directive (which tells
> about nothing regarding the reason for the failure to produce SCFI).
> 

Only that the x86 -> ginsn does not choke on these instructions.  You 
are right that it doesnt test much for SCFI per se.

>> --- /dev/null
>> +++ b/gas/testsuite/gas/scfi/x86_64/scfi-diag-1.s
>> @@ -0,0 +1,23 @@
>> +# Testcase for REG_FP based CFA
>> +# and using REG_FP as scratch.
>> +	.text
>> +	.globl	foo
>> +	.type	foo, @function
>> +foo:
>> +	.cfi_startproc
>> +	pushq	%rbp
>> +	.cfi_def_cfa_offset 16
>> +	.cfi_offset 6, -16
>> +	movq    %rsp, %rbp
>> +	.cfi_def_cfa_register 6
>> +# The following add causes REG_FP to become untraceable
>> +	addq	%rax, %rbp
> 
> But this isn't a problem as long as FP isn't further used. Indeed ...
> 
>> +	.cfi_def_cfa_register 7
>> +	pop	%rbp
> 
> ... its original value is restored right afterwards. Yet another constraint?
> 

Hmm. I need some clarification on the statement "Yet another constraint".

>> --- /dev/null
>> +++ b/gas/testsuite/gas/scfi/x86_64/scfi-fp-diag-2.s
>> @@ -0,0 +1,55 @@
>> +# Testcase for a diagnostic around assymetrical restore
>> +# Testcase inspired by byte_insert_op1 in libiberty
>> +# False positive for the diagnostic
>> +.type	foo, @function
>> +foo:
>> +.LFB10:
>> +	.cfi_startproc
>> +	endbr64
>> +	pushq	%rbp
>> +	.cfi_def_cfa_offset 16
>> +	.cfi_offset 6, -16
>> +	movq	%rsp, %rbp
>> +	.cfi_def_cfa_register 6
>> +	pushq	%r12
>> +	pushq	%rbx
>> +	subq	$24, %rsp
>> +	.cfi_offset 12, -24
>> +	.cfi_offset 3, -32
>> +	movl	%edi, -20(%rbp)
>> +	movq	%rsi, -32(%rbp)
>> +	movl	%edx, -24(%rbp)
>> +	movq	%rcx, -40(%rbp)
>> +# The assembler cannot differentiate that the following
>> +# mov to %rbx is not a true restore operation, but simply
>> +# %rbx register usage as a scratch reg of some sort.
>> +# The assembler merely warns of a possible assymetric restore operation
>> +# In this case, its noise for the user unfortunately.
>> +	movq	-40(%rbp), %rbx
>> +	movq	-40(%rbp), %rax
>> +	leaq	3(%rax), %r12
>> +	jmp	.L563
>> +.L564:
>> +	subq	$1, %rbx
>> +	subq	$1, %r12
>> +	movzbl	(%rbx), %eax
>> +	movb	%al, (%r12)
>> +.L563:
>> +	cmpq	-32(%rbp), %rbx
>> +	jne	.L564
> 
> But this is pretty common usage. Imo this (the false positive warning)
> cannot remain like this.
> 

The warning of "Warning: SCFI: asymetrical register restore" was added 
to alert user if they do something like
     pushq %rbx
     pushq %r12
     ...
     popq  %rbx
     popq  %r12
i.e., asymmetric save and restore.  Now the user may do a restore to any 
register and use what was saved on stack as scratch regiser; the only 
way to differentiate between a "true reg restore in epilogue" vs "reg 
restored for scratch purposes" is to know whether its the epilogue.  GAS 
will not be able to determine that easily.

We could remove the warning altogether.  I just thought it provides 
users with some protection / validation of hand-written asm.


>> --- /dev/null
>> +++ b/gas/testsuite/gas/scfi/x86_64/scfi-ignore-1.s
>> @@ -0,0 +1,13 @@
>> +	.text
>> +	.globl	foo
>> +	.type	foo, @function
>> +foo:
>> +	.cfi_startproc
>> +	pushq	%rbp
>> +        .cfi_def_cfa_offset 16
>> +        .cfi_offset 6, -16
>> +	ret
>> +	.cfi_endproc
>> +.LFE0:
>> +	.size	foo, .-foo
> 
> This, otoh, imo wants diagnosing. The framework ought to recognize that
> the RET doesn't use the correct stack slot.
> 

Yes, its on my TODO list. I plan to add this: if the stack is not 
balanced at the return from function, gas can warn.

> Additionally, isn't scfi-simple-1.s effectively testing the same? The
> code at least looks extremely similar.
> 

Yes, one can removed. The two tests achieve the same end result.

>> --- /dev/null
>> +++ b/gas/testsuite/gas/scfi/x86_64/scfi-unsupported-1.l
>> @@ -0,0 +1,2 @@
>> +Assembler messages:
>> +Fatal error: Synthesizing CFI is not supported for this ABI
>> diff --git a/gas/testsuite/gas/scfi/x86_64/scfi-unsupported-1.s b/gas/testsuite/gas/scfi/x86_64/scfi-unsupported-1.s
>> new file mode 100644
>> index 00000000000..87d2a4971a1
>> --- /dev/null
>> +++ b/gas/testsuite/gas/scfi/x86_64/scfi-unsupported-1.s
>> @@ -0,0 +1,10 @@
>> +# Testcase run with --m32 (Not supported).
>> +	.text
>> +	.globl	foo
>> +	.type	foo, @function
>> +foo:
>> +	pushq	%rbp
> 
> This code, being built with --32, is bogus anyway. I wonder why this file
> has any insns in the first place.
> 

I will update this.

>> --- /dev/null
>> +++ b/gas/testsuite/gas/scfi/x86_64/scfi-x86-64.exp
>> @@ -0,0 +1,103 @@
>> +# Copyright (C) 2022-2023 Free Software Foundation, Inc.
>> +
>> +# This program is free software; you can redistribute it and/or modify
>> +# it under the terms of the GNU General Public License as published by
>> +# the Free Software Foundation; either version 3 of the License, or
>> +# (at your option) any later version.
>> +#
>> +# This program is distributed in the hope that it will be useful,
>> +# but WITHOUT ANY WARRANTY; without even the implied warranty of
>> +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
>> +# GNU General Public License for more details.
>> +#
>> +# You should have received a copy of the GNU General Public License
>> +# along with this program; if not, write to the Free Software
>> +# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
>> +
>> +if { ![is_elf_format] } then {
>> +    return
>> +}
>> +
>> +# common tests
>> +if  { ([istarget "x86_64-*-*"]) } then {
>> +
>> +    global ASFLAGS
>> +    set old_ASFLAGS "$ASFLAGS"
>> +
>> +    run_dump_test "scfi-cfi-label-1"
>> +    run_list_test "scfi-cfi-label-1" "--scfi --warn"
>> +
>> +    run_list_test "scfi-diag-1" "--scfi"
>> +    run_list_test "scfi-fp-diag-2" "--scfi"
>> +    run_list_test "scfi-diag-2" "--scfi"
>> +
>> +    run_list_test "scfi-unsupported-1" "--32 --scfi"
> 
> Perhaps a 2nd run with --x32, unless (see above) you choose to support
> that ABI as well?
> 

At the moment, the plan was to next work on --scfi=inline and add 
support for aarch64/aapcs64 ABIs.  No plans to add support for x32 
unless a need arises.

Thanks
Indu
  
Jan Beulich Nov. 2, 2023, 12:28 p.m. UTC | #3
On 01.11.2023 07:24, Indu Bhagat wrote:
> On 10/31/23 09:13, Jan Beulich wrote:
>> On 30.10.2023 17:51, Indu Bhagat wrote:
>>> --- /dev/null
>>> +++ b/gas/testsuite/gas/scfi/x86_64/scfi-add-2.s
>>> @@ -0,0 +1,48 @@
>>> +        .section        .rodata
>>> +	.type	simd_cmp_op, @object
>>> +	.size	simd_cmp_op, 8
>>> +simd_cmp_op:
>>> +	.long	2
>>> +	.zero	4
>>> +
>>> +# Testcase for add instruction.
>>> +# add reg, reg instruction
>>> +	.text
>>> +	.globl	foo
>>> +	.type	foo, @function
>>> +foo:
>>> +	.cfi_startproc
>>> +	pushq	%rbp
>>> +	.cfi_def_cfa_offset 16
>>> +	.cfi_offset 6, -16
>>> +	movq    %rsp, %rbp
>>> +	.cfi_def_cfa_register 6
>>> +	pushq	%r12
>>> +	.cfi_offset 12, -24
>>> +	mov	%rsp, %r12
>>
>> You copy %rsp to %r12 here, and ...
>>
>>> +# Stack manipulation is permitted if the base register for
>>> +# tracking CFA has been changed to FP.
>>> +	addq    %rdx, %rsp
>>> +	addq	%rsp, %rax
>>> +# Some add instructions may access the stack indirectly.  Such
>>> +# accesses do not make REG_FP untraceable.
>>> +	addl    %eax, -84(%rbp)
>>> +# Other kind of add instructions should not error out in the
>>> +# x86_64 -> ginsn translator
>>> +	addq    $simd_cmp_op+8, %rdx
>>> +	addl    %edx, -32(%rsp)
>>> +	addl    $1, fb_low_counter(,%rbx,4)
>>> +	mov	%r12, %rsp
>>
>> ... you restore it here, but both without any .cfi_* annotation.
>> It is therefore unclear whether this is in any way related to ...
>>
> 
> There are no .cfi_* annotations for the %rsp updates here because the 
> CFA tracking has already been switched to REG_FP based tracking.  From 
> the perspective of DWARF CFI, this usages of the stack do not need to 
> tracked.  If unwinding happens from any instruction in the above 
> sequence, we already have the correct and complete unwind information.
> 
>>> +# Popping a callee-saved register.
>>> +# RSP must be traceable.
>>> +	pop     %r12
>>> +	.cfi_restore 12
>>
>> ... what the comment says about these.
>>
> 
> The comment here means that hand-written programs may use stack for 
> their local usage etc. but must ensure that before or in the epilogue, 
> rsp is restored to the desired value (before register restores via pop 
> instructions).

And how exactly do you tell that the "mov %r12, %rsp" is a restore, not
the setting of an arbitrary new %rsp value?

> This is not a special handling in the SCFI machinery but it is what is 
> needed to ensure correctness of the function.  For asm not adhering to 
> the ABI/calling conventions, SCFI cannot be used.

But the calling convention doesn't go as far as dictating local frame
layout in a function, I don't think?

>>> +	leave
>>> +	.cfi_def_cfa_register 7
>>> +	.cfi_restore 6
>>
>> Using numbers here isn't very helpful, I'm afraid.
>>
> 
> I am not sure I understand.  The DWARF register numbers and the offset 
> values are required by the semantics of those CFI directives.

Offsets are (largely) unavoidable to be numerics, yes. But .cfi_*
directives support register names, and using them is (imo) far better
than Dwarf register numbers - you may have memorized them by now, but
others likely won't.

>>> --- /dev/null
>>> +++ b/gas/testsuite/gas/scfi/x86_64/scfi-asm-marker-3.l
>>> @@ -0,0 +1,2 @@
>>> +.*Assembler messages:
>>> +.*9: Warning: --scfi=all ignores some user-specified CFI directives
>>
>> Is repeating this for (about?) every test really necessary / useful?
>> If multiple passes for every test were to make sense to me, I'd expect
>> one pass with SCFI and one pass without, where the directives then
>> take effect. And then the same set of expectations should match.
>>
> 
> re: is repeating this useful? Strictly speaking no. _But_, I think as 
> the code evolves, we may add more diagnostics to the SCFI machinery. 
> Explicitly checking for the set of warnings helps us ensure no new 
> warnings show up where they are not expected. In a way, it is a stricter 
> check and ensures no unintented slippage.

Well, okay, that's fair. You didn't respond to the other part of my
comment, though.

>>> --- /dev/null
>>> +++ b/gas/testsuite/gas/scfi/x86_64/scfi-bp-sp-2.s
>>> @@ -0,0 +1,49 @@
>>> +# Testcase for switching between sp/fp based CFA.
>>> +	.text
>>> +	.globl	foo
>>> +	.type	foo, @function
>>> +foo:
>>> +        .cfi_startproc
>>> +        pushq   %r14
>>> +        .cfi_def_cfa_offset 16
>>> +        .cfi_offset 14, -16
>>> +        pushq   %r13
>>> +        .cfi_def_cfa_offset 24
>>> +        .cfi_offset 13, -24
>>> +        pushq   %r12
>>> +        .cfi_def_cfa_offset 32
>>> +        .cfi_offset 12, -32
>>> +        pushq   %rbp
>>> +        .cfi_def_cfa_offset 40
>>> +        .cfi_offset 6, -40
>>> +        pushq   %rbx
>>> +        .cfi_def_cfa_offset 48
>>> +        .cfi_offset 3, -48
>>> +        movq    %rdi, %rbx
>>> +        subq    $32, %rsp
>>> +        .cfi_def_cfa_offset 80
>>> +# This mov does not switch CFA tracking to REG_FP, because there has already
>>> +# been stack usage between here and the push %rbp
>>> +        movq    %rsp, %rbp
>>
>> Yet another constraint?
>>
> 
> Not sure I understand. This is not a constraint for SCFI.  A pattern 
> where the user does:
>      push %rbp
>      .. more stack usage..
>      movq %rsp, %rbp
> is not using frame pointer for stack tracing, but simply as a scratch 
> register.

Why might it not be? We're talking about hand-written assembly, and
assembly writers are free to e.g. first push all (necessary) callee-
saved register and then copy %rsp into %rbp. For a function with many
stack locals this has the benefit of allowing more of them to be
accessed via <disp8>(%rbp).

>>> --- /dev/null
>>> +++ b/gas/testsuite/gas/scfi/x86_64/scfi-cfg-1.d
>>> @@ -0,0 +1,36 @@
>>> +#as: --scfi -W
>>> +#objdump: -Wf
>>> +#name: Synthesize CFI in presence of control flow 1
>>> +#...
>>> +Contents of the .eh_frame section:
>>> +
>>> +00000000 0+0014 0+0000 CIE
>>> +  Version:               1
>>> +  Augmentation:          "zR"
>>> +  Code alignment factor: 1
>>> +  Data alignment factor: -8
>>> +  Return address column: 16
>>> +  Augmentation data:     [01][abc]
>>> +  DW_CFA_def_cfa: r7 \(rsp\) ofs 8
>>> +  DW_CFA_offset: r16 \(rip\) at cfa-8
>>> +  DW_CFA_nop
>>> +  DW_CFA_nop
>>> +
>>> +0+0018 0+0024 0000001c FDE cie=00000000 pc=0+0000..0+003a
>>> +  DW_CFA_advance_loc: 1 to 0+0001
>>> +  DW_CFA_def_cfa_offset: 16
>>> +  DW_CFA_offset: r3 \(rbx\) at cfa-16
>>> +  DW_CFA_advance_loc: 37 to 0+0026
>>> +  DW_CFA_remember_state
>>> +  DW_CFA_advance_loc: 1 to 0+0027
>>> +  DW_CFA_restore: r3 \(rbx\)
>>> +  DW_CFA_def_cfa_offset: 8
>>> +  DW_CFA_advance_loc: 1 to 0+0028
>>> +  DW_CFA_restore_state
>>> +  DW_CFA_advance_loc: 9 to 0+0031
>>> +  DW_CFA_restore: r3 \(rbx\)
>>> +  DW_CFA_def_cfa_offset: 8
>>> +  DW_CFA_nop
>>> +#...
>>> +
>>> +#pass
>>
>> Seeing this recurring pattern (the last three lines): Why not just #pass?
>>
> 
> I thought adding #... is clearer as it indicates that the test knowingly 
> skips lines thereafter.

Well, #pass alone already says exactly this. If you didn't expect further
output lines, you'd _omit_ #pass.

>>> --- /dev/null
>>> +++ b/gas/testsuite/gas/scfi/x86_64/scfi-cfg-1.s
>>> @@ -0,0 +1,47 @@
>>> +# Testcase with one dominator bb and two exit bbs
>>> +# Something like for: return ferror (f) || fclose (f) != 0;
>>> +	.text
>>> +	.section	.rodata.str1.1,"aMS",@progbits,1
>>> +.LC0:
>>> +	.string	"w"
>>> +.LC1:
>>> +	.string	"conftest.out"
>>> +	.section	.text.startup,"ax",@progbits
>>> +	.p2align 4
>>> +	.globl	main
>>> +	.type	main, @function
>>> +main:
>>> +.LFB11:
>>
>> Coming back to "hand-written assembly": The above looks very much like it
>> was compiler output (earlier tests did, too, but it's perhaps more
>> prominent here). That's not necessarily what a human might write, and
>> hence I wonder about the overall coverage that can be gained that way.
>>
> 
> Yes, its inspired by compiler generated output. I ran into this when 
> running some tests. Its still a good basic cfg test for SCFI - a 
> function with two return paths.

You understand though that I used this only as (sutiable) example. My point
being that hand-written assembly frequently doesn't resemble compiler-
genertaed code. Otherwise, i.e. if the resulting code wasn't to be different,
why would one write assembly code in nthe first place?

>>> --- /dev/null
>>> +++ b/gas/testsuite/gas/scfi/x86_64/scfi-diag-1.s
>>> @@ -0,0 +1,23 @@
>>> +# Testcase for REG_FP based CFA
>>> +# and using REG_FP as scratch.
>>> +	.text
>>> +	.globl	foo
>>> +	.type	foo, @function
>>> +foo:
>>> +	.cfi_startproc
>>> +	pushq	%rbp
>>> +	.cfi_def_cfa_offset 16
>>> +	.cfi_offset 6, -16
>>> +	movq    %rsp, %rbp
>>> +	.cfi_def_cfa_register 6
>>> +# The following add causes REG_FP to become untraceable
>>> +	addq	%rax, %rbp
>>
>> But this isn't a problem as long as FP isn't further used. Indeed ...
>>
>>> +	.cfi_def_cfa_register 7
>>> +	pop	%rbp
>>
>> ... its original value is restored right afterwards. Yet another constraint?
>>
> 
> Hmm. I need some clarification on the statement "Yet another constraint".

By "constraint" I mean assumptions you make on the way assembly code is
written, for your machinery to be usable. The more such assumptions, the
smaller the set of code "eligible" to (future) use of your work. Hence
also why I think all such "constraints" need to be spelled out in a
single place, such that one can
- verify that everything meeting these constraints actually also works,
- check up front whether one's assembly code is actually suitable for
  enabling --scfi.

>>> --- /dev/null
>>> +++ b/gas/testsuite/gas/scfi/x86_64/scfi-fp-diag-2.s
>>> @@ -0,0 +1,55 @@
>>> +# Testcase for a diagnostic around assymetrical restore
>>> +# Testcase inspired by byte_insert_op1 in libiberty
>>> +# False positive for the diagnostic
>>> +.type	foo, @function
>>> +foo:
>>> +.LFB10:
>>> +	.cfi_startproc
>>> +	endbr64
>>> +	pushq	%rbp
>>> +	.cfi_def_cfa_offset 16
>>> +	.cfi_offset 6, -16
>>> +	movq	%rsp, %rbp
>>> +	.cfi_def_cfa_register 6
>>> +	pushq	%r12
>>> +	pushq	%rbx
>>> +	subq	$24, %rsp
>>> +	.cfi_offset 12, -24
>>> +	.cfi_offset 3, -32
>>> +	movl	%edi, -20(%rbp)
>>> +	movq	%rsi, -32(%rbp)
>>> +	movl	%edx, -24(%rbp)
>>> +	movq	%rcx, -40(%rbp)
>>> +# The assembler cannot differentiate that the following
>>> +# mov to %rbx is not a true restore operation, but simply
>>> +# %rbx register usage as a scratch reg of some sort.
>>> +# The assembler merely warns of a possible assymetric restore operation
>>> +# In this case, its noise for the user unfortunately.
>>> +	movq	-40(%rbp), %rbx
>>> +	movq	-40(%rbp), %rax
>>> +	leaq	3(%rax), %r12
>>> +	jmp	.L563
>>> +.L564:
>>> +	subq	$1, %rbx
>>> +	subq	$1, %r12
>>> +	movzbl	(%rbx), %eax
>>> +	movb	%al, (%r12)
>>> +.L563:
>>> +	cmpq	-32(%rbp), %rbx
>>> +	jne	.L564
>>
>> But this is pretty common usage. Imo this (the false positive warning)
>> cannot remain like this.
>>
> 
> The warning of "Warning: SCFI: asymetrical register restore" was added 
> to alert user if they do something like
>      pushq %rbx
>      pushq %r12
>      ...
>      popq  %rbx
>      popq  %r12
> i.e., asymmetric save and restore.  Now the user may do a restore to any 
> register and use what was saved on stack as scratch regiser; the only 
> way to differentiate between a "true reg restore in epilogue" vs "reg 
> restored for scratch purposes" is to know whether its the epilogue.  GAS 
> will not be able to determine that easily.
> 
> We could remove the warning altogether.  I just thought it provides 
> users with some protection / validation of hand-written asm.

I'm in favor of such assisting warnings, but they're useful only if there
are few false positives and few false negatives. Too many warnings makes
people ignore them all (or shut them off), while too few makes people
mistrust them being helpful.

>>> --- /dev/null
>>> +++ b/gas/testsuite/gas/scfi/x86_64/scfi-x86-64.exp
>>> @@ -0,0 +1,103 @@
>>> +# Copyright (C) 2022-2023 Free Software Foundation, Inc.
>>> +
>>> +# This program is free software; you can redistribute it and/or modify
>>> +# it under the terms of the GNU General Public License as published by
>>> +# the Free Software Foundation; either version 3 of the License, or
>>> +# (at your option) any later version.
>>> +#
>>> +# This program is distributed in the hope that it will be useful,
>>> +# but WITHOUT ANY WARRANTY; without even the implied warranty of
>>> +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
>>> +# GNU General Public License for more details.
>>> +#
>>> +# You should have received a copy of the GNU General Public License
>>> +# along with this program; if not, write to the Free Software
>>> +# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
>>> +
>>> +if { ![is_elf_format] } then {
>>> +    return
>>> +}
>>> +
>>> +# common tests
>>> +if  { ([istarget "x86_64-*-*"]) } then {
>>> +
>>> +    global ASFLAGS
>>> +    set old_ASFLAGS "$ASFLAGS"
>>> +
>>> +    run_dump_test "scfi-cfi-label-1"
>>> +    run_list_test "scfi-cfi-label-1" "--scfi --warn"
>>> +
>>> +    run_list_test "scfi-diag-1" "--scfi"
>>> +    run_list_test "scfi-fp-diag-2" "--scfi"
>>> +    run_list_test "scfi-diag-2" "--scfi"
>>> +
>>> +    run_list_test "scfi-unsupported-1" "--32 --scfi"
>>
>> Perhaps a 2nd run with --x32, unless (see above) you choose to support
>> that ABI as well?
>>
> 
> At the moment, the plan was to next work on --scfi=inline and add 
> support for aarch64/aapcs64 ABIs.  No plans to add support for x32 
> unless a need arises.

But that's precisely my point: As long as you don't support --x32, you
want to check that its use is properly diagnosed (just like use of
--32 is).

Jan
  
Indu Bhagat Nov. 3, 2023, 5:45 a.m. UTC | #4
On 11/2/23 05:28, Jan Beulich wrote:
> On 01.11.2023 07:24, Indu Bhagat wrote:
>> On 10/31/23 09:13, Jan Beulich wrote:
>>> On 30.10.2023 17:51, Indu Bhagat wrote:
>>>> --- /dev/null
>>>> +++ b/gas/testsuite/gas/scfi/x86_64/scfi-add-2.s
>>>> @@ -0,0 +1,48 @@
>>>> +        .section        .rodata
>>>> +	.type	simd_cmp_op, @object
>>>> +	.size	simd_cmp_op, 8
>>>> +simd_cmp_op:
>>>> +	.long	2
>>>> +	.zero	4
>>>> +
>>>> +# Testcase for add instruction.
>>>> +# add reg, reg instruction
>>>> +	.text
>>>> +	.globl	foo
>>>> +	.type	foo, @function
>>>> +foo:
>>>> +	.cfi_startproc
>>>> +	pushq	%rbp
>>>> +	.cfi_def_cfa_offset 16
>>>> +	.cfi_offset 6, -16
>>>> +	movq    %rsp, %rbp
>>>> +	.cfi_def_cfa_register 6
>>>> +	pushq	%r12
>>>> +	.cfi_offset 12, -24
>>>> +	mov	%rsp, %r12
>>>
>>> You copy %rsp to %r12 here, and ...
>>>
>>>> +# Stack manipulation is permitted if the base register for
>>>> +# tracking CFA has been changed to FP.
>>>> +	addq    %rdx, %rsp
>>>> +	addq	%rsp, %rax
>>>> +# Some add instructions may access the stack indirectly.  Such
>>>> +# accesses do not make REG_FP untraceable.
>>>> +	addl    %eax, -84(%rbp)
>>>> +# Other kind of add instructions should not error out in the
>>>> +# x86_64 -> ginsn translator
>>>> +	addq    $simd_cmp_op+8, %rdx
>>>> +	addl    %edx, -32(%rsp)
>>>> +	addl    $1, fb_low_counter(,%rbx,4)
>>>> +	mov	%r12, %rsp
>>>
>>> ... you restore it here, but both without any .cfi_* annotation.
>>> It is therefore unclear whether this is in any way related to ...
>>>
>>
>> There are no .cfi_* annotations for the %rsp updates here because the
>> CFA tracking has already been switched to REG_FP based tracking.  From
>> the perspective of DWARF CFI, this usages of the stack do not need to
>> tracked.  If unwinding happens from any instruction in the above
>> sequence, we already have the correct and complete unwind information.
>>
>>>> +# Popping a callee-saved register.
>>>> +# RSP must be traceable.
>>>> +	pop     %r12
>>>> +	.cfi_restore 12
>>>
>>> ... what the comment says about these.
>>>
>>
>> The comment here means that hand-written programs may use stack for
>> their local usage etc. but must ensure that before or in the epilogue,
>> rsp is restored to the desired value (before register restores via pop
>> instructions).
> 
> And how exactly do you tell that the "mov %r12, %rsp" is a restore, not
> the setting of an arbitrary new %rsp value?
> 

It checks that there must have been a "mov %rsp, %r12" seen earlier. 
The SCFI machinery caches such a save of stack pointer state.

>> This is not a special handling in the SCFI machinery but it is what is
>> needed to ensure correctness of the function.  For asm not adhering to
>> the ABI/calling conventions, SCFI cannot be used.
> 
> But the calling convention doesn't go as far as dictating local frame
> layout in a function, I don't think?
> 

No you are right on that one.

In this example, we only concern ourselves only with the callee-saved 
registers and their save/restores; the components that affect the CFI 
annotations.  The local stack usage is not of interest per se; the 
program is allowed to allocate and use as it pleases.

>>>> +	leave
>>>> +	.cfi_def_cfa_register 7
>>>> +	.cfi_restore 6
>>>
>>> Using numbers here isn't very helpful, I'm afraid.
>>>
>>
>> I am not sure I understand.  The DWARF register numbers and the offset
>> values are required by the semantics of those CFI directives.
> 
> Offsets are (largely) unavoidable to be numerics, yes. But .cfi_*
> directives support register names, and using them is (imo) far better
> than Dwarf register numbers - you may have memorized them by now, but
> others likely won't.
> 

Ah ok. Yeah I can use register numbers.

>>>> --- /dev/null
>>>> +++ b/gas/testsuite/gas/scfi/x86_64/scfi-asm-marker-3.l
>>>> @@ -0,0 +1,2 @@
>>>> +.*Assembler messages:
>>>> +.*9: Warning: --scfi=all ignores some user-specified CFI directives
>>>
>>> Is repeating this for (about?) every test really necessary / useful?
>>> If multiple passes for every test were to make sense to me, I'd expect
>>> one pass with SCFI and one pass without, where the directives then
>>> take effect. And then the same set of expectations should match.
>>>
>>
>> re: is repeating this useful? Strictly speaking no. _But_, I think as
>> the code evolves, we may add more diagnostics to the SCFI machinery.
>> Explicitly checking for the set of warnings helps us ensure no new
>> warnings show up where they are not expected. In a way, it is a stricter
>> check and ensures no unintented slippage.
> 
> Well, okay, that's fair. You didn't respond to the other part of my
> comment, though.
> 

Sorry I missed that.  Yes, we could do two runs for the meaningful 
tests, one with --scfi and another without. That should be useful.  I 
recall there was only one case (dont recollect which one) where the 
generated FDEs were reversed in order with --scfi, but it was not a 
functional difference.  Other than that test, rest all should match.

>>>> --- /dev/null
>>>> +++ b/gas/testsuite/gas/scfi/x86_64/scfi-bp-sp-2.s
>>>> @@ -0,0 +1,49 @@
>>>> +# Testcase for switching between sp/fp based CFA.
>>>> +	.text
>>>> +	.globl	foo
>>>> +	.type	foo, @function
>>>> +foo:
>>>> +        .cfi_startproc
>>>> +        pushq   %r14
>>>> +        .cfi_def_cfa_offset 16
>>>> +        .cfi_offset 14, -16
>>>> +        pushq   %r13
>>>> +        .cfi_def_cfa_offset 24
>>>> +        .cfi_offset 13, -24
>>>> +        pushq   %r12
>>>> +        .cfi_def_cfa_offset 32
>>>> +        .cfi_offset 12, -32
>>>> +        pushq   %rbp
>>>> +        .cfi_def_cfa_offset 40
>>>> +        .cfi_offset 6, -40
>>>> +        pushq   %rbx
>>>> +        .cfi_def_cfa_offset 48
>>>> +        .cfi_offset 3, -48
>>>> +        movq    %rdi, %rbx
>>>> +        subq    $32, %rsp
>>>> +        .cfi_def_cfa_offset 80
>>>> +# This mov does not switch CFA tracking to REG_FP, because there has already
>>>> +# been stack usage between here and the push %rbp
>>>> +        movq    %rsp, %rbp
>>>
>>> Yet another constraint?
>>>
>>
>> Not sure I understand. This is not a constraint for SCFI.  A pattern
>> where the user does:
>>       push %rbp
>>       .. more stack usage..
>>       movq %rsp, %rbp
>> is not using frame pointer for stack tracing, but simply as a scratch
>> register.
> 
> Why might it not be? We're talking about hand-written assembly, and
> assembly writers are free to e.g. first push all (necessary) callee-
> saved register and then copy %rsp into %rbp. For a function with many
> stack locals this has the benefit of allowing more of them to be
> accessed via <disp8>(%rbp).
> 

You are right on this one. It should be allowed. The mov %rsp, %rbp 
should switch to REG_FP based CFA in this example. I will fix it.

>>>> --- /dev/null
>>>> +++ b/gas/testsuite/gas/scfi/x86_64/scfi-cfg-1.d
>>>> @@ -0,0 +1,36 @@
>>>> +#as: --scfi -W
>>>> +#objdump: -Wf
>>>> +#name: Synthesize CFI in presence of control flow 1
>>>> +#...
>>>> +Contents of the .eh_frame section:
>>>> +
>>>> +00000000 0+0014 0+0000 CIE
>>>> +  Version:               1
>>>> +  Augmentation:          "zR"
>>>> +  Code alignment factor: 1
>>>> +  Data alignment factor: -8
>>>> +  Return address column: 16
>>>> +  Augmentation data:     [01][abc]
>>>> +  DW_CFA_def_cfa: r7 \(rsp\) ofs 8
>>>> +  DW_CFA_offset: r16 \(rip\) at cfa-8
>>>> +  DW_CFA_nop
>>>> +  DW_CFA_nop
>>>> +
>>>> +0+0018 0+0024 0000001c FDE cie=00000000 pc=0+0000..0+003a
>>>> +  DW_CFA_advance_loc: 1 to 0+0001
>>>> +  DW_CFA_def_cfa_offset: 16
>>>> +  DW_CFA_offset: r3 \(rbx\) at cfa-16
>>>> +  DW_CFA_advance_loc: 37 to 0+0026
>>>> +  DW_CFA_remember_state
>>>> +  DW_CFA_advance_loc: 1 to 0+0027
>>>> +  DW_CFA_restore: r3 \(rbx\)
>>>> +  DW_CFA_def_cfa_offset: 8
>>>> +  DW_CFA_advance_loc: 1 to 0+0028
>>>> +  DW_CFA_restore_state
>>>> +  DW_CFA_advance_loc: 9 to 0+0031
>>>> +  DW_CFA_restore: r3 \(rbx\)
>>>> +  DW_CFA_def_cfa_offset: 8
>>>> +  DW_CFA_nop
>>>> +#...
>>>> +
>>>> +#pass
>>>
>>> Seeing this recurring pattern (the last three lines): Why not just #pass?
>>>
>>
>> I thought adding #... is clearer as it indicates that the test knowingly
>> skips lines thereafter.
> 
> Well, #pass alone already says exactly this. If you didn't expect further
> output lines, you'd _omit_ #pass.
> 

OK.

>>>> --- /dev/null
>>>> +++ b/gas/testsuite/gas/scfi/x86_64/scfi-cfg-1.s
>>>> @@ -0,0 +1,47 @@
>>>> +# Testcase with one dominator bb and two exit bbs
>>>> +# Something like for: return ferror (f) || fclose (f) != 0;
>>>> +	.text
>>>> +	.section	.rodata.str1.1,"aMS",@progbits,1
>>>> +.LC0:
>>>> +	.string	"w"
>>>> +.LC1:
>>>> +	.string	"conftest.out"
>>>> +	.section	.text.startup,"ax",@progbits
>>>> +	.p2align 4
>>>> +	.globl	main
>>>> +	.type	main, @function
>>>> +main:
>>>> +.LFB11:
>>>
>>> Coming back to "hand-written assembly": The above looks very much like it
>>> was compiler output (earlier tests did, too, but it's perhaps more
>>> prominent here). That's not necessarily what a human might write, and
>>> hence I wonder about the overall coverage that can be gained that way.
>>>
>>
>> Yes, its inspired by compiler generated output. I ran into this when
>> running some tests. Its still a good basic cfg test for SCFI - a
>> function with two return paths.
> 
> You understand though that I used this only as (sutiable) example. My point
> being that hand-written assembly frequently doesn't resemble compiler-
> genertaed code. Otherwise, i.e. if the resulting code wasn't to be different,
> why would one write assembly code in nthe first place?
> 

True.
Open to suggestions on improving the testsuite.

>>>> --- /dev/null
>>>> +++ b/gas/testsuite/gas/scfi/x86_64/scfi-diag-1.s
>>>> @@ -0,0 +1,23 @@
>>>> +# Testcase for REG_FP based CFA
>>>> +# and using REG_FP as scratch.
>>>> +	.text
>>>> +	.globl	foo
>>>> +	.type	foo, @function
>>>> +foo:
>>>> +	.cfi_startproc
>>>> +	pushq	%rbp
>>>> +	.cfi_def_cfa_offset 16
>>>> +	.cfi_offset 6, -16
>>>> +	movq    %rsp, %rbp
>>>> +	.cfi_def_cfa_register 6
>>>> +# The following add causes REG_FP to become untraceable
>>>> +	addq	%rax, %rbp
>>>
>>> But this isn't a problem as long as FP isn't further used. Indeed ...
>>>
>>>> +	.cfi_def_cfa_register 7
>>>> +	pop	%rbp
>>>
>>> ... its original value is restored right afterwards. Yet another constraint?
>>>
>>
>> Hmm. I need some clarification on the statement "Yet another constraint".
> 
> By "constraint" I mean assumptions you make on the way assembly code is
> written, for your machinery to be usable. The more such assumptions, the
> smaller the set of code "eligible" to (future) use of your work. Hence
> also why I think all such "constraints" need to be spelled out in a
> single place, such that one can
> - verify that everything meeting these constraints actually also works,
> - check up front whether one's assembly code is actually suitable for
>    enabling --scfi.
> 

OK, Thanks. We are on the same page wrt "Constraints" then. In the above 
example, though, the "constraint" is due to the desire to be able 
unwind/stack trace asynchronously. Which is why it confused me in the 
first place, I think I wouldn't call this a "constraint" here. But this 
is a subjective line.

In the above example, the 'addq    %rax, %rbp' does cause a problem for 
unwinding because the CFA is REG_FP based. And the SCFI machinery needs 
to be able to tell what offset from REG_FP is the CFA. I think its 
correct for the SCFI machinery to complain with a ".*14: Error: SCFI: 
usage of REG_FP as scratch not supported" right away, because the unwind 
information at the next instruction is already affected.

That said, I do agree that the constraints need to be spelled out in a 
single place. I already have done some of it in scfi.c, but there is 
room for improvement, I see.

>>>> --- /dev/null
>>>> +++ b/gas/testsuite/gas/scfi/x86_64/scfi-fp-diag-2.s
>>>> @@ -0,0 +1,55 @@
>>>> +# Testcase for a diagnostic around assymetrical restore
>>>> +# Testcase inspired by byte_insert_op1 in libiberty
>>>> +# False positive for the diagnostic
>>>> +.type	foo, @function
>>>> +foo:
>>>> +.LFB10:
>>>> +	.cfi_startproc
>>>> +	endbr64
>>>> +	pushq	%rbp
>>>> +	.cfi_def_cfa_offset 16
>>>> +	.cfi_offset 6, -16
>>>> +	movq	%rsp, %rbp
>>>> +	.cfi_def_cfa_register 6
>>>> +	pushq	%r12
>>>> +	pushq	%rbx
>>>> +	subq	$24, %rsp
>>>> +	.cfi_offset 12, -24
>>>> +	.cfi_offset 3, -32
>>>> +	movl	%edi, -20(%rbp)
>>>> +	movq	%rsi, -32(%rbp)
>>>> +	movl	%edx, -24(%rbp)
>>>> +	movq	%rcx, -40(%rbp)
>>>> +# The assembler cannot differentiate that the following
>>>> +# mov to %rbx is not a true restore operation, but simply
>>>> +# %rbx register usage as a scratch reg of some sort.
>>>> +# The assembler merely warns of a possible assymetric restore operation
>>>> +# In this case, its noise for the user unfortunately.
>>>> +	movq	-40(%rbp), %rbx
>>>> +	movq	-40(%rbp), %rax
>>>> +	leaq	3(%rax), %r12
>>>> +	jmp	.L563
>>>> +.L564:
>>>> +	subq	$1, %rbx
>>>> +	subq	$1, %r12
>>>> +	movzbl	(%rbx), %eax
>>>> +	movb	%al, (%r12)
>>>> +.L563:
>>>> +	cmpq	-32(%rbp), %rbx
>>>> +	jne	.L564
>>>
>>> But this is pretty common usage. Imo this (the false positive warning)
>>> cannot remain like this.
>>>
>>
>> The warning of "Warning: SCFI: asymetrical register restore" was added
>> to alert user if they do something like
>>       pushq %rbx
>>       pushq %r12
>>       ...
>>       popq  %rbx
>>       popq  %r12
>> i.e., asymmetric save and restore.  Now the user may do a restore to any
>> register and use what was saved on stack as scratch regiser; the only
>> way to differentiate between a "true reg restore in epilogue" vs "reg
>> restored for scratch purposes" is to know whether its the epilogue.  GAS
>> will not be able to determine that easily.
>>
>> We could remove the warning altogether.  I just thought it provides
>> users with some protection / validation of hand-written asm.
> 
> I'm in favor of such assisting warnings, but they're useful only if there
> are few false positives and few false negatives. Too many warnings makes
> people ignore them all (or shut them off), while too few makes people
> mistrust them being helpful.
> 

Noted. And I do agree. I just so happens that I dont have a solution to 
this problem of false positive warnings yet.

>>>> --- /dev/null
>>>> +++ b/gas/testsuite/gas/scfi/x86_64/scfi-x86-64.exp
>>>> @@ -0,0 +1,103 @@
>>>> +# Copyright (C) 2022-2023 Free Software Foundation, Inc.
>>>> +
>>>> +# This program is free software; you can redistribute it and/or modify
>>>> +# it under the terms of the GNU General Public License as published by
>>>> +# the Free Software Foundation; either version 3 of the License, or
>>>> +# (at your option) any later version.
>>>> +#
>>>> +# This program is distributed in the hope that it will be useful,
>>>> +# but WITHOUT ANY WARRANTY; without even the implied warranty of
>>>> +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
>>>> +# GNU General Public License for more details.
>>>> +#
>>>> +# You should have received a copy of the GNU General Public License
>>>> +# along with this program; if not, write to the Free Software
>>>> +# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
>>>> +
>>>> +if { ![is_elf_format] } then {
>>>> +    return
>>>> +}
>>>> +
>>>> +# common tests
>>>> +if  { ([istarget "x86_64-*-*"]) } then {
>>>> +
>>>> +    global ASFLAGS
>>>> +    set old_ASFLAGS "$ASFLAGS"
>>>> +
>>>> +    run_dump_test "scfi-cfi-label-1"
>>>> +    run_list_test "scfi-cfi-label-1" "--scfi --warn"
>>>> +
>>>> +    run_list_test "scfi-diag-1" "--scfi"
>>>> +    run_list_test "scfi-fp-diag-2" "--scfi"
>>>> +    run_list_test "scfi-diag-2" "--scfi"
>>>> +
>>>> +    run_list_test "scfi-unsupported-1" "--32 --scfi"
>>>
>>> Perhaps a 2nd run with --x32, unless (see above) you choose to support
>>> that ABI as well?
>>>
>>
>> At the moment, the plan was to next work on --scfi=inline and add
>> support for aarch64/aapcs64 ABIs.  No plans to add support for x32
>> unless a need arises.
> 
> But that's precisely my point: As long as you don't support --x32, you
> want to check that its use is properly diagnosed (just like use of
> --32 is).
> 

Ah, apologies I construed this comment differently earlier. Yes, I agree 
we can add another run with --x32.
  

Patch

diff --git a/gas/testsuite/gas/scfi/README b/gas/testsuite/gas/scfi/README
new file mode 100644
index 00000000000..75dcebb602d
--- /dev/null
+++ b/gas/testsuite/gas/scfi/README
@@ -0,0 +1,17 @@ 
+Notes on the SCFI testsuite in GAS:
+
+* At this time, SCFI machinery is only supported for x86_64.
+
+* When adding more tests, please keep CFI annotations updated in the .s files.
+  Recall that user-specified, synthesizable CFI annotations are ignored by the
+  GAS when --scfi (=all) is in effect.  Adding CFI annocations, irrespectively,
+  makes the testcases clearer in terms of understanding the expected unwind
+  data.
+
+* Note that GAS issues a warning:
+    "Warning: --scfi=all ignores some user-specified CFI directive"
+  when it encounters CFI directives in the input assembly and --scfi (=all) is
+  active.  To bypass the noise from this warning, while keeping the testcases
+  useful/understandable, most tests are run twice. E.g.,
+     - run_dump_test "scfi-cfi-add-1" // ignores warnings
+     - run_list_test "scfi-cfi-add-1" "--scfi --warn" // tests warnings
diff --git a/gas/testsuite/gas/scfi/x86_64/scfi-add-1.d b/gas/testsuite/gas/scfi/x86_64/scfi-add-1.d
new file mode 100644
index 00000000000..d224990641a
--- /dev/null
+++ b/gas/testsuite/gas/scfi/x86_64/scfi-add-1.d
@@ -0,0 +1,25 @@ 
+#as: --scfi -W
+#objdump: -Wf
+#name: Synthesize CFI for add insn 1
+#...
+Contents of the .eh_frame section:
+
+00000000 0+0014 0+0000 CIE
+  Version:               1
+  Augmentation:          "zR"
+  Code alignment factor: 1
+  Data alignment factor: -8
+  Return address column: 16
+  Augmentation data:     [01][abc]
+  DW_CFA_def_cfa: r7 \(rsp\) ofs 8
+  DW_CFA_offset: r16 \(rip\) at cfa-8
+  DW_CFA_nop
+  DW_CFA_nop
+
+0+0018 0+0014 0+001c FDE cie=0+0000 pc=0+0000..0+0005
+  DW_CFA_advance_loc: 4 to 0+0004
+  DW_CFA_def_cfa_offset: 0
+  DW_CFA_nop
+#...
+
+#pass
diff --git a/gas/testsuite/gas/scfi/x86_64/scfi-add-1.l b/gas/testsuite/gas/scfi/x86_64/scfi-add-1.l
new file mode 100644
index 00000000000..0e094077edd
--- /dev/null
+++ b/gas/testsuite/gas/scfi/x86_64/scfi-add-1.l
@@ -0,0 +1,2 @@ 
+.*Assembler messages:
+.*6: Warning: --scfi=all ignores some user-specified CFI directives
diff --git a/gas/testsuite/gas/scfi/x86_64/scfi-add-1.s b/gas/testsuite/gas/scfi/x86_64/scfi-add-1.s
new file mode 100644
index 00000000000..99002c5e34e
--- /dev/null
+++ b/gas/testsuite/gas/scfi/x86_64/scfi-add-1.s
@@ -0,0 +1,13 @@ 
+# Testcase for add instruction.
+	.text
+	.globl	foo
+	.type	foo, @function
+foo:
+	.cfi_startproc
+	addq    $8, %rsp
+	.cfi_def_cfa_offset 0
+	ret
+	.cfi_endproc
+.LFE0:
+	.size	foo, .-foo
+
diff --git a/gas/testsuite/gas/scfi/x86_64/scfi-add-2.d b/gas/testsuite/gas/scfi/x86_64/scfi-add-2.d
new file mode 100644
index 00000000000..4b378caa117
--- /dev/null
+++ b/gas/testsuite/gas/scfi/x86_64/scfi-add-2.d
@@ -0,0 +1,36 @@ 
+#as: --scfi -W
+#objdump: -Wf
+#name: Synthesize CFI for add insn 2
+#...
+Contents of the .eh_frame section:
+
+00000000 0+0014 0+0000 CIE
+  Version:               1
+  Augmentation:          "zR"
+  Code alignment factor: 1
+  Data alignment factor: -8
+  Return address column: 16
+  Augmentation data:     [01][abc]
+  DW_CFA_def_cfa: r7 \(rsp\) ofs 8
+  DW_CFA_offset: r16 \(rip\) at cfa-8
+  DW_CFA_nop
+  DW_CFA_nop
+
+0+0018 0+0024 0+001c FDE cie=0+0000 pc=0+0000..0+002c
+  DW_CFA_advance_loc: 1 to 0+0001
+  DW_CFA_def_cfa_offset: 16
+  DW_CFA_offset: r6 \(rbp\) at cfa-16
+  DW_CFA_advance_loc: 3 to 0+0004
+  DW_CFA_def_cfa_register: r6 \(rbp\)
+  DW_CFA_advance_loc: 2 to 0+0006
+  DW_CFA_offset: r12 \(r12\) at cfa-24
+  DW_CFA_advance_loc: 36 to 0+002a
+  DW_CFA_restore: r12 \(r12\)
+  DW_CFA_advance_loc: 1 to 0+002b
+  DW_CFA_def_cfa_register: r7 \(rsp\)
+  DW_CFA_restore: r6 \(rbp\)
+  DW_CFA_def_cfa_offset: 8
+  DW_CFA_nop
+#...
+
+#pass
diff --git a/gas/testsuite/gas/scfi/x86_64/scfi-add-2.l b/gas/testsuite/gas/scfi/x86_64/scfi-add-2.l
new file mode 100644
index 00000000000..147ffcb6bda
--- /dev/null
+++ b/gas/testsuite/gas/scfi/x86_64/scfi-add-2.l
@@ -0,0 +1,2 @@ 
+.*Assembler messages:
+.*14: Warning: --scfi=all ignores some user-specified CFI directives
diff --git a/gas/testsuite/gas/scfi/x86_64/scfi-add-2.s b/gas/testsuite/gas/scfi/x86_64/scfi-add-2.s
new file mode 100644
index 00000000000..6ea0fefc7b5
--- /dev/null
+++ b/gas/testsuite/gas/scfi/x86_64/scfi-add-2.s
@@ -0,0 +1,48 @@ 
+        .section        .rodata
+	.type	simd_cmp_op, @object
+	.size	simd_cmp_op, 8
+simd_cmp_op:
+	.long	2
+	.zero	4
+
+# Testcase for add instruction.
+# add reg, reg instruction
+	.text
+	.globl	foo
+	.type	foo, @function
+foo:
+	.cfi_startproc
+	pushq	%rbp
+	.cfi_def_cfa_offset 16
+	.cfi_offset 6, -16
+	movq    %rsp, %rbp
+	.cfi_def_cfa_register 6
+	pushq	%r12
+	.cfi_offset 12, -24
+	mov	%rsp, %r12
+# Stack manipulation is permitted if the base register for
+# tracking CFA has been changed to FP.
+	addq    %rdx, %rsp
+	addq	%rsp, %rax
+# Some add instructions may access the stack indirectly.  Such
+# accesses do not make REG_FP untraceable.
+	addl    %eax, -84(%rbp)
+# Other kind of add instructions should not error out in the
+# x86_64 -> ginsn translator
+	addq    $simd_cmp_op+8, %rdx
+	addl    %edx, -32(%rsp)
+	addl    $1, fb_low_counter(,%rbx,4)
+	mov	%r12, %rsp
+# Popping a callee-saved register.
+# RSP must be traceable.
+	pop     %r12
+	.cfi_restore 12
+	leave
+	.cfi_def_cfa_register 7
+	.cfi_restore 6
+	.cfi_def_cfa_offset 8
+	ret
+	.cfi_endproc
+.LFE0:
+	.size	foo, .-foo
+
diff --git a/gas/testsuite/gas/scfi/x86_64/scfi-asm-marker-1.d b/gas/testsuite/gas/scfi/x86_64/scfi-asm-marker-1.d
new file mode 100644
index 00000000000..9103e9f1881
--- /dev/null
+++ b/gas/testsuite/gas/scfi/x86_64/scfi-asm-marker-1.d
@@ -0,0 +1,28 @@ 
+#as: --scfi -W
+#objdump: -Wf
+#name: Synthesize CFI for demarcated code blocks 1
+#...
+Contents of the .eh_frame section:
+
+00000000 0+0014 0+0000 CIE
+  Version:               1
+  Augmentation:          "zR"
+  Code alignment factor: 1
+  Data alignment factor: -8
+  Return address column: 16
+  Augmentation data:     [01][abc]
+  DW_CFA_def_cfa: r7 \(rsp\) ofs 8
+  DW_CFA_offset: r16 \(rip\) at cfa-8
+  DW_CFA_nop
+  DW_CFA_nop
+
+00000018 0+0010 0000001c FDE cie=00000000 pc=0+0000..0+000f
+  DW_CFA_nop
+  DW_CFA_nop
+  DW_CFA_nop
+
+0000002c 0+0010 00000030 FDE cie=00000000 pc=0+0000..0+0006
+  DW_CFA_advance_loc: 1 to 0+0001
+  DW_CFA_def_cfa_offset: 16
+
+#pass
diff --git a/gas/testsuite/gas/scfi/x86_64/scfi-asm-marker-1.l b/gas/testsuite/gas/scfi/x86_64/scfi-asm-marker-1.l
new file mode 100644
index 00000000000..f6a884c238f
--- /dev/null
+++ b/gas/testsuite/gas/scfi/x86_64/scfi-asm-marker-1.l
@@ -0,0 +1,3 @@ 
+.*Assembler messages:
+.*8: Warning: --scfi=all ignores some user-specified CFI directives
+.*10: Warning: missing label '.L3' in func 'foo' may result in imprecise cfg
diff --git a/gas/testsuite/gas/scfi/x86_64/scfi-asm-marker-1.s b/gas/testsuite/gas/scfi/x86_64/scfi-asm-marker-1.s
new file mode 100644
index 00000000000..88d78795643
--- /dev/null
+++ b/gas/testsuite/gas/scfi/x86_64/scfi-asm-marker-1.s
@@ -0,0 +1,27 @@ 
+# Testcase where a user may define hot and cold areas of function
+# Note how the .type, and .size directives may be placed differently
+# than a regular function.
+
+	.globl  foo
+	.type   foo, @function
+foo:
+        .cfi_startproc
+        testl   %edi, %edi
+        je      .L3
+        movl    b(%rip), %eax
+        ret
+        .cfi_endproc
+        .section        .text.unlikely
+        .cfi_startproc
+        .type   foo.cold, @function
+foo.cold:
+.L3:
+        pushq   %rax
+        .cfi_def_cfa_offset 16
+        call    abort
+       .cfi_endproc
+.LFE11:
+        .text
+        .size   foo, .-foo
+        .section        .text.unlikely
+        .size   foo.cold, .-foo.cold
diff --git a/gas/testsuite/gas/scfi/x86_64/scfi-asm-marker-2.d b/gas/testsuite/gas/scfi/x86_64/scfi-asm-marker-2.d
new file mode 100644
index 00000000000..3e5a4f05ea4
--- /dev/null
+++ b/gas/testsuite/gas/scfi/x86_64/scfi-asm-marker-2.d
@@ -0,0 +1,24 @@ 
+#as: --scfi -W
+#objdump: -Wf
+#name: Synthesize CFI for demarcated code blocks 2
+#...
+Contents of the .eh_frame section:
+
+00000000 0+0014 0+0000 CIE
+  Version:               1
+  Augmentation:          "zR"
+  Code alignment factor: 1
+  Data alignment factor: -8
+  Return address column: 16
+  Augmentation data:     [01][abc]
+  DW_CFA_def_cfa: r7 \(rsp\) ofs 8
+  DW_CFA_offset: r16 \(rip\) at cfa-8
+  DW_CFA_nop
+  DW_CFA_nop
+
+00000018 0+0014 0000001c FDE cie=00000000 pc=0+0000..0+000f
+  DW_CFA_nop
+  DW_CFA_nop
+#...
+
+#pass
diff --git a/gas/testsuite/gas/scfi/x86_64/scfi-asm-marker-2.l b/gas/testsuite/gas/scfi/x86_64/scfi-asm-marker-2.l
new file mode 100644
index 00000000000..6688ea8b5d8
--- /dev/null
+++ b/gas/testsuite/gas/scfi/x86_64/scfi-asm-marker-2.l
@@ -0,0 +1,3 @@ 
+.*Assembler messages:
+.*6: Warning: --scfi=all ignores some user-specified CFI directives
+.*8: Warning: missing label '.L3' in func 'foo' may result in imprecise cfg
diff --git a/gas/testsuite/gas/scfi/x86_64/scfi-asm-marker-2.s b/gas/testsuite/gas/scfi/x86_64/scfi-asm-marker-2.s
new file mode 100644
index 00000000000..9bcfe8d2e0a
--- /dev/null
+++ b/gas/testsuite/gas/scfi/x86_64/scfi-asm-marker-2.s
@@ -0,0 +1,11 @@ 
+# A programmer may not bother to set the size of the 
+# function symbols via an explicit .size directive.
+	.globl  foo
+	.type   foo, @function
+foo:
+        .cfi_startproc
+        testl   %edi, %edi
+        je      .L3
+        movl    b(%rip), %eax
+        ret
+       .cfi_endproc
diff --git a/gas/testsuite/gas/scfi/x86_64/scfi-asm-marker-3.d b/gas/testsuite/gas/scfi/x86_64/scfi-asm-marker-3.d
new file mode 100644
index 00000000000..3c1fcb2c85c
--- /dev/null
+++ b/gas/testsuite/gas/scfi/x86_64/scfi-asm-marker-3.d
@@ -0,0 +1,31 @@ 
+#as: --scfi -W
+#objdump: -Wf
+#name: Synthesize CFI for demarcated code blocks 3
+#...
+Contents of the .eh_frame section:
+
+00000000 0+0014 0+0000 CIE
+  Version:               1
+  Augmentation:          "zR"
+  Code alignment factor: 1
+  Data alignment factor: -8
+  Return address column: 16
+  Augmentation data:     [01][abc]
+  DW_CFA_def_cfa: r7 \(rsp\) ofs 8
+  DW_CFA_offset: r16 \(rip\) at cfa-8
+  DW_CFA_nop
+  DW_CFA_nop
+
+00000018 0+001c 0000001c FDE cie=00000000 pc=0+0000..0+0035
+  DW_CFA_advance_loc: 1 to 0+0001
+  DW_CFA_def_cfa_offset: 16
+  DW_CFA_offset: r6 \(rbp\) at cfa-16
+  DW_CFA_advance_loc: 3 to 0+0004
+  DW_CFA_def_cfa_register: r6 \(rbp\)
+  DW_CFA_advance_loc: 48 to 0+0034
+  DW_CFA_def_cfa_register: r7 \(rsp\)
+  DW_CFA_restore: r6 \(rbp\)
+  DW_CFA_def_cfa_offset: 8
+  DW_CFA_nop
+
+#pass
diff --git a/gas/testsuite/gas/scfi/x86_64/scfi-asm-marker-3.l b/gas/testsuite/gas/scfi/x86_64/scfi-asm-marker-3.l
new file mode 100644
index 00000000000..bcf4bacf823
--- /dev/null
+++ b/gas/testsuite/gas/scfi/x86_64/scfi-asm-marker-3.l
@@ -0,0 +1,2 @@ 
+.*Assembler messages:
+.*9: Warning: --scfi=all ignores some user-specified CFI directives
diff --git a/gas/testsuite/gas/scfi/x86_64/scfi-asm-marker-3.s b/gas/testsuite/gas/scfi/x86_64/scfi-asm-marker-3.s
new file mode 100644
index 00000000000..6a2b8e1ac14
--- /dev/null
+++ b/gas/testsuite/gas/scfi/x86_64/scfi-asm-marker-3.s
@@ -0,0 +1,38 @@ 
+# Testcase where the input may have interleaved sections,
+# possibly even text and data.
+	.globl	main
+	.type	main, @function
+main:
+.LFB1:
+#	.cfi_startproc
+	pushq	%rbp
+	.cfi_def_cfa_offset 16
+	.cfi_offset 6, -16
+	movq	%rsp, %rbp
+	.cfi_def_cfa_register 6
+	subq	$16, %rsp
+	movl	$17, %esi
+	movl	$5, %edi
+	call	add
+        .section        .rodata
+        .align 16
+        .type   __test_obj.0, @object
+        .size   __test_obj.0, 24
+__test_obj.0:
+        .string "test_elf_objs_in_rodata"
+.LC0:
+	.string	"the result is = %d\n"
+	.text
+	movl	%eax, -4(%rbp)
+	movl	-4(%rbp), %eax
+	movl	%eax, %esi
+	movl	$.LC0, %edi
+	movl	$0, %eax
+	call	printf
+	movl	$0, %eax
+	leave
+	.cfi_def_cfa_register 7
+	.cfi_restore 6
+	.cfi_def_cfa_offset 8
+	ret
+#	.cfi_endproc
diff --git a/gas/testsuite/gas/scfi/x86_64/scfi-bp-sp-1.d b/gas/testsuite/gas/scfi/x86_64/scfi-bp-sp-1.d
new file mode 100644
index 00000000000..373895c7caf
--- /dev/null
+++ b/gas/testsuite/gas/scfi/x86_64/scfi-bp-sp-1.d
@@ -0,0 +1,31 @@ 
+#as: --scfi -W
+#objdump: -Wf
+#name: Synthesize CFI for SP/FP based CFA switching 1
+#...
+Contents of the .eh_frame section:
+
+00000000 0+0014 0+0000 CIE
+  Version:               1
+  Augmentation:          "zR"
+  Code alignment factor: 1
+  Data alignment factor: -8
+  Return address column: 16
+  Augmentation data:     [01][abc]
+  DW_CFA_def_cfa: r7 \(rsp\) ofs 8
+  DW_CFA_offset: r16 \(rip\) at cfa-8
+  DW_CFA_nop
+  DW_CFA_nop
+
+0+0018 0+001c 0+001c FDE cie=0+0000 pc=0+0000..0+000c
+  DW_CFA_advance_loc: 1 to 0+0001
+  DW_CFA_def_cfa_offset: 16
+  DW_CFA_offset: r6 \(rbp\) at cfa-16
+  DW_CFA_advance_loc: 3 to 0+0004
+  DW_CFA_def_cfa_register: r6 \(rbp\)
+  DW_CFA_advance_loc: 6 to 0+000a
+  DW_CFA_def_cfa_register: r7 \(rsp\)
+  DW_CFA_advance_loc: 1 to 0+000b
+  DW_CFA_restore: r6 \(rbp\)
+  DW_CFA_def_cfa_offset: 8
+
+#pass
diff --git a/gas/testsuite/gas/scfi/x86_64/scfi-bp-sp-1.l b/gas/testsuite/gas/scfi/x86_64/scfi-bp-sp-1.l
new file mode 100644
index 00000000000..0e094077edd
--- /dev/null
+++ b/gas/testsuite/gas/scfi/x86_64/scfi-bp-sp-1.l
@@ -0,0 +1,2 @@ 
+.*Assembler messages:
+.*6: Warning: --scfi=all ignores some user-specified CFI directives
diff --git a/gas/testsuite/gas/scfi/x86_64/scfi-bp-sp-1.s b/gas/testsuite/gas/scfi/x86_64/scfi-bp-sp-1.s
new file mode 100644
index 00000000000..c9b949fdf8f
--- /dev/null
+++ b/gas/testsuite/gas/scfi/x86_64/scfi-bp-sp-1.s
@@ -0,0 +1,22 @@ 
+# Testcase for switching between sp/fp based CFA.
+	.text
+	.globl	foo
+	.type	foo, @function
+foo:
+	.cfi_startproc
+	pushq	%rbp
+	.cfi_def_cfa_offset 16
+	.cfi_offset 6, -16
+	movq    %rsp, %rbp
+	.cfi_def_cfa_register 6
+	addq	%rax, %rdi
+	mov	%rbp, %rsp
+	.cfi_def_cfa_register 7
+	pop	%rbp
+	.cfi_restore 6
+	.cfi_def_cfa_offset 8
+	ret
+	.cfi_endproc
+.LFE0:
+	.size	foo, .-foo
+
diff --git a/gas/testsuite/gas/scfi/x86_64/scfi-bp-sp-2.d b/gas/testsuite/gas/scfi/x86_64/scfi-bp-sp-2.d
new file mode 100644
index 00000000000..3f167c3ef1a
--- /dev/null
+++ b/gas/testsuite/gas/scfi/x86_64/scfi-bp-sp-2.d
@@ -0,0 +1,57 @@ 
+#as: --scfi -W
+#objdump: -Wf
+#name: Synthesize CFI for SP/FP based CFA switching 2
+#...
+Contents of the .eh_frame section:
+
+00000000 0+0014 0+0000 CIE
+  Version:               1
+  Augmentation:          "zR"
+  Code alignment factor: 1
+  Data alignment factor: -8
+  Return address column: 16
+  Augmentation data:     [01][abc]
+  DW_CFA_def_cfa: r7 \(rsp\) ofs 8
+  DW_CFA_offset: r16 \(rip\) at cfa-8
+  DW_CFA_nop
+  DW_CFA_nop
+
+0+0018 0+0044 0000001c FDE cie=00000000 pc=0+0000..0+0021
+  DW_CFA_advance_loc: 2 to 0+0002
+  DW_CFA_def_cfa_offset: 16
+  DW_CFA_offset: r14 \(r14\) at cfa-16
+  DW_CFA_advance_loc: 2 to 0+0004
+  DW_CFA_def_cfa_offset: 24
+  DW_CFA_offset: r13 \(r13\) at cfa-24
+  DW_CFA_advance_loc: 2 to 0+0006
+  DW_CFA_def_cfa_offset: 32
+  DW_CFA_offset: r12 \(r12\) at cfa-32
+  DW_CFA_advance_loc: 1 to 0+0007
+  DW_CFA_def_cfa_offset: 40
+  DW_CFA_offset: r6 \(rbp\) at cfa-40
+  DW_CFA_advance_loc: 1 to 0+0008
+  DW_CFA_def_cfa_offset: 48
+  DW_CFA_offset: r3 \(rbx\) at cfa-48
+  DW_CFA_advance_loc: 7 to 0+000f
+  DW_CFA_def_cfa_offset: 80
+  DW_CFA_advance_loc: 9 to 0+0018
+  DW_CFA_def_cfa_offset: 48
+  DW_CFA_advance_loc: 1 to 0+0019
+  DW_CFA_restore: r3 \(rbx\)
+  DW_CFA_def_cfa_offset: 40
+  DW_CFA_advance_loc: 1 to 0+001a
+  DW_CFA_restore: r6 \(rbp\)
+  DW_CFA_def_cfa_offset: 32
+  DW_CFA_advance_loc: 2 to 0+001c
+  DW_CFA_restore: r12 \(r12\)
+  DW_CFA_def_cfa_offset: 24
+  DW_CFA_advance_loc: 2 to 0+001e
+  DW_CFA_restore: r13 \(r13\)
+  DW_CFA_def_cfa_offset: 16
+  DW_CFA_advance_loc: 2 to 0+0020
+  DW_CFA_restore: r14 \(r14\)
+  DW_CFA_def_cfa_offset: 8
+  DW_CFA_nop
+#...
+
+#pass
diff --git a/gas/testsuite/gas/scfi/x86_64/scfi-bp-sp-2.l b/gas/testsuite/gas/scfi/x86_64/scfi-bp-sp-2.l
new file mode 100644
index 00000000000..0e094077edd
--- /dev/null
+++ b/gas/testsuite/gas/scfi/x86_64/scfi-bp-sp-2.l
@@ -0,0 +1,2 @@ 
+.*Assembler messages:
+.*6: Warning: --scfi=all ignores some user-specified CFI directives
diff --git a/gas/testsuite/gas/scfi/x86_64/scfi-bp-sp-2.s b/gas/testsuite/gas/scfi/x86_64/scfi-bp-sp-2.s
new file mode 100644
index 00000000000..f17c5c8dfc4
--- /dev/null
+++ b/gas/testsuite/gas/scfi/x86_64/scfi-bp-sp-2.s
@@ -0,0 +1,49 @@ 
+# Testcase for switching between sp/fp based CFA.
+	.text
+	.globl	foo
+	.type	foo, @function
+foo:
+        .cfi_startproc
+        pushq   %r14
+        .cfi_def_cfa_offset 16
+        .cfi_offset 14, -16
+        pushq   %r13
+        .cfi_def_cfa_offset 24
+        .cfi_offset 13, -24
+        pushq   %r12
+        .cfi_def_cfa_offset 32
+        .cfi_offset 12, -32
+        pushq   %rbp
+        .cfi_def_cfa_offset 40
+        .cfi_offset 6, -40
+        pushq   %rbx
+        .cfi_def_cfa_offset 48
+        .cfi_offset 3, -48
+        movq    %rdi, %rbx
+        subq    $32, %rsp
+        .cfi_def_cfa_offset 80
+# This mov does not switch CFA tracking to REG_FP, because there has already
+# been stack usage between here and the push %rbp
+        movq    %rsp, %rbp
+        xorl    %eax, %eax
+        addq    $32, %rsp
+        .cfi_def_cfa_offset 48
+        popq    %rbx
+	.cfi_restore 3
+        .cfi_def_cfa_offset 40
+        popq    %rbp
+	.cfi_restore 6
+        .cfi_def_cfa_offset 32
+        popq    %r12
+	.cfi_restore 12
+        .cfi_def_cfa_offset 24
+        popq    %r13
+	.cfi_restore 13
+        .cfi_def_cfa_offset 16
+        popq    %r14
+	.cfi_restore 14
+        .cfi_def_cfa_offset 8
+        ret
+	.cfi_endproc
+	.size	foo, .-foo
+
diff --git a/gas/testsuite/gas/scfi/x86_64/scfi-callee-saved-1.d b/gas/testsuite/gas/scfi/x86_64/scfi-callee-saved-1.d
new file mode 100644
index 00000000000..feb93d28d7a
--- /dev/null
+++ b/gas/testsuite/gas/scfi/x86_64/scfi-callee-saved-1.d
@@ -0,0 +1,40 @@ 
+#as: --scfi
+#objdump: -Wf
+#name: SCFI for callee-saved registers 1
+#...
+Contents of the .eh_frame section:
+
+00000000 0+0014 0+0000 CIE
+  Version:               1
+  Augmentation:          "zR"
+  Code alignment factor: 1
+  Data alignment factor: -8
+  Return address column: 16
+  Augmentation data:     [01][abc]
+  DW_CFA_def_cfa: r7 \(rsp\) ofs 8
+  DW_CFA_offset: r16 \(rip\) at cfa-8
+  DW_CFA_nop
+  DW_CFA_nop
+
+0+0018 0+0002c 0+0001c FDE cie=0+0000 pc=0+0000..0+0007
+  DW_CFA_advance_loc: 1 to 0+0001
+  DW_CFA_def_cfa_offset: 16
+  DW_CFA_advance_loc: 1 to 0+0002
+  DW_CFA_def_cfa_offset: 24
+  DW_CFA_offset: r3 \(rbx\) at cfa-24
+  DW_CFA_advance_loc: 1 to 0+0003
+  DW_CFA_def_cfa_offset: 32
+  DW_CFA_offset: r6 \(rbp\) at cfa-32
+  DW_CFA_advance_loc: 1 to 0+0004
+  DW_CFA_restore: r6 \(rbp\)
+  DW_CFA_def_cfa_offset: 24
+  DW_CFA_advance_loc: 1 to 0+0005
+  DW_CFA_restore: r3 \(rbx\)
+  DW_CFA_def_cfa_offset: 16
+  DW_CFA_advance_loc: 1 to 0+0006
+  DW_CFA_def_cfa_offset: 8
+  DW_CFA_nop
+  DW_CFA_nop
+#...
+
+#pass
diff --git a/gas/testsuite/gas/scfi/x86_64/scfi-callee-saved-1.l b/gas/testsuite/gas/scfi/x86_64/scfi-callee-saved-1.l
new file mode 100644
index 00000000000..2762adba5b1
--- /dev/null
+++ b/gas/testsuite/gas/scfi/x86_64/scfi-callee-saved-1.l
@@ -0,0 +1,2 @@ 
+.*Assembler messages:
+.*8: Warning: --scfi=all ignores some user-specified CFI directives
diff --git a/gas/testsuite/gas/scfi/x86_64/scfi-callee-saved-1.s b/gas/testsuite/gas/scfi/x86_64/scfi-callee-saved-1.s
new file mode 100644
index 00000000000..db3a2690bf3
--- /dev/null
+++ b/gas/testsuite/gas/scfi/x86_64/scfi-callee-saved-1.s
@@ -0,0 +1,26 @@ 
+	.text
+	.globl	foo
+	.type	foo, @function
+foo:
+#	.cfi_startproc
+	pushq	%rax
+	.cfi_def_cfa_offset 16
+	push	%rbx
+	.cfi_def_cfa_offset 24
+	.cfi_offset 3, -24
+	pushq	%rbp
+        .cfi_def_cfa_offset 32
+        .cfi_offset 6, -32
+	popq	%rbp
+	.cfi_def_cfa_offset 24
+	.cfi_restore 6
+	popq	%rbx
+	.cfi_def_cfa_offset 16
+	.cfi_restore 3
+	popq	%rax
+        .cfi_def_cfa_offset 8
+	ret
+#	.cfi_endproc
+.LFE0:
+	.size	foo, .-foo
+
diff --git a/gas/testsuite/gas/scfi/x86_64/scfi-callee-saved-2.d b/gas/testsuite/gas/scfi/x86_64/scfi-callee-saved-2.d
new file mode 100644
index 00000000000..57a99b04557
--- /dev/null
+++ b/gas/testsuite/gas/scfi/x86_64/scfi-callee-saved-2.d
@@ -0,0 +1,41 @@ 
+#as: --scfi -W
+#objdump: -Wf
+#name: SCFI for callee-saved registers 2
+#...
+Contents of the .eh_frame section:
+
+00000000 0+0014 0+0000 CIE
+  Version:               1
+  Augmentation:          "zR"
+  Code alignment factor: 1
+  Data alignment factor: -8
+  Return address column: 16
+  Augmentation data:     [01][abc]
+  DW_CFA_def_cfa: r7 \(rsp\) ofs 8
+  DW_CFA_offset: r16 \(rip\) at cfa-8
+  DW_CFA_nop
+  DW_CFA_nop
+
+00000018 0+002c 0000001c FDE cie=00000000 pc=0+0000..0+0017
+  DW_CFA_advance_loc: 2 to 0+0002
+  DW_CFA_def_cfa_offset: 16
+  DW_CFA_offset: r12 \(r12\) at cfa-16
+  DW_CFA_advance_loc: 2 to 0+0004
+  DW_CFA_def_cfa_offset: 24
+  DW_CFA_offset: r13 \(r13\) at cfa-24
+  DW_CFA_advance_loc: 9 to 0+000d
+  DW_CFA_def_cfa_offset: 32
+  DW_CFA_advance_loc: 1 to 0+000e
+  DW_CFA_def_cfa_offset: 40
+  DW_CFA_advance_loc: 4 to 0+0012
+  DW_CFA_def_cfa_offset: 24
+  DW_CFA_advance_loc: 2 to 0+0014
+  DW_CFA_restore: r13 \(r13\)
+  DW_CFA_def_cfa_offset: 16
+  DW_CFA_advance_loc: 2 to 0+0016
+  DW_CFA_restore: r12 \(r12\)
+  DW_CFA_def_cfa_offset: 8
+  DW_CFA_nop
+#...
+
+#pass
diff --git a/gas/testsuite/gas/scfi/x86_64/scfi-callee-saved-2.l b/gas/testsuite/gas/scfi/x86_64/scfi-callee-saved-2.l
new file mode 100644
index 00000000000..bcf4bacf823
--- /dev/null
+++ b/gas/testsuite/gas/scfi/x86_64/scfi-callee-saved-2.l
@@ -0,0 +1,2 @@ 
+.*Assembler messages:
+.*9: Warning: --scfi=all ignores some user-specified CFI directives
diff --git a/gas/testsuite/gas/scfi/x86_64/scfi-callee-saved-2.s b/gas/testsuite/gas/scfi/x86_64/scfi-callee-saved-2.s
new file mode 100644
index 00000000000..7b10a2c1c6b
--- /dev/null
+++ b/gas/testsuite/gas/scfi/x86_64/scfi-callee-saved-2.s
@@ -0,0 +1,42 @@ 
+# Testcase for save reg ops for callee-saved registers
+# These latter two pushq's of callee-saved regs must NOT generate
+# .cfi_offset.
+
+	.text
+	.globl	foo
+	.type	foo, @function
+foo:
+	.cfi_startproc
+	pushq	%r12
+	.cfi_def_cfa_offset 16
+	.cfi_offset 12, -16
+	pushq	%r13
+	.cfi_def_cfa_offset 24
+	.cfi_offset 13, -24
+# The function may use callee-saved registers for its use, and may even
+# chose to spill them to stack if necessary.
+	addq    %rax, %r13
+	subq 	$8, %r13
+# These two pushq's of callee-saved regs must NOT generate
+# .cfi_offset.
+	pushq	%r13
+	.cfi_def_cfa_offset 32
+	pushq	%rax
+	.cfi_def_cfa_offset 40
+# Adjust the REG_SP to get rid of local stack usage.
+	addq	$16, %rsp
+	.cfi_def_cfa_offset 24
+# The SCFI machinery keeps track of where the callee-saved registers
+# are on the stack.  It generates a restore operation if the stack
+# offsets match.
+	popq	%r13
+	.cfi_restore 13
+	.cfi_def_cfa_offset 16
+	popq	%r12
+	.cfi_restore 12
+        .cfi_def_cfa_offset 8
+	ret
+	.cfi_endproc
+.LFE0:
+	.size	foo, .-foo
+
diff --git a/gas/testsuite/gas/scfi/x86_64/scfi-callee-saved-3.d b/gas/testsuite/gas/scfi/x86_64/scfi-callee-saved-3.d
new file mode 100644
index 00000000000..73eb147a539
--- /dev/null
+++ b/gas/testsuite/gas/scfi/x86_64/scfi-callee-saved-3.d
@@ -0,0 +1,42 @@ 
+#as: --scfi -W
+#objdump: -Wf
+#name: SCFI for callee-saved registers 3
+#...
+Contents of the .eh_frame section:
+
+00000000 0+0014 0+0000 CIE
+  Version:               1
+  Augmentation:          "zR"
+  Code alignment factor: 1
+  Data alignment factor: -8
+  Return address column: 16
+  Augmentation data:     [01][abc]
+  DW_CFA_def_cfa: r7 \(rsp\) ofs 8
+  DW_CFA_offset: r16 \(rip\) at cfa-8
+  DW_CFA_nop
+  DW_CFA_nop
+
+00000018 0+002c 0000001c FDE cie=00000000 pc=0+0000..0+0016
+  DW_CFA_advance_loc: 2 to 0+0002
+  DW_CFA_def_cfa_offset: 16
+  DW_CFA_offset: r12 \(r12\) at cfa-16
+  DW_CFA_advance_loc: 2 to 0+0004
+  DW_CFA_def_cfa_offset: 24
+  DW_CFA_offset: r13 \(r13\) at cfa-24
+  DW_CFA_advance_loc: 9 to 0+000d
+  DW_CFA_def_cfa_offset: 32
+  DW_CFA_advance_loc: 1 to 0+000e
+  DW_CFA_def_cfa_offset: 40
+  DW_CFA_advance_loc: 1 to 0+000f
+  DW_CFA_def_cfa_offset: 32
+  DW_CFA_advance_loc: 2 to 0+0011
+  DW_CFA_def_cfa_offset: 24
+  DW_CFA_advance_loc: 2 to 0+0013
+  DW_CFA_restore: r13 \(r13\)
+  DW_CFA_def_cfa_offset: 16
+  DW_CFA_advance_loc: 2 to 0+0015
+  DW_CFA_restore: r12 \(r12\)
+  DW_CFA_def_cfa_offset: 8
+  DW_CFA_nop
+
+#pass
diff --git a/gas/testsuite/gas/scfi/x86_64/scfi-callee-saved-3.l b/gas/testsuite/gas/scfi/x86_64/scfi-callee-saved-3.l
new file mode 100644
index 00000000000..2930658dc2d
--- /dev/null
+++ b/gas/testsuite/gas/scfi/x86_64/scfi-callee-saved-3.l
@@ -0,0 +1,3 @@ 
+.*Assembler messages:
+.*6: Warning: --scfi=all ignores some user-specified CFI directives
+.*25: Warning: SCFI: asymetrical register restore
diff --git a/gas/testsuite/gas/scfi/x86_64/scfi-callee-saved-3.s b/gas/testsuite/gas/scfi/x86_64/scfi-callee-saved-3.s
new file mode 100644
index 00000000000..a2bb53017f1
--- /dev/null
+++ b/gas/testsuite/gas/scfi/x86_64/scfi-callee-saved-3.s
@@ -0,0 +1,40 @@ 
+# Testcase for save reg ops for callee-saved registers
+	.text
+	.globl	foo
+	.type	foo, @function
+foo:
+	.cfi_startproc
+	pushq	%r12
+	.cfi_def_cfa_offset 16
+	.cfi_offset 12, -16
+	pushq	%r13
+	.cfi_def_cfa_offset 24
+	.cfi_offset 13, -24
+# The program may use callee-saved registers for its use, and may even
+# chose to spill them to stack if necessary.
+	addq    %rax, %r13
+	subq 	$8, %r13
+# These two pushq's of callee-saved regs must NOT generate
+# .cfi_offset.
+	pushq	%r13
+	.cfi_def_cfa_offset 32
+	pushq	%rax
+	.cfi_def_cfa_offset 40
+	popq	%rax
+	.cfi_def_cfa_offset 32
+	popq	%r13
+	.cfi_def_cfa_offset 24
+# The SCFI machinery keeps track of where the callee-saved registers
+# are on the stack.  It generates a restore operation if the stack
+# offsets match.
+	popq	%r13
+	.cfi_restore 13
+	.cfi_def_cfa_offset 16
+	popq	%r12
+	.cfi_restore 12
+        .cfi_def_cfa_offset 8
+	ret
+	.cfi_endproc
+.LFE0:
+	.size	foo, .-foo
+
diff --git a/gas/testsuite/gas/scfi/x86_64/scfi-callee-saved-4.d b/gas/testsuite/gas/scfi/x86_64/scfi-callee-saved-4.d
new file mode 100644
index 00000000000..d6543fa8f6c
--- /dev/null
+++ b/gas/testsuite/gas/scfi/x86_64/scfi-callee-saved-4.d
@@ -0,0 +1,40 @@ 
+#as: -W --scfi
+#objdump: -Wf
+#name: SCFI for callee-saved registers 4
+#...
+Contents of the .eh_frame section:
+
+00000000 0+0014 0+0000 CIE
+  Version:               1
+  Augmentation:          "zR"
+  Code alignment factor: 1
+  Data alignment factor: -8
+  Return address column: 16
+  Augmentation data:     [01][abc]
+  DW_CFA_def_cfa: r7 \(rsp\) ofs 8
+  DW_CFA_offset: r16 \(rip\) at cfa-8
+  DW_CFA_nop
+  DW_CFA_nop
+
+00000018 0+002c 0000001c FDE cie=00000000 pc=0+0000..0+005e
+  DW_CFA_advance_loc: 5 to 0+0005
+  DW_CFA_def_cfa_offset: 16
+  DW_CFA_offset: r6 \(rbp\) at cfa-16
+  DW_CFA_advance_loc: 3 to 0+0008
+  DW_CFA_def_cfa_register: r6 \(rbp\)
+  DW_CFA_advance_loc: 2 to 0+000a
+  DW_CFA_offset: r12 \(r12\) at cfa-24
+  DW_CFA_advance_loc: 1 to 0+000b
+  DW_CFA_offset: r3 \(rbx\) at cfa-32
+  DW_CFA_advance_loc1: 79 to 0+005a
+  DW_CFA_restore: r3 \(rbx\)
+  DW_CFA_advance_loc: 2 to 0+005c
+  DW_CFA_restore: r12 \(r12\)
+  DW_CFA_advance_loc: 1 to 0+005d
+  DW_CFA_def_cfa_register: r7 \(rsp\)
+  DW_CFA_restore: r6 \(rbp\)
+  DW_CFA_def_cfa_offset: 8
+  DW_CFA_nop
+#...
+
+#pass
diff --git a/gas/testsuite/gas/scfi/x86_64/scfi-callee-saved-4.l b/gas/testsuite/gas/scfi/x86_64/scfi-callee-saved-4.l
new file mode 100644
index 00000000000..58b417460e5
--- /dev/null
+++ b/gas/testsuite/gas/scfi/x86_64/scfi-callee-saved-4.l
@@ -0,0 +1,3 @@ 
+.*Assembler messages:
+.*4: Warning: --scfi=all ignores some user-specified CFI directives
+.*24: Warning: SCFI: asymetrical register restore
diff --git a/gas/testsuite/gas/scfi/x86_64/scfi-callee-saved-4.s b/gas/testsuite/gas/scfi/x86_64/scfi-callee-saved-4.s
new file mode 100644
index 00000000000..be29a3ccfa8
--- /dev/null
+++ b/gas/testsuite/gas/scfi/x86_64/scfi-callee-saved-4.s
@@ -0,0 +1,55 @@ 
+	.type	byte_insert_op1, @function
+byte_insert_op1:
+.LFB10:
+	.cfi_startproc
+	endbr64
+	pushq	%rbp
+	.cfi_def_cfa_offset 16
+	.cfi_offset 6, -16
+	movq	%rsp, %rbp
+	.cfi_def_cfa_register 6
+	pushq	%r12
+	.cfi_offset 12, -24
+	pushq	%rbx
+	.cfi_offset 3, -32
+	subq	$24, %rsp
+	movl	%edi, -20(%rbp)
+	movq	%rsi, -32(%rbp)
+	movl	%edx, -24(%rbp)
+	movq	%rcx, -40(%rbp)
+# The program may use callee-saved registers for its use, and may even
+# chose to read them from stack if necessary.  The following use should
+# not be treated as reg restore for SCFI purposes (because rbx has been
+# saved to -16(%rbp).
+	movq	-40(%rbp), %rbx
+	movq	-40(%rbp), %rax
+	leaq	3(%rax), %r12
+	jmp	.L563
+.L564:
+	subq	$1, %rbx
+	subq	$1, %r12
+	movzbl	(%rbx), %eax
+	movb	%al, (%r12)
+.L563:
+	cmpq	-32(%rbp), %rbx
+	jne	.L564
+	movl	-24(%rbp), %edx
+	movq	-32(%rbp), %rcx
+	movl	-20(%rbp), %eax
+	movq	%rcx, %rsi
+	movl	%eax, %edi
+	call	byte_store_op1
+	nop
+	addq	$24, %rsp
+	popq	%rbx
+	.cfi_restore 3
+	popq	%r12
+	.cfi_restore 12
+	popq	%rbp
+	.cfi_def_cfa_register 7
+	.cfi_restore 6
+	.cfi_def_cfa_offset 8
+	ret
+	.cfi_endproc
+.LFE10:
+	.size	byte_insert_op1, .-byte_insert_op1
diff --git a/gas/testsuite/gas/scfi/x86_64/scfi-cfg-1.d b/gas/testsuite/gas/scfi/x86_64/scfi-cfg-1.d
new file mode 100644
index 00000000000..aa14af48613
--- /dev/null
+++ b/gas/testsuite/gas/scfi/x86_64/scfi-cfg-1.d
@@ -0,0 +1,36 @@ 
+#as: --scfi -W
+#objdump: -Wf
+#name: Synthesize CFI in presence of control flow 1
+#...
+Contents of the .eh_frame section:
+
+00000000 0+0014 0+0000 CIE
+  Version:               1
+  Augmentation:          "zR"
+  Code alignment factor: 1
+  Data alignment factor: -8
+  Return address column: 16
+  Augmentation data:     [01][abc]
+  DW_CFA_def_cfa: r7 \(rsp\) ofs 8
+  DW_CFA_offset: r16 \(rip\) at cfa-8
+  DW_CFA_nop
+  DW_CFA_nop
+
+0+0018 0+0024 0000001c FDE cie=00000000 pc=0+0000..0+003a
+  DW_CFA_advance_loc: 1 to 0+0001
+  DW_CFA_def_cfa_offset: 16
+  DW_CFA_offset: r3 \(rbx\) at cfa-16
+  DW_CFA_advance_loc: 37 to 0+0026
+  DW_CFA_remember_state
+  DW_CFA_advance_loc: 1 to 0+0027
+  DW_CFA_restore: r3 \(rbx\)
+  DW_CFA_def_cfa_offset: 8
+  DW_CFA_advance_loc: 1 to 0+0028
+  DW_CFA_restore_state
+  DW_CFA_advance_loc: 9 to 0+0031
+  DW_CFA_restore: r3 \(rbx\)
+  DW_CFA_def_cfa_offset: 8
+  DW_CFA_nop
+#...
+
+#pass
diff --git a/gas/testsuite/gas/scfi/x86_64/scfi-cfg-1.l b/gas/testsuite/gas/scfi/x86_64/scfi-cfg-1.l
new file mode 100644
index 00000000000..653937edbf9
--- /dev/null
+++ b/gas/testsuite/gas/scfi/x86_64/scfi-cfg-1.l
@@ -0,0 +1,2 @@ 
+.*Assembler messages:
+.*15: Warning: --scfi=all ignores some user-specified CFI directives
diff --git a/gas/testsuite/gas/scfi/x86_64/scfi-cfg-1.s b/gas/testsuite/gas/scfi/x86_64/scfi-cfg-1.s
new file mode 100644
index 00000000000..9e72ed0ed2b
--- /dev/null
+++ b/gas/testsuite/gas/scfi/x86_64/scfi-cfg-1.s
@@ -0,0 +1,47 @@ 
+# Testcase with one dominator bb and two exit bbs
+# Something like for: return ferror (f) || fclose (f) != 0;
+	.text
+	.section	.rodata.str1.1,"aMS",@progbits,1
+.LC0:
+	.string	"w"
+.LC1:
+	.string	"conftest.out"
+	.section	.text.startup,"ax",@progbits
+	.p2align 4
+	.globl	main
+	.type	main, @function
+main:
+.LFB11:
+	.cfi_startproc
+	pushq	%rbx
+	.cfi_def_cfa_offset 16
+	.cfi_offset 3, -16
+	movl	$.LC0, %esi
+	movl	$.LC1, %edi
+	call	fopen
+	movq	%rax, %rdi
+	movq	%rax, %rbx
+	call	ferror
+	movl	%eax, %edx
+	movl	$1, %eax
+	testl	%edx, %edx
+	je	.L7
+	.cfi_remember_state
+	popq	%rbx
+	.cfi_restore 3
+	.cfi_def_cfa_offset 8
+	ret
+.L7:
+	.cfi_restore_state
+	movq	%rbx, %rdi
+	call	fclose
+	popq	%rbx
+	.cfi_restore 3
+	.cfi_def_cfa_offset 8
+	testl	%eax, %eax
+	setne	%al
+	movzbl	%al, %eax
+	ret
+	.cfi_endproc
+.LFE11:
+	.size	main, .-main
diff --git a/gas/testsuite/gas/scfi/x86_64/scfi-cfg-2.d b/gas/testsuite/gas/scfi/x86_64/scfi-cfg-2.d
new file mode 100644
index 00000000000..736c26386e7
--- /dev/null
+++ b/gas/testsuite/gas/scfi/x86_64/scfi-cfg-2.d
@@ -0,0 +1,28 @@ 
+#as: --scfi -W
+#objdump: -Wf
+#name: Synthesize CFI in presence of control flow 2
+#...
+Contents of the .eh_frame section:
+
+00000000 0+0014 0+0000 CIE
+  Version:               1
+  Augmentation:          "zR"
+  Code alignment factor: 1
+  Data alignment factor: -8
+  Return address column: 16
+  Augmentation data:     [01][abc]
+  DW_CFA_def_cfa: r7 \(rsp\) ofs 8
+  DW_CFA_offset: r16 \(rip\) at cfa-8
+  DW_CFA_nop
+  DW_CFA_nop
+
+0+0018 0+0001c 0+001c FDE cie=00000000 pc=0000000000000000..0000000000000016
+  DW_CFA_advance_loc: 1 to 0+0001
+  DW_CFA_def_cfa_offset: 16
+  DW_CFA_offset: r6 \(rbp\) at cfa-16
+  DW_CFA_advance_loc: 3 to 0+0004
+  DW_CFA_def_cfa_register: r6 \(rbp\)
+  DW_CFA_nop
+#...
+
+#pass
diff --git a/gas/testsuite/gas/scfi/x86_64/scfi-cfg-2.l b/gas/testsuite/gas/scfi/x86_64/scfi-cfg-2.l
new file mode 100644
index 00000000000..2762adba5b1
--- /dev/null
+++ b/gas/testsuite/gas/scfi/x86_64/scfi-cfg-2.l
@@ -0,0 +1,2 @@ 
+.*Assembler messages:
+.*8: Warning: --scfi=all ignores some user-specified CFI directives
diff --git a/gas/testsuite/gas/scfi/x86_64/scfi-cfg-2.s b/gas/testsuite/gas/scfi/x86_64/scfi-cfg-2.s
new file mode 100644
index 00000000000..adf1df08bc4
--- /dev/null
+++ b/gas/testsuite/gas/scfi/x86_64/scfi-cfg-2.s
@@ -0,0 +1,21 @@ 
+# Testcase for CFG creation of ginsns
+# This testcase has no return instruction at the end.
+	.text
+	.globl	main
+	.type	main, @function
+main:
+.LFB7:
+	.cfi_startproc
+	pushq	%rbp
+	.cfi_def_cfa_offset 16
+	.cfi_offset 6, -16
+	movq	%rsp, %rbp
+	.cfi_def_cfa_register 6
+	call	foo
+	shrl	$31, %eax
+	movzbl	%al, %eax
+	movl	%eax, %edi
+	call	exit
+	.cfi_endproc
+.LFE7:
+	.size	main, .-main
diff --git a/gas/testsuite/gas/scfi/x86_64/scfi-cfi-label-1.d b/gas/testsuite/gas/scfi/x86_64/scfi-cfi-label-1.d
new file mode 100644
index 00000000000..6e11583a534
--- /dev/null
+++ b/gas/testsuite/gas/scfi/x86_64/scfi-cfi-label-1.d
@@ -0,0 +1,37 @@ 
+#as: --scfi -W
+#objdump: -tWf
+#name: SCFI no ignore .cfi_label
+#...
+.*\.o:     file format elf.*
+
+SYMBOL TABLE:
+0+0000 l    d  \.text	0+0000 \.text
+0+002b l       \.eh_frame	0+0000 cfi2
+0+0000 g     F \.text	0+0008 foo
+0+002a g       \.eh_frame	0+0000 cfi1
+
+
+Contents of the .eh_frame section:
+
+
+00000000 0+0014 00000000 CIE
+  Version:               1
+  Augmentation:          "zR"
+  Code alignment factor: 1
+  Data alignment factor: -8
+  Return address column: 16
+  Augmentation data:     1b
+  DW_CFA_def_cfa: r7 \(rsp\) ofs 8
+  DW_CFA_offset: r16 \(rip\) at cfa-8
+  DW_CFA_nop
+  DW_CFA_nop
+
+00000018 0+0014 0000001c FDE cie=00000000 pc=0+0000..0+0008
+  DW_CFA_advance_loc: 1 to 0+0001
+  DW_CFA_advance_loc: 1 to 0+0002
+  DW_CFA_advance_loc: 1 to 0+0003
+  DW_CFA_advance_loc: 4 to 0+0007
+  DW_CFA_def_cfa_offset: 0
+  DW_CFA_nop
+
+#pass
diff --git a/gas/testsuite/gas/scfi/x86_64/scfi-cfi-label-1.l b/gas/testsuite/gas/scfi/x86_64/scfi-cfi-label-1.l
new file mode 100644
index 00000000000..0e094077edd
--- /dev/null
+++ b/gas/testsuite/gas/scfi/x86_64/scfi-cfi-label-1.l
@@ -0,0 +1,2 @@ 
+.*Assembler messages:
+.*6: Warning: --scfi=all ignores some user-specified CFI directives
diff --git a/gas/testsuite/gas/scfi/x86_64/scfi-cfi-label-1.s b/gas/testsuite/gas/scfi/x86_64/scfi-cfi-label-1.s
new file mode 100644
index 00000000000..845696d4749
--- /dev/null
+++ b/gas/testsuite/gas/scfi/x86_64/scfi-cfi-label-1.s
@@ -0,0 +1,19 @@ 
+# Testcase for .cfi_label directives
+	.text
+	.globl	foo
+	.type	foo, @function
+foo:
+	.cfi_startproc
+	nop
+        .globl cfi1
+        .cfi_label cfi1
+	nop
+	.cfi_label cfi2
+	nop
+	.cfi_label .Lcfi3
+	addq    $8, %rsp
+	.cfi_def_cfa_offset 0
+	ret
+	.cfi_endproc
+.LFE0:
+	.size	foo, .-foo
diff --git a/gas/testsuite/gas/scfi/x86_64/scfi-cofi-1.d b/gas/testsuite/gas/scfi/x86_64/scfi-cofi-1.d
new file mode 100644
index 00000000000..af4fa429339
--- /dev/null
+++ b/gas/testsuite/gas/scfi/x86_64/scfi-cofi-1.d
@@ -0,0 +1,5 @@ 
+#as: --scfi -W
+#objdump: -Wf
+#name: Synthesize CFI for add insn
+
+#pass
diff --git a/gas/testsuite/gas/scfi/x86_64/scfi-cofi-1.l b/gas/testsuite/gas/scfi/x86_64/scfi-cofi-1.l
new file mode 100644
index 00000000000..fd57194cedf
--- /dev/null
+++ b/gas/testsuite/gas/scfi/x86_64/scfi-cofi-1.l
@@ -0,0 +1,3 @@ 
+.*Assembler messages:
+.*12: Warning: --scfi=all ignores some user-specified CFI directives
+.*22: Warning: Untraceable control flow for func 'foo'; Skipping SCFI
diff --git a/gas/testsuite/gas/scfi/x86_64/scfi-cofi-1.s b/gas/testsuite/gas/scfi/x86_64/scfi-cofi-1.s
new file mode 100644
index 00000000000..fa03b5ef5e4
--- /dev/null
+++ b/gas/testsuite/gas/scfi/x86_64/scfi-cofi-1.s
@@ -0,0 +1,23 @@ 
+# Testcase with a variety of "change of flow instructions"
+#
+# Must be run with -W so it remains warning free.
+#
+# This test does not have much going on wrt synthesis of CFI;
+# it just aims to ensure x8_64 -> ginsn decoding must behave
+# gracefully for these "change of flow instructions"
+	.text
+	.globl	foo
+	.type	foo, @function
+foo:
+	.cfi_startproc
+	addq    %rdx, %rax
+	notrack jmp     *%rax
+	call   *%r8
+	jmp     *48(%rdi)
+	jo      .L179
+.L179:
+	ret
+	.cfi_endproc
+.LFE0:
+	.size	foo, .-foo
+
diff --git a/gas/testsuite/gas/scfi/x86_64/scfi-diag-1.l b/gas/testsuite/gas/scfi/x86_64/scfi-diag-1.l
new file mode 100644
index 00000000000..ecc6b82ce97
--- /dev/null
+++ b/gas/testsuite/gas/scfi/x86_64/scfi-diag-1.l
@@ -0,0 +1,4 @@ 
+.*Assembler messages:
+.*7: Warning: --scfi=all ignores some user-specified CFI directives
+.*14: Error: SCFI: usage of REG_FP as scratch not supported
+.*22: Warning: SCFI: forward pass failed for func 'foo'
diff --git a/gas/testsuite/gas/scfi/x86_64/scfi-diag-1.s b/gas/testsuite/gas/scfi/x86_64/scfi-diag-1.s
new file mode 100644
index 00000000000..c09ec0da1c4
--- /dev/null
+++ b/gas/testsuite/gas/scfi/x86_64/scfi-diag-1.s
@@ -0,0 +1,23 @@ 
+# Testcase for REG_FP based CFA
+# and using REG_FP as scratch.
+	.text
+	.globl	foo
+	.type	foo, @function
+foo:
+	.cfi_startproc
+	pushq	%rbp
+	.cfi_def_cfa_offset 16
+	.cfi_offset 6, -16
+	movq    %rsp, %rbp
+	.cfi_def_cfa_register 6
+# The following add causes REG_FP to become untraceable
+	addq	%rax, %rbp
+	.cfi_def_cfa_register 7
+	pop	%rbp
+	.cfi_restore 6
+	.cfi_def_cfa_offset 8
+	ret
+	.cfi_endproc
+.LFE0:
+	.size	foo, .-foo
+
diff --git a/gas/testsuite/gas/scfi/x86_64/scfi-diag-2.l b/gas/testsuite/gas/scfi/x86_64/scfi-diag-2.l
new file mode 100644
index 00000000000..d3adbeca35a
--- /dev/null
+++ b/gas/testsuite/gas/scfi/x86_64/scfi-diag-2.l
@@ -0,0 +1,4 @@ 
+.*Assembler messages:
+.*5: Warning: --scfi=all ignores some user-specified CFI directives
+.*21: Warning: SCFI: asymetrical register restore
+.*22: Warning: SCFI: asymetrical register restore
diff --git a/gas/testsuite/gas/scfi/x86_64/scfi-diag-2.s b/gas/testsuite/gas/scfi/x86_64/scfi-diag-2.s
new file mode 100644
index 00000000000..f58915d0a72
--- /dev/null
+++ b/gas/testsuite/gas/scfi/x86_64/scfi-diag-2.s
@@ -0,0 +1,28 @@ 
+# Testcase for a diagnostic around assymetrical restore
+.type	foo, @function
+foo:
+.LFB10:
+	.cfi_startproc
+	endbr64
+	pushq	%rbp
+	.cfi_def_cfa_offset 16
+	.cfi_offset 6, -16
+	movq	%rsp, %rbp
+	.cfi_def_cfa_register 6
+	pushq	%r12
+	pushq	%rbx
+	subq	$24, %rsp
+	.cfi_offset 12, -24
+	.cfi_offset 3, -32
+	addq	$24, %rsp
+# Note that the order of r12 and rbx restore does not match
+# order of the corresponding save(s).
+# The SCFI machinery warns the user.
+	popq	%r12
+	popq	%rbx
+	popq	%rbp
+	.cfi_def_cfa 7, 8
+	ret
+	.cfi_endproc
+.LFE10:
+	.size	foo, .-foo
diff --git a/gas/testsuite/gas/scfi/x86_64/scfi-dyn-stack-1.d b/gas/testsuite/gas/scfi/x86_64/scfi-dyn-stack-1.d
new file mode 100644
index 00000000000..935deace54f
--- /dev/null
+++ b/gas/testsuite/gas/scfi/x86_64/scfi-dyn-stack-1.d
@@ -0,0 +1,23 @@ 
+#as: --scfi --gsframe -W
+#objdump: --sframe
+#name: SCFI for dynamic alloc stack
+#...
+
+Contents of the SFrame section .sframe:
+  Header :
+
+    Version: SFRAME_VERSION_2
+    Flags: NONE
+    Num FDEs: 1
+    Num FREs: 4
+
+  Function Index :
+
+    func idx \[0\]: pc = 0x0, size = 87 bytes
+    STARTPC + CFA + FP + RA           
+    0+0000 + sp\+8 + u + u            
+    0+0001 + sp\+16 + c-16 + u            
+    0+0004 + fp\+16 + c-16 + u            
+    0+0056 + sp\+8 + u + u            
+
+#pass
diff --git a/gas/testsuite/gas/scfi/x86_64/scfi-dyn-stack-1.l b/gas/testsuite/gas/scfi/x86_64/scfi-dyn-stack-1.l
new file mode 100644
index 00000000000..ce97dd14432
--- /dev/null
+++ b/gas/testsuite/gas/scfi/x86_64/scfi-dyn-stack-1.l
@@ -0,0 +1,2 @@ 
+.*Assembler messages:
+.*5: Warning: --scfi=all ignores some user-specified CFI directives
diff --git a/gas/testsuite/gas/scfi/x86_64/scfi-dyn-stack-1.s b/gas/testsuite/gas/scfi/x86_64/scfi-dyn-stack-1.s
new file mode 100644
index 00000000000..12f1cd78994
--- /dev/null
+++ b/gas/testsuite/gas/scfi/x86_64/scfi-dyn-stack-1.s
@@ -0,0 +1,50 @@ 
+	.text
+	.globl	foo
+	.type	foo, @function
+foo:
+	.cfi_startproc
+	pushq	%rbp
+	.cfi_def_cfa_offset 16
+	.cfi_offset 6, -16
+	movq	%rsp, %rbp
+	.cfi_def_cfa_register 6
+	pushq	%r13
+	pushq	%r12
+	pushq	%rbx
+	subq	$8, %rsp
+	.cfi_offset 13, -24
+	.cfi_offset 12, -32
+	.cfi_offset 3, -40
+	call	read_user
+	testl	%eax, %eax
+	jle	.L2
+	cltq
+	xorl	%ebx, %ebx
+	leaq	0(,%rax,4), %r13
+	.p2align 4,,10
+	.p2align 3
+.L3:
+	leaq	15(%rbx), %rax
+	movq	%rsp, %r12
+	addq	$4, %rbx
+	andq	$-16, %rax
+	subq	%rax, %rsp
+	movq	%rsp, %rdi
+	call	foo
+	movq	%r12, %rsp
+	cmpq	%r13, %rbx
+	jne	.L3
+.L2:
+	leaq	-24(%rbp), %rsp
+	xorl	%eax, %eax
+	popq	%rbx
+	popq	%r12
+	popq	%r13
+	popq	%rbp
+	.cfi_restore 6
+	.cfi_def_cfa_register 7
+	.cfi_def_cfa_offset 8
+	ret
+	.cfi_endproc
+.LFE0:
+	.size	foo, .-foo
diff --git a/gas/testsuite/gas/scfi/x86_64/scfi-fp-diag-2.l b/gas/testsuite/gas/scfi/x86_64/scfi-fp-diag-2.l
new file mode 100644
index 00000000000..734666af914
--- /dev/null
+++ b/gas/testsuite/gas/scfi/x86_64/scfi-fp-diag-2.l
@@ -0,0 +1,3 @@ 
+.*Assembler messages:
+.*7: Warning: --scfi=all ignores some user-specified CFI directives
+.*28: Warning: SCFI: asymetrical register restore
diff --git a/gas/testsuite/gas/scfi/x86_64/scfi-fp-diag-2.s b/gas/testsuite/gas/scfi/x86_64/scfi-fp-diag-2.s
new file mode 100644
index 00000000000..fd46fe3f65c
--- /dev/null
+++ b/gas/testsuite/gas/scfi/x86_64/scfi-fp-diag-2.s
@@ -0,0 +1,55 @@ 
+# Testcase for a diagnostic around assymetrical restore
+# Testcase inspired by byte_insert_op1 in libiberty
+# False positive for the diagnostic
+.type	foo, @function
+foo:
+.LFB10:
+	.cfi_startproc
+	endbr64
+	pushq	%rbp
+	.cfi_def_cfa_offset 16
+	.cfi_offset 6, -16
+	movq	%rsp, %rbp
+	.cfi_def_cfa_register 6
+	pushq	%r12
+	pushq	%rbx
+	subq	$24, %rsp
+	.cfi_offset 12, -24
+	.cfi_offset 3, -32
+	movl	%edi, -20(%rbp)
+	movq	%rsi, -32(%rbp)
+	movl	%edx, -24(%rbp)
+	movq	%rcx, -40(%rbp)
+# The assembler cannot differentiate that the following
+# mov to %rbx is not a true restore operation, but simply
+# %rbx register usage as a scratch reg of some sort.
+# The assembler merely warns of a possible assymetric restore operation
+# In this case, its noise for the user unfortunately.
+	movq	-40(%rbp), %rbx
+	movq	-40(%rbp), %rax
+	leaq	3(%rax), %r12
+	jmp	.L563
+.L564:
+	subq	$1, %rbx
+	subq	$1, %r12
+	movzbl	(%rbx), %eax
+	movb	%al, (%r12)
+.L563:
+	cmpq	-32(%rbp), %rbx
+	jne	.L564
+	movl	-24(%rbp), %edx
+	movq	-32(%rbp), %rcx
+	movl	-20(%rbp), %eax
+	movq	%rcx, %rsi
+	movl	%eax, %edi
+	call	byte_store_op1
+	nop
+	addq	$24, %rsp
+	popq	%rbx
+	popq	%r12
+	popq	%rbp
+	.cfi_def_cfa 7, 8
+	ret
+	.cfi_endproc
+.LFE10:
+	.size	foo, .-foo
diff --git a/gas/testsuite/gas/scfi/x86_64/scfi-ignore-1.d b/gas/testsuite/gas/scfi/x86_64/scfi-ignore-1.d
new file mode 100644
index 00000000000..1cf5919add6
--- /dev/null
+++ b/gas/testsuite/gas/scfi/x86_64/scfi-ignore-1.d
@@ -0,0 +1,26 @@ 
+#as: --scfi -W
+#objdump: -Wf
+#name: Ignore user specified CFI directives
+#...
+Contents of the .eh_frame section:
+
+00000000 0+0014 0+0000 CIE
+  Version:               1
+  Augmentation:          "zR"
+  Code alignment factor: 1
+  Data alignment factor: -8
+  Return address column: 16
+  Augmentation data:     [01][abc]
+  DW_CFA_def_cfa: r7 \(rsp\) ofs 8
+  DW_CFA_offset: r16 \(rip\) at cfa-8
+  DW_CFA_nop
+  DW_CFA_nop
+
+0+0018 0+0014 0+001c FDE cie=0+0000 pc=0+0000..0+0002
+  DW_CFA_advance_loc: 1 to 0+0001
+  DW_CFA_def_cfa_offset: 16
+  DW_CFA_offset: r6 \(rbp\) at cfa-16
+  DW_CFA_nop
+  DW_CFA_nop
+
+#pass
diff --git a/gas/testsuite/gas/scfi/x86_64/scfi-ignore-1.l b/gas/testsuite/gas/scfi/x86_64/scfi-ignore-1.l
new file mode 100644
index 00000000000..ce97dd14432
--- /dev/null
+++ b/gas/testsuite/gas/scfi/x86_64/scfi-ignore-1.l
@@ -0,0 +1,2 @@ 
+.*Assembler messages:
+.*5: Warning: --scfi=all ignores some user-specified CFI directives
diff --git a/gas/testsuite/gas/scfi/x86_64/scfi-ignore-1.s b/gas/testsuite/gas/scfi/x86_64/scfi-ignore-1.s
new file mode 100644
index 00000000000..68b731c58ba
--- /dev/null
+++ b/gas/testsuite/gas/scfi/x86_64/scfi-ignore-1.s
@@ -0,0 +1,13 @@ 
+	.text
+	.globl	foo
+	.type	foo, @function
+foo:
+	.cfi_startproc
+	pushq	%rbp
+        .cfi_def_cfa_offset 16
+        .cfi_offset 6, -16
+	ret
+	.cfi_endproc
+.LFE0:
+	.size	foo, .-foo
+
diff --git a/gas/testsuite/gas/scfi/x86_64/scfi-indirect-mov-1.d b/gas/testsuite/gas/scfi/x86_64/scfi-indirect-mov-1.d
new file mode 100644
index 00000000000..4f4436506f6
--- /dev/null
+++ b/gas/testsuite/gas/scfi/x86_64/scfi-indirect-mov-1.d
@@ -0,0 +1,51 @@ 
+#as: --scfi -W
+#objdump: -Wf
+#name: Synthesize CFI for indirect mem op to stack 1
+#...
+Contents of the .eh_frame section:
+
+00000000 0+0014 0+0000 CIE
+  Version:               1
+  Augmentation:          "zR"
+  Code alignment factor: 1
+  Data alignment factor: -8
+  Return address column: 16
+  Augmentation data:     [01][abc]
+  DW_CFA_def_cfa: r7 \(rsp\) ofs 8
+  DW_CFA_offset: r16 \(rip\) at cfa-8
+  DW_CFA_nop
+  DW_CFA_nop
+
+0+0018 0+0034 0+001c FDE cie=00000000 pc=0+0000..0+005b
+  DW_CFA_advance_loc: 4 to 0+0004
+  DW_CFA_def_cfa_offset: 64
+  DW_CFA_advance_loc: 4 to 0+0008
+  DW_CFA_offset: r3 \(rbx\) at cfa-64
+  DW_CFA_advance_loc: 5 to 0+000d
+  DW_CFA_offset: r6 \(rbp\) at cfa-56
+  DW_CFA_advance_loc: 5 to 0+0012
+  DW_CFA_offset: r12 \(r12\) at cfa-48
+  DW_CFA_advance_loc: 5 to 0+0017
+  DW_CFA_offset: r13 \(r13\) at cfa-40
+  DW_CFA_advance_loc: 5 to 0+001c
+  DW_CFA_offset: r14 \(r14\) at cfa-32
+  DW_CFA_advance_loc: 5 to 0+0021
+  DW_CFA_offset: r15 \(r15\) at cfa-24
+  DW_CFA_advance_loc: 29 to 0+003e
+  DW_CFA_restore: r15 \(r15\)
+  DW_CFA_advance_loc: 5 to 0+0043
+  DW_CFA_restore: r14 \(r14\)
+  DW_CFA_advance_loc: 5 to 0+0048
+  DW_CFA_restore: r13 \(r13\)
+  DW_CFA_advance_loc: 5 to 0+004d
+  DW_CFA_restore: r12 \(r12\)
+  DW_CFA_advance_loc: 5 to 0+0052
+  DW_CFA_restore: r6 \(rbp\)
+  DW_CFA_advance_loc: 4 to 0+0056
+  DW_CFA_restore: r3 \(rbx\)
+  DW_CFA_advance_loc: 4 to 0+005a
+  DW_CFA_def_cfa_offset: 8
+  DW_CFA_nop
+#...
+
+#pass
diff --git a/gas/testsuite/gas/scfi/x86_64/scfi-indirect-mov-1.l b/gas/testsuite/gas/scfi/x86_64/scfi-indirect-mov-1.l
new file mode 100644
index 00000000000..229fb4e7035
--- /dev/null
+++ b/gas/testsuite/gas/scfi/x86_64/scfi-indirect-mov-1.l
@@ -0,0 +1,2 @@ 
+.*Assembler messages:
+.*4: Warning: --scfi=all ignores some user-specified CFI directives
diff --git a/gas/testsuite/gas/scfi/x86_64/scfi-indirect-mov-1.s b/gas/testsuite/gas/scfi/x86_64/scfi-indirect-mov-1.s
new file mode 100644
index 00000000000..e3b5ab30ff1
--- /dev/null
+++ b/gas/testsuite/gas/scfi/x86_64/scfi-indirect-mov-1.s
@@ -0,0 +1,48 @@ 
+# An example of static stack allocation by hand
+	.type foo, @function
+foo:
+	.cfi_startproc
+	/* Allocate space for 7 registers.  */
+	subq	$56,%rsp
+	.cfi_adjust_cfa_offset 56
+	movq	%rbx,(%rsp)
+	.cfi_rel_offset 3, 0
+	movq	%rbp,8(%rsp)
+	.cfi_rel_offset 6, 8
+	movq	%r12,16(%rsp)
+	.cfi_rel_offset 12, 16
+	movq	%r13,24(%rsp)
+	.cfi_rel_offset 13, 24
+	movq	%r14,32(%rsp)
+	.cfi_rel_offset 14, 32
+	movq	%r15,40(%rsp)
+	.cfi_rel_offset 15, 40
+	movq	%r9,48(%rsp)
+
+	/* Setup parameter for __foo_internal.  */
+	/* selfpc is the return address on the stack.  */
+	movq	56(%rsp),%rsi
+	/* Get frompc via the frame pointer.  */
+	movq	8(%rbp),%rdi
+	call __foo_internal
+	/* Pop the saved registers.  Please note that `foo' has no
+	   return value.  */
+	movq	48(%rsp),%r9
+
+	movq	40(%rsp),%r15
+	.cfi_restore 15
+	movq	32(%rsp),%r14
+	.cfi_restore 14
+	movq	24(%rsp),%r13
+	.cfi_restore 13
+	movq	16(%rsp),%r12
+	.cfi_restore 12
+	movq	8(%rsp),%rbp
+	.cfi_restore 6
+	movq	(%rsp),%rbx
+	.cfi_restore 3
+	addq	$56,%rsp
+	.cfi_adjust_cfa_offset -56
+	ret
+	.cfi_endproc
+	.size foo, .-foo
diff --git a/gas/testsuite/gas/scfi/x86_64/scfi-indirect-mov-2.d b/gas/testsuite/gas/scfi/x86_64/scfi-indirect-mov-2.d
new file mode 100644
index 00000000000..3caa66547f6
--- /dev/null
+++ b/gas/testsuite/gas/scfi/x86_64/scfi-indirect-mov-2.d
@@ -0,0 +1,41 @@ 
+#as: --scfi -W
+#objdump: -Wf
+#name: Synthesize CFI for indirect mem op to stack 2
+#...
+Contents of the .eh_frame section:
+
+00000000 0+0014 0+0000 CIE
+  Version:               1
+  Augmentation:          "zR"
+  Code alignment factor: 1
+  Data alignment factor: -8
+  Return address column: 16
+  Augmentation data:     [01][abc]
+  DW_CFA_def_cfa: r7 \(rsp\) ofs 8
+  DW_CFA_offset: r16 \(rip\) at cfa-8
+  DW_CFA_nop
+  DW_CFA_nop
+
+0+0018 0+002c 0+001c FDE cie=00000000 pc=0+0000..0+0026
+  DW_CFA_advance_loc: 1 to 0+0001
+  DW_CFA_def_cfa_offset: 16
+  DW_CFA_offset: r6 \(rbp\) at cfa-16
+  DW_CFA_advance_loc: 3 to 0+0004
+  DW_CFA_def_cfa_register: r6 \(rbp\)
+  DW_CFA_advance_loc: 8 to 0+000c
+  DW_CFA_offset: r3 \(rbx\) at cfa-32
+  DW_CFA_advance_loc: 4 to 0+0010
+  DW_CFA_offset: r12 \(r12\) at cfa-24
+  DW_CFA_advance_loc: 9 to 0+0019
+  DW_CFA_restore: r3 \(rbx\)
+  DW_CFA_advance_loc: 4 to 0+001d
+  DW_CFA_restore: r12 \(r12\)
+  DW_CFA_advance_loc: 7 to 0+0024
+  DW_CFA_def_cfa_register: r7 \(rsp\)
+  DW_CFA_advance_loc: 1 to 0+0025
+  DW_CFA_restore: r6 \(rbp\)
+  DW_CFA_def_cfa_offset: 8
+  DW_CFA_nop
+#...
+
+#pass
diff --git a/gas/testsuite/gas/scfi/x86_64/scfi-indirect-mov-2.l b/gas/testsuite/gas/scfi/x86_64/scfi-indirect-mov-2.l
new file mode 100644
index 00000000000..0e094077edd
--- /dev/null
+++ b/gas/testsuite/gas/scfi/x86_64/scfi-indirect-mov-2.l
@@ -0,0 +1,2 @@ 
+.*Assembler messages:
+.*6: Warning: --scfi=all ignores some user-specified CFI directives
diff --git a/gas/testsuite/gas/scfi/x86_64/scfi-indirect-mov-2.s b/gas/testsuite/gas/scfi/x86_64/scfi-indirect-mov-2.s
new file mode 100644
index 00000000000..bed2050241c
--- /dev/null
+++ b/gas/testsuite/gas/scfi/x86_64/scfi-indirect-mov-2.s
@@ -0,0 +1,38 @@ 
+# Testcase for movq instructions
+	.text
+	.globl	foo
+	.type	foo, @function
+foo:
+	.cfi_startproc
+	pushq	%rbp
+	.cfi_def_cfa_offset 16
+	.cfi_offset 6, -16
+	movq    %rsp, %rbp
+	.cfi_def_cfa_register 6
+
+	subq	$16,%rsp
+
+# store rbx at %rsp; rsp = rbp - 16;
+	movq	%rbx, -16(%rbp)
+	.cfi_rel_offset 3, -16
+# store r12 at %rsp + 8; rsp = rbp -16;
+	movq	%r12, -8(%rbp)
+	.cfi_rel_offset 12, -8
+
+	call bar
+
+	movq	-16(%rbp), %rbx
+	.cfi_restore 3
+	movq	-8(%rbp), %r12
+	.cfi_restore 12
+
+	addq	$16,%rsp
+
+	mov	%rbp, %rsp
+	.cfi_def_cfa_register 7
+	pop	%rbp
+	.cfi_restore 6
+	.cfi_def_cfa_offset 8
+	ret
+	.cfi_endproc
+	.size	foo, .-foo
diff --git a/gas/testsuite/gas/scfi/x86_64/scfi-indirect-mov-3.d b/gas/testsuite/gas/scfi/x86_64/scfi-indirect-mov-3.d
new file mode 100644
index 00000000000..8070e220b7a
--- /dev/null
+++ b/gas/testsuite/gas/scfi/x86_64/scfi-indirect-mov-3.d
@@ -0,0 +1,41 @@ 
+#as: --scfi -W
+#objdump: -Wf
+#name: Synthesize CFI for indirect mem op to stack 3
+#...
+Contents of the .eh_frame section:
+
+00000000 0+0014 0+0000 CIE
+  Version:               1
+  Augmentation:          "zR"
+  Code alignment factor: 1
+  Data alignment factor: -8
+  Return address column: 16
+  Augmentation data:     [01][abc]
+  DW_CFA_def_cfa: r7 \(rsp\) ofs 8
+  DW_CFA_offset: r16 \(rip\) at cfa-8
+  DW_CFA_nop
+  DW_CFA_nop
+
+0+0018 0+002c 0+001c FDE cie=00000000 pc=0+0000..0+0028
+  DW_CFA_advance_loc: 1 to 0+0001
+  DW_CFA_def_cfa_offset: 16
+  DW_CFA_offset: r6 \(rbp\) at cfa-16
+  DW_CFA_advance_loc: 3 to 0+0004
+  DW_CFA_def_cfa_register: r6 \(rbp\)
+  DW_CFA_advance_loc: 8 to 0+000c
+  DW_CFA_offset: r3 \(rbx\) at cfa-32
+  DW_CFA_advance_loc: 5 to 0+0011
+  DW_CFA_offset: r12 \(r12\) at cfa-24
+  DW_CFA_advance_loc: 9 to 0+001a
+  DW_CFA_restore: r3 \(rbx\)
+  DW_CFA_advance_loc: 5 to 0+001f
+  DW_CFA_restore: r12 \(r12\)
+  DW_CFA_advance_loc: 7 to 0+0026
+  DW_CFA_def_cfa_register: r7 \(rsp\)
+  DW_CFA_advance_loc: 1 to 0+0027
+  DW_CFA_restore: r6 \(rbp\)
+  DW_CFA_def_cfa_offset: 8
+  DW_CFA_nop
+#...
+
+#pass
diff --git a/gas/testsuite/gas/scfi/x86_64/scfi-indirect-mov-3.l b/gas/testsuite/gas/scfi/x86_64/scfi-indirect-mov-3.l
new file mode 100644
index 00000000000..0e094077edd
--- /dev/null
+++ b/gas/testsuite/gas/scfi/x86_64/scfi-indirect-mov-3.l
@@ -0,0 +1,2 @@ 
+.*Assembler messages:
+.*6: Warning: --scfi=all ignores some user-specified CFI directives
diff --git a/gas/testsuite/gas/scfi/x86_64/scfi-indirect-mov-3.s b/gas/testsuite/gas/scfi/x86_64/scfi-indirect-mov-3.s
new file mode 100644
index 00000000000..0eb90bc34e3
--- /dev/null
+++ b/gas/testsuite/gas/scfi/x86_64/scfi-indirect-mov-3.s
@@ -0,0 +1,38 @@ 
+# Testcase for movq instructions
+	.text
+	.globl	foo
+	.type	foo, @function
+foo:
+	.cfi_startproc
+	pushq	%rbp
+	.cfi_def_cfa_offset 16
+	.cfi_offset 6, -16
+	movq    %rsp, %rbp
+	.cfi_def_cfa_register 6
+
+	subq	$16,%rsp
+
+# store rbx at %rsp; rsp = rbp - 16; rsp = CFA - 32
+	movq	%rbx, (%rsp)
+	.cfi_rel_offset 3, -16
+# store r12 at %rsp + 8; rsp = CFA - 32
+	movq	%r12, 8(%rsp)
+	.cfi_rel_offset 12, -8
+
+	call bar
+
+	movq	(%rsp), %rbx
+	.cfi_restore 3
+	movq	8(%rsp), %r12
+	.cfi_restore 12
+
+	addq	$16,%rsp
+
+	mov	%rbp, %rsp
+	.cfi_def_cfa_register 7
+	pop	%rbp
+	.cfi_restore 6
+	.cfi_def_cfa_offset 8
+	ret
+	.cfi_endproc
+	.size	foo, .-foo
diff --git a/gas/testsuite/gas/scfi/x86_64/scfi-indirect-mov-4.d b/gas/testsuite/gas/scfi/x86_64/scfi-indirect-mov-4.d
new file mode 100644
index 00000000000..dbb16d7d05e
--- /dev/null
+++ b/gas/testsuite/gas/scfi/x86_64/scfi-indirect-mov-4.d
@@ -0,0 +1,63 @@ 
+#as: --scfi -W
+#objdump: -Wf
+#name: Synthesize CFI for indirect mem op to stack 3
+#...
+Contents of the .eh_frame section:
+
+00000000 0+0014 0+0000 CIE
+  Version:               1
+  Augmentation:          "zR"
+  Code alignment factor: 1
+  Data alignment factor: -8
+  Return address column: 16
+  Augmentation data:     [01][abc]
+  DW_CFA_def_cfa: r7 \(rsp\) ofs 8
+  DW_CFA_offset: r16 \(rip\) at cfa-8
+  DW_CFA_nop
+  DW_CFA_nop
+
+00000018 0+004c 0000001c FDE cie=00000000 pc=0+0000..0+003d
+  DW_CFA_advance_loc: 2 to 0+0002
+  DW_CFA_def_cfa_offset: 16
+  DW_CFA_offset: r15 \(r15\) at cfa-16
+  DW_CFA_advance_loc: 2 to 0+0004
+  DW_CFA_def_cfa_offset: 24
+  DW_CFA_offset: r14 \(r14\) at cfa-24
+  DW_CFA_advance_loc: 5 to 0+0009
+  DW_CFA_def_cfa_offset: 32
+  DW_CFA_offset: r13 \(r13\) at cfa-32
+  DW_CFA_advance_loc: 5 to 0+000e
+  DW_CFA_def_cfa_offset: 40
+  DW_CFA_offset: r12 \(r12\) at cfa-40
+  DW_CFA_advance_loc: 4 to 0+0012
+  DW_CFA_def_cfa_offset: 48
+  DW_CFA_offset: r6 \(rbp\) at cfa-48
+  DW_CFA_advance_loc: 4 to 0+0016
+  DW_CFA_def_cfa_offset: 56
+  DW_CFA_offset: r3 \(rbx\) at cfa-56
+  DW_CFA_advance_loc: 7 to 0+001d
+  DW_CFA_def_cfa_offset: 96
+  DW_CFA_advance_loc: 21 to 0+0032
+  DW_CFA_def_cfa_offset: 56
+  DW_CFA_advance_loc: 1 to 0+0033
+  DW_CFA_restore: r3 \(rbx\)
+  DW_CFA_def_cfa_offset: 48
+  DW_CFA_advance_loc: 1 to 0+0034
+  DW_CFA_restore: r6 \(rbp\)
+  DW_CFA_def_cfa_offset: 40
+  DW_CFA_advance_loc: 2 to 0+0036
+  DW_CFA_restore: r12 \(r12\)
+  DW_CFA_def_cfa_offset: 32
+  DW_CFA_advance_loc: 2 to 0+0038
+  DW_CFA_restore: r13 \(r13\)
+  DW_CFA_def_cfa_offset: 24
+  DW_CFA_advance_loc: 2 to 0+003a
+  DW_CFA_restore: r14 \(r14\)
+  DW_CFA_def_cfa_offset: 16
+  DW_CFA_advance_loc: 2 to 0+003c
+  DW_CFA_restore: r15 \(r15\)
+  DW_CFA_def_cfa_offset: 8
+  DW_CFA_nop
+#...
+
+#pass
diff --git a/gas/testsuite/gas/scfi/x86_64/scfi-indirect-mov-4.l b/gas/testsuite/gas/scfi/x86_64/scfi-indirect-mov-4.l
new file mode 100644
index 00000000000..1793f4b4799
--- /dev/null
+++ b/gas/testsuite/gas/scfi/x86_64/scfi-indirect-mov-4.l
@@ -0,0 +1,3 @@ 
+.*Assembler messages:
+.*7: Warning: --scfi=all ignores some user-specified CFI directives
+.*41: Warning: SCFI: asymetrical register restore
diff --git a/gas/testsuite/gas/scfi/x86_64/scfi-indirect-mov-4.s b/gas/testsuite/gas/scfi/x86_64/scfi-indirect-mov-4.s
new file mode 100644
index 00000000000..ae0c0fde16c
--- /dev/null
+++ b/gas/testsuite/gas/scfi/x86_64/scfi-indirect-mov-4.s
@@ -0,0 +1,68 @@ 
+# Testcase for save/unsave of callee-saved registers
+# Must be run -W as there is an expected warning as
+# noted below
+	.type	foo, @function
+foo:
+.LFB118:
+	.cfi_startproc
+	pushq	%r15
+	.cfi_def_cfa_offset 16
+	.cfi_offset 15, -16
+	pushq	%r14
+	.cfi_def_cfa_offset 24
+	.cfi_offset 14, -24
+	movl	%r8d, %r14d
+	pushq	%r13
+	.cfi_def_cfa_offset 32
+	.cfi_offset 13, -32
+	movq	%rdi, %r13
+	pushq	%r12
+	.cfi_def_cfa_offset 40
+	.cfi_offset 12, -40
+	movq	%rsi, %r12
+	pushq	%rbp
+	.cfi_def_cfa_offset 48
+	.cfi_offset 6, -48
+	movq	%rcx, %rbp
+	pushq	%rbx
+	.cfi_def_cfa_offset 56
+	.cfi_offset 3, -56
+	movq	%rdx, %rbx
+	subq	$40, %rsp
+	.cfi_def_cfa_offset 96
+	testb	$1, 37(%rdx)
+	je	.L2
+.L3:
+# The following is not a restore of r15: rbp has been used as
+# scratch register already.  The SCFI machinery must know that
+# REG_FP is not traceable.
+# A warning here is expected:
+# 41: Warning: SCFI: asymetrical register restore
+	movq	32(%rbp), %r15
+	cmpq	$0, 64(%r15)
+	je	.L2
+.L2:
+	addq	$40, %rsp
+	.cfi_def_cfa_offset 56
+	popq	%rbx
+	.cfi_restore 3
+	.cfi_def_cfa_offset 48
+	popq	%rbp
+	.cfi_restore 6
+	.cfi_def_cfa_offset 40
+	popq	%r12
+	.cfi_restore 12
+	.cfi_def_cfa_offset 32
+	popq	%r13
+	.cfi_restore 13
+	.cfi_def_cfa_offset 24
+	popq	%r14
+	.cfi_restore 14
+	.cfi_def_cfa_offset 16
+	popq	%r15
+	.cfi_restore 15
+	.cfi_def_cfa_offset 8
+	ret
+	.cfi_endproc
+.LFE118:
+	.size	foo, .-foo
diff --git a/gas/testsuite/gas/scfi/x86_64/scfi-lea-1.d b/gas/testsuite/gas/scfi/x86_64/scfi-lea-1.d
new file mode 100644
index 00000000000..d2fa442df63
--- /dev/null
+++ b/gas/testsuite/gas/scfi/x86_64/scfi-lea-1.d
@@ -0,0 +1,37 @@ 
+#as: --scfi -W -O2
+#objdump: -Wf
+#name: Synthesize CFI for various lea instructions (-O2)
+#...
+Contents of the .eh_frame section:
+
+00000000 0+0014 0+0000 CIE
+  Version:               1
+  Augmentation:          "zR"
+  Code alignment factor: 1
+  Data alignment factor: -8
+  Return address column: 16
+  Augmentation data:     [01][abc]
+  DW_CFA_def_cfa: r7 \(rsp\) ofs 8
+  DW_CFA_offset: r16 \(rip\) at cfa-8
+  DW_CFA_nop
+  DW_CFA_nop
+
+0+0018 0+0024 0+001c FDE cie=00000000 pc=0+0000..0+0029
+  DW_CFA_advance_loc: 1 to 0+0001
+  DW_CFA_def_cfa_offset: 16
+  DW_CFA_offset: r6 \(rbp\) at cfa-16
+  DW_CFA_advance_loc: 3 to 0+0004
+  DW_CFA_def_cfa_register: r6 \(rbp\)
+  DW_CFA_advance_loc: 2 to 0+0006
+  DW_CFA_offset: r13 \(r13\) at cfa-24
+  DW_CFA_advance_loc: 33 to 0+0027
+  DW_CFA_restore: r13 \(r13\)
+  DW_CFA_advance_loc: 1 to 0+0028
+  DW_CFA_def_cfa_register: r7 \(rsp\)
+  DW_CFA_restore: r6 \(rbp\)
+  DW_CFA_def_cfa_offset: 8
+  DW_CFA_nop
+  DW_CFA_nop
+#...
+
+#pass
diff --git a/gas/testsuite/gas/scfi/x86_64/scfi-lea-1.l b/gas/testsuite/gas/scfi/x86_64/scfi-lea-1.l
new file mode 100644
index 00000000000..2762adba5b1
--- /dev/null
+++ b/gas/testsuite/gas/scfi/x86_64/scfi-lea-1.l
@@ -0,0 +1,2 @@ 
+.*Assembler messages:
+.*8: Warning: --scfi=all ignores some user-specified CFI directives
diff --git a/gas/testsuite/gas/scfi/x86_64/scfi-lea-1.s b/gas/testsuite/gas/scfi/x86_64/scfi-lea-1.s
new file mode 100644
index 00000000000..8fb8fe794d6
--- /dev/null
+++ b/gas/testsuite/gas/scfi/x86_64/scfi-lea-1.s
@@ -0,0 +1,40 @@ 
+## Testcase with a variety of lea.
+## This test is run with -O2 by default to check
+## SCFI in wake of certain target optimizations.
+	.text
+	.globl	foo
+	.type	foo, @function
+foo:
+	.cfi_startproc
+	pushq   %rbp
+	.cfi_def_cfa_offset 16
+	.cfi_offset 6, -16
+# This lea gets transformed to mov %rsp, %rbp when -O2.
+# The SCFI machinery must see it as such.
+        lea    (%rsp), %rbp
+	.cfi_def_cfa_register 6
+	push   %r13
+	.cfi_offset 13, -24
+	subq   $8, %rsp
+	testl  %eax, %eax
+	jle   .L2
+.L3:
+	movq   %rsp, %r12
+        lea    -0x2(%r13),%rax
+        lea    0x8(%r12,%rdx,4),%r8
+	movq   %r12, %rsp
+	jne   .L3
+.L2:
+	leaq	-8(%rbp), %rsp
+	xorl	%eax, %eax
+	popq	%r13
+	.cfi_restore 13
+	popq	%rbp
+	.cfi_def_cfa_register 7
+	.cfi_restore 6
+	.cfi_def_cfa_offset 8
+	ret
+	.cfi_endproc
+.LFE0:
+	.size	foo, .-foo
+
diff --git a/gas/testsuite/gas/scfi/x86_64/scfi-leave-1.d b/gas/testsuite/gas/scfi/x86_64/scfi-leave-1.d
new file mode 100644
index 00000000000..0d9e5943a30
--- /dev/null
+++ b/gas/testsuite/gas/scfi/x86_64/scfi-leave-1.d
@@ -0,0 +1,36 @@ 
+#as: --scfi -W
+#objdump: -Wf
+#name: Synthesize CFI for leave insn
+#...
+Contents of the .eh_frame section:
+
+00000000 0+0014 0+0000 CIE
+  Version:               1
+  Augmentation:          "zR"
+  Code alignment factor: 1
+  Data alignment factor: -8
+  Return address column: 16
+  Augmentation data:     [01][abc]
+  DW_CFA_def_cfa: r7 \(rsp\) ofs 8
+  DW_CFA_offset: r16 \(rip\) at cfa-8
+  DW_CFA_nop
+  DW_CFA_nop
+
+0+0018 0+0024 0+001c FDE cie=0+0000 pc=0+0000..0+000a
+  DW_CFA_advance_loc: 1 to 0+0001
+  DW_CFA_def_cfa_offset: 16
+  DW_CFA_offset: r6 \(rbp\) at cfa-16
+  DW_CFA_advance_loc: 3 to 0+0004
+  DW_CFA_def_cfa_register: r6 \(rbp\)
+  DW_CFA_advance_loc: 1 to 0+0005
+  DW_CFA_offset: r3 \(rbx\) at cfa-24
+  DW_CFA_advance_loc: 3 to 0+0008
+  DW_CFA_restore: r3 \(rbx\)
+  DW_CFA_advance_loc: 1 to 0+0009
+  DW_CFA_def_cfa_register: r7 \(rsp\)
+  DW_CFA_restore: r6 \(rbp\)
+  DW_CFA_def_cfa_offset: 8
+  DW_CFA_nop
+#...
+
+#pass
diff --git a/gas/testsuite/gas/scfi/x86_64/scfi-leave-1.l b/gas/testsuite/gas/scfi/x86_64/scfi-leave-1.l
new file mode 100644
index 00000000000..0e094077edd
--- /dev/null
+++ b/gas/testsuite/gas/scfi/x86_64/scfi-leave-1.l
@@ -0,0 +1,2 @@ 
+.*Assembler messages:
+.*6: Warning: --scfi=all ignores some user-specified CFI directives
diff --git a/gas/testsuite/gas/scfi/x86_64/scfi-leave-1.s b/gas/testsuite/gas/scfi/x86_64/scfi-leave-1.s
new file mode 100644
index 00000000000..0466ab15708
--- /dev/null
+++ b/gas/testsuite/gas/scfi/x86_64/scfi-leave-1.s
@@ -0,0 +1,26 @@ 
+# Testcase for leave insn
+	.text
+	.globl	foo
+	.type	foo, @function
+foo:
+	.cfi_startproc
+	pushq	%rbp
+	.cfi_def_cfa_offset 16
+	.cfi_offset 6, -16
+	movq    %rsp, %rbp
+	.cfi_def_cfa_register 6
+	push    %rbx
+	.cfi_offset 3, -24
+	push    %rdi
+	pop	%rdi
+	pop	%rbx
+	.cfi_restore 3
+	leave
+	.cfi_def_cfa_register 7
+	.cfi_restore 6
+	.cfi_def_cfa_offset 8
+	ret
+	.cfi_endproc
+.LFE0:
+	.size	foo, .-foo
+
diff --git a/gas/testsuite/gas/scfi/x86_64/scfi-pushq-1.d b/gas/testsuite/gas/scfi/x86_64/scfi-pushq-1.d
new file mode 100644
index 00000000000..e37d4a93917
--- /dev/null
+++ b/gas/testsuite/gas/scfi/x86_64/scfi-pushq-1.d
@@ -0,0 +1,35 @@ 
+#as: --scfi -W
+#objdump: -Wf
+#name: Synthesize CFI for pushq insns
+#...
+Contents of the .eh_frame section:
+
+00000000 0+0014 0+0000 CIE
+  Version:               1
+  Augmentation:          "zR"
+  Code alignment factor: 1
+  Data alignment factor: -8
+  Return address column: 16
+  Augmentation data:     [01][abc]
+  DW_CFA_def_cfa: r7 \(rsp\) ofs 8
+  DW_CFA_offset: r16 \(rip\) at cfa-8
+  DW_CFA_nop
+  DW_CFA_nop
+
+0+0018 0+0024 0+001c FDE cie=0+0000 pc=0+0000..0+000c
+  DW_CFA_advance_loc: 1 to 0+0001
+  DW_CFA_def_cfa_offset: 16
+  DW_CFA_advance_loc: 3 to 0+0004
+  DW_CFA_def_cfa_offset: 24
+  DW_CFA_advance_loc: 2 to 0+0006
+  DW_CFA_def_cfa_offset: 32
+  DW_CFA_advance_loc: 2 to 0+0008
+  DW_CFA_def_cfa_offset: 40
+  DW_CFA_advance_loc: 2 to 0+0000a
+  DW_CFA_def_cfa_offset: 48
+  DW_CFA_advance_loc: 1 to 0+0000b
+  DW_CFA_def_cfa_offset: 56
+  DW_CFA_nop
+#...
+
+#pass
diff --git a/gas/testsuite/gas/scfi/x86_64/scfi-pushq-1.l b/gas/testsuite/gas/scfi/x86_64/scfi-pushq-1.l
new file mode 100644
index 00000000000..bba199d24b9
--- /dev/null
+++ b/gas/testsuite/gas/scfi/x86_64/scfi-pushq-1.l
@@ -0,0 +1,2 @@ 
+.*Assembler messages:
+.*7: Warning: --scfi=all ignores some user-specified CFI directives
diff --git a/gas/testsuite/gas/scfi/x86_64/scfi-pushq-1.s b/gas/testsuite/gas/scfi/x86_64/scfi-pushq-1.s
new file mode 100644
index 00000000000..b896a295b56
--- /dev/null
+++ b/gas/testsuite/gas/scfi/x86_64/scfi-pushq-1.s
@@ -0,0 +1,24 @@ 
+## Testcase with a variety of pushq.
+## all push insns valid in 64-bit mode must be processed for SCFI.
+	.text
+	.globl	foo
+	.type	foo, @function
+foo:
+	.cfi_startproc
+	pushq	%rax
+	.cfi_def_cfa_offset 16
+	pushq   16(%rax)
+	.cfi_def_cfa_offset 24
+	pushq	$36
+	.cfi_def_cfa_offset 32
+	pushq   %fs
+	.cfi_def_cfa_offset 40
+	pushq   %gs
+	.cfi_def_cfa_offset 48
+	pushf
+	.cfi_def_cfa_offset 56
+	ret
+	.cfi_endproc
+.LFE0:
+	.size	foo, .-foo
+
diff --git a/gas/testsuite/gas/scfi/x86_64/scfi-pushsection-1.d b/gas/testsuite/gas/scfi/x86_64/scfi-pushsection-1.d
new file mode 100644
index 00000000000..1fd0af4d8ae
--- /dev/null
+++ b/gas/testsuite/gas/scfi/x86_64/scfi-pushsection-1.d
@@ -0,0 +1,43 @@ 
+#as: --scfi -W
+#objdump: -Wf
+#name: Synthesize CFI with pushsection 1
+#...
+Contents of the .eh_frame section:
+
+00000000 0+0014 0+0000 CIE
+  Version:               1
+  Augmentation:          "zR"
+  Code alignment factor: 1
+  Data alignment factor: -8
+  Return address column: 16
+  Augmentation data:     [01][abc]
+  DW_CFA_def_cfa: r7 \(rsp\) ofs 8
+  DW_CFA_offset: r16 \(rip\) at cfa-8
+  DW_CFA_nop
+  DW_CFA_nop
+
+00000018 0+0010 0000001c FDE cie=00000000 pc=0+0000..0+0005
+  DW_CFA_advance_loc: 4 to 0+0004
+  DW_CFA_def_cfa_offset: 48
+
+0000002c 0+0028 00000030 FDE cie=00000000 pc=0+0000..0+0014
+  DW_CFA_advance_loc: 2 to 0+0002
+  DW_CFA_def_cfa_offset: 16
+  DW_CFA_offset: r12 \(r12\) at cfa-16
+  DW_CFA_advance_loc: 2 to 0+0004
+  DW_CFA_def_cfa_offset: 24
+  DW_CFA_offset: r13 \(r13\) at cfa-24
+  DW_CFA_advance_loc: 4 to 0+0008
+  DW_CFA_def_cfa_offset: 32
+  DW_CFA_advance_loc: 7 to 0+000f
+  DW_CFA_def_cfa_offset: 24
+  DW_CFA_advance_loc: 2 to 0+0011
+  DW_CFA_restore: r13 \(r13\)
+  DW_CFA_def_cfa_offset: 16
+  DW_CFA_advance_loc: 2 to 0+0013
+  DW_CFA_restore: r12 \(r12\)
+  DW_CFA_def_cfa_offset: 8
+  DW_CFA_nop
+#...
+
+#pass
diff --git a/gas/testsuite/gas/scfi/x86_64/scfi-pushsection-1.l b/gas/testsuite/gas/scfi/x86_64/scfi-pushsection-1.l
new file mode 100644
index 00000000000..bba199d24b9
--- /dev/null
+++ b/gas/testsuite/gas/scfi/x86_64/scfi-pushsection-1.l
@@ -0,0 +1,2 @@ 
+.*Assembler messages:
+.*7: Warning: --scfi=all ignores some user-specified CFI directives
diff --git a/gas/testsuite/gas/scfi/x86_64/scfi-pushsection-1.s b/gas/testsuite/gas/scfi/x86_64/scfi-pushsection-1.s
new file mode 100644
index 00000000000..4bee003e6f5
--- /dev/null
+++ b/gas/testsuite/gas/scfi/x86_64/scfi-pushsection-1.s
@@ -0,0 +1,40 @@ 
+# Testcase for pushsection directive and SCFI.
+# The .pushsection directive must cause creation of a new FDE.
+        .text
+        .globl  foo
+        .type   foo, @function
+foo:
+        .cfi_startproc
+        pushq   %r12
+        .cfi_def_cfa_offset 16
+        .cfi_offset 12, -16
+        pushq   %r13
+        .cfi_def_cfa_offset 24
+        .cfi_offset 13, -24
+        subq    $8, %rsp
+        .cfi_def_cfa_offset 32
+	mov	%rax, %rbx
+	.pushsection .text2
+# It's the .type directive here that enforces SCFI generation
+# for the code block that follows
+	.type   foo2, @function
+foo2:
+	.cfi_startproc
+	subq    $40, %rsp
+	.cfi_def_cfa_offset 48
+	ret
+	.cfi_endproc
+	.size foo2, .-foo2
+	.popsection
+	addq	$8, %rsp
+	.cfi_def_cfa_offset 24
+        popq    %r13
+        .cfi_restore 13
+        .cfi_def_cfa_offset 16
+        popq    %r12
+        .cfi_restore 12
+        .cfi_def_cfa_offset 8
+        ret
+        .cfi_endproc
+.LFE0:
+        .size   foo, .-foo
diff --git a/gas/testsuite/gas/scfi/x86_64/scfi-pushsection-2.d b/gas/testsuite/gas/scfi/x86_64/scfi-pushsection-2.d
new file mode 100644
index 00000000000..3e6ebc15aa3
--- /dev/null
+++ b/gas/testsuite/gas/scfi/x86_64/scfi-pushsection-2.d
@@ -0,0 +1,39 @@ 
+#as: --scfi -W
+#objdump: -Wf
+#name: Synthesize CFI for demarcated code blocks 2
+#...
+Contents of the .eh_frame section:
+
+00000000 0+0014 0+0000 CIE
+  Version:               1
+  Augmentation:          "zR"
+  Code alignment factor: 1
+  Data alignment factor: -8
+  Return address column: 16
+  Augmentation data:     [01][abc]
+  DW_CFA_def_cfa: r7 \(rsp\) ofs 8
+  DW_CFA_offset: r16 \(rip\) at cfa-8
+  DW_CFA_nop
+  DW_CFA_nop
+
+00000018 0+002c 0000001c FDE cie=00000000 pc=0+0000..0+0014
+  DW_CFA_advance_loc: 2 to 0+0002
+  DW_CFA_def_cfa_offset: 16
+  DW_CFA_offset: r12 \(r12\) at cfa-16
+  DW_CFA_advance_loc: 2 to 0+0004
+  DW_CFA_def_cfa_offset: 24
+  DW_CFA_offset: r13 \(r13\) at cfa-24
+  DW_CFA_advance_loc: 4 to 0+0008
+  DW_CFA_def_cfa_offset: 32
+  DW_CFA_advance_loc: 7 to 0+000f
+  DW_CFA_def_cfa_offset: 24
+  DW_CFA_advance_loc: 2 to 0+0011
+  DW_CFA_restore: r13 \(r13\)
+  DW_CFA_def_cfa_offset: 16
+  DW_CFA_advance_loc: 2 to 0+0013
+  DW_CFA_restore: r12 \(r12\)
+  DW_CFA_def_cfa_offset: 8
+  DW_CFA_nop
+#...
+
+#pass
diff --git a/gas/testsuite/gas/scfi/x86_64/scfi-pushsection-2.l b/gas/testsuite/gas/scfi/x86_64/scfi-pushsection-2.l
new file mode 100644
index 00000000000..0e094077edd
--- /dev/null
+++ b/gas/testsuite/gas/scfi/x86_64/scfi-pushsection-2.l
@@ -0,0 +1,2 @@ 
+.*Assembler messages:
+.*6: Warning: --scfi=all ignores some user-specified CFI directives
diff --git a/gas/testsuite/gas/scfi/x86_64/scfi-pushsection-2.s b/gas/testsuite/gas/scfi/x86_64/scfi-pushsection-2.s
new file mode 100644
index 00000000000..e7b6dbc2526
--- /dev/null
+++ b/gas/testsuite/gas/scfi/x86_64/scfi-pushsection-2.s
@@ -0,0 +1,38 @@ 
+# Testcase for pushsection directive and SCFI.
+        .text
+        .globl  foo
+        .type   foo, @function
+foo:
+        .cfi_startproc
+        pushq   %r12
+        .cfi_def_cfa_offset 16
+        .cfi_offset 12, -16
+        pushq   %r13
+        .cfi_def_cfa_offset 24
+        .cfi_offset 13, -24
+        subq    $8, %rsp
+        .cfi_def_cfa_offset 32
+	mov	%rax, %rbx
+# The .pushsection directive creates a new code block,
+# which must not contribute ginsn to the existing one.
+	.pushsection .text2
+# For CFI to be synthesized for this block, the user should have
+# demarcated the beginning with a .type name, @function
+	.cfi_startproc
+	subq    $40, %rsp
+	.cfi_def_cfa_offset 48
+	ret
+	.cfi_endproc
+	.popsection
+	addq	$8, %rsp
+	.cfi_def_cfa_offset 24
+        popq    %r13
+        .cfi_restore 13
+        .cfi_def_cfa_offset 16
+        popq    %r12
+        .cfi_restore 12
+        .cfi_def_cfa_offset 8
+        ret
+        .cfi_endproc
+.LFE0:
+        .size   foo, .-foo
diff --git a/gas/testsuite/gas/scfi/x86_64/scfi-selfalign-func-1.d b/gas/testsuite/gas/scfi/x86_64/scfi-selfalign-func-1.d
new file mode 100644
index 00000000000..c05c0314c0f
--- /dev/null
+++ b/gas/testsuite/gas/scfi/x86_64/scfi-selfalign-func-1.d
@@ -0,0 +1,31 @@ 
+#as: --scfi -W
+#objdump: -Wf
+#name: Synthesize CFI for self-aligning func
+#...
+Contents of the .eh_frame section:
+
+0+0000 0+0014 0+0000 CIE
+  Version:               1
+  Augmentation:          "zR"
+  Code alignment factor: 1
+  Data alignment factor: -8
+  Return address column: 16
+  Augmentation data:     [01][abc]
+  DW_CFA_def_cfa: r7 \(rsp\) ofs 8
+  DW_CFA_offset: r16 \(rip\) at cfa-8
+  DW_CFA_nop
+  DW_CFA_nop
+
+0+0018 0+001c 0000001c FDE cie=00000000 pc=0+0000..0+002f
+  DW_CFA_advance_loc: 1 to 0+0001
+  DW_CFA_def_cfa_offset: 16
+  DW_CFA_offset: r6 \(rbp\) at cfa-16
+  DW_CFA_advance_loc: 3 to 0+0004
+  DW_CFA_def_cfa_register: r6 \(rbp\)
+  DW_CFA_advance_loc: 42 to 0+002e
+  DW_CFA_def_cfa_register: r7 \(rsp\)
+  DW_CFA_restore: r6 \(rbp\)
+  DW_CFA_def_cfa_offset: 8
+  DW_CFA_nop
+
+#pass
diff --git a/gas/testsuite/gas/scfi/x86_64/scfi-selfalign-func-1.l b/gas/testsuite/gas/scfi/x86_64/scfi-selfalign-func-1.l
new file mode 100644
index 00000000000..bba199d24b9
--- /dev/null
+++ b/gas/testsuite/gas/scfi/x86_64/scfi-selfalign-func-1.l
@@ -0,0 +1,2 @@ 
+.*Assembler messages:
+.*7: Warning: --scfi=all ignores some user-specified CFI directives
diff --git a/gas/testsuite/gas/scfi/x86_64/scfi-selfalign-func-1.s b/gas/testsuite/gas/scfi/x86_64/scfi-selfalign-func-1.s
new file mode 100644
index 00000000000..51a40b5940b
--- /dev/null
+++ b/gas/testsuite/gas/scfi/x86_64/scfi-selfalign-func-1.s
@@ -0,0 +1,36 @@ 
+# If it is known that the caller of self_aligning_foo may have had
+# the stack pointer unaligned to 16-bytes boundary,  such self-aligning
+# functions may be used by asm programmers.
+	.globl  self_aligning_foo
+        .type   self_aligning_foo, @function
+self_aligning_foo:
+        .cfi_startproc
+        pushq   %rbp
+        .cfi_def_cfa_offset 16
+        .cfi_offset 6, -16
+        movq    %rsp, %rbp
+        .cfi_def_cfa_register 6
+# The following 'and' op aligns the stack pointer.
+# At the same time, it causes REG_SP to become non-traceable
+# for SCFI purposes.  But no warning is issued as no further stack
+# size tracking is needed for SCFI purposes.
+        andq    $-16, %rsp
+        subq    $32, %rsp
+        movl    %edi, 12(%rsp)
+        movl    %esi, 8(%rsp)
+        movl    $0, %eax
+        call    vector_using_function
+        movaps  %xmm0, 16(%rsp)
+        movl    12(%rsp), %edx
+        movl    8(%rsp), %eax
+        addl    %edx, %eax
+        leave
+# GCC typically generates a '.cfi_def_cfa 7, 8' for leave
+# insn.  The SCFI however, will generate the following:
+	.cfi_def_cfa_register 7
+	.cfi_restore 6
+	.cfi_def_cfa_offset 8
+        ret
+       .cfi_endproc
+.LFE0:
+        .size   self_aligning_foo, .-self_aligning_foo
diff --git a/gas/testsuite/gas/scfi/x86_64/scfi-simple-1.d b/gas/testsuite/gas/scfi/x86_64/scfi-simple-1.d
new file mode 100644
index 00000000000..849833cb5c8
--- /dev/null
+++ b/gas/testsuite/gas/scfi/x86_64/scfi-simple-1.d
@@ -0,0 +1,26 @@ 
+#as: --scfi -W
+#objdump: -Wf
+#name: Synthesize CFI simple test 1
+#...
+Contents of the .eh_frame section:
+
+00000000 0+0014 0+0000 CIE
+  Version:               1
+  Augmentation:          "zR"
+  Code alignment factor: 1
+  Data alignment factor: -8
+  Return address column: 16
+  Augmentation data:     [01][abc]
+  DW_CFA_def_cfa: r7 \(rsp\) ofs 8
+  DW_CFA_offset: r16 \(rip\) at cfa-8
+  DW_CFA_nop
+  DW_CFA_nop
+
+0+0018 0+0014 0+001c FDE cie=0+0000 pc=0+0000..0+0002
+  DW_CFA_advance_loc: 1 to 0+0001
+  DW_CFA_def_cfa_offset: 16
+  DW_CFA_offset: r6 \(rbp\) at cfa-16
+  DW_CFA_nop
+  DW_CFA_nop
+
+#pass
diff --git a/gas/testsuite/gas/scfi/x86_64/scfi-simple-1.l b/gas/testsuite/gas/scfi/x86_64/scfi-simple-1.l
new file mode 100644
index 00000000000..bba199d24b9
--- /dev/null
+++ b/gas/testsuite/gas/scfi/x86_64/scfi-simple-1.l
@@ -0,0 +1,2 @@ 
+.*Assembler messages:
+.*7: Warning: --scfi=all ignores some user-specified CFI directives
diff --git a/gas/testsuite/gas/scfi/x86_64/scfi-simple-1.s b/gas/testsuite/gas/scfi/x86_64/scfi-simple-1.s
new file mode 100644
index 00000000000..f36b553cbff
--- /dev/null
+++ b/gas/testsuite/gas/scfi/x86_64/scfi-simple-1.s
@@ -0,0 +1,15 @@ 
+# Simple test
+# A wierd function, but SCFI machinery does not complain yet.
+	.text
+	.globl	foo
+	.type	foo, @function
+foo:
+	.cfi_startproc
+	pushq	%rbp
+	.cfi_def_cfa_offset 16
+	.cfi_offset 6, -16
+	ret
+	.cfi_endproc
+.LFE0:
+	.size	foo, .-foo
+
diff --git a/gas/testsuite/gas/scfi/x86_64/scfi-simple-2.d b/gas/testsuite/gas/scfi/x86_64/scfi-simple-2.d
new file mode 100644
index 00000000000..2fa5e565f8b
--- /dev/null
+++ b/gas/testsuite/gas/scfi/x86_64/scfi-simple-2.d
@@ -0,0 +1,30 @@ 
+#as: --scfi -W
+#objdump: -Wf
+#name: Synthesize CFI simple test 2
+#...
+Contents of the .eh_frame section:
+
+00000000 0+0014 0+0000 CIE
+  Version:               1
+  Augmentation:          "zR"
+  Code alignment factor: 1
+  Data alignment factor: -8
+  Return address column: 16
+  Augmentation data:     [01][abc]
+  DW_CFA_def_cfa: r7 \(rsp\) ofs 8
+  DW_CFA_offset: r16 \(rip\) at cfa-8
+  DW_CFA_nop
+  DW_CFA_nop
+
+0+0018 0+0001c 0+0001c FDE cie=0+0000 pc=0+0000..0+0003
+  DW_CFA_advance_loc: 1 to 0+0001
+  DW_CFA_def_cfa_offset: 16
+  DW_CFA_offset: r6 \(rbp\) at cfa-16
+  DW_CFA_advance_loc: 1 to 0+0002
+  DW_CFA_restore: r6 \(rbp\)
+  DW_CFA_def_cfa_offset: 8
+  DW_CFA_nop
+  DW_CFA_nop
+#...
+
+#pass
diff --git a/gas/testsuite/gas/scfi/x86_64/scfi-simple-2.l b/gas/testsuite/gas/scfi/x86_64/scfi-simple-2.l
new file mode 100644
index 00000000000..ce97dd14432
--- /dev/null
+++ b/gas/testsuite/gas/scfi/x86_64/scfi-simple-2.l
@@ -0,0 +1,2 @@ 
+.*Assembler messages:
+.*5: Warning: --scfi=all ignores some user-specified CFI directives
diff --git a/gas/testsuite/gas/scfi/x86_64/scfi-simple-2.s b/gas/testsuite/gas/scfi/x86_64/scfi-simple-2.s
new file mode 100644
index 00000000000..e778cef517b
--- /dev/null
+++ b/gas/testsuite/gas/scfi/x86_64/scfi-simple-2.s
@@ -0,0 +1,16 @@ 
+	.text
+	.globl	foo
+	.type	foo, @function
+foo:
+	.cfi_startproc
+	pushq	%rbp
+	.cfi_def_cfa_offset 16
+	.cfi_offset 6, -16
+	popq	%rbp
+	.cfi_restore 6
+	.cfi_def_cfa_offset 8
+	ret
+	.cfi_endproc
+.LFE0:
+	.size	foo, .-foo
+
diff --git a/gas/testsuite/gas/scfi/x86_64/scfi-sub-1.d b/gas/testsuite/gas/scfi/x86_64/scfi-sub-1.d
new file mode 100644
index 00000000000..80fb5bfb210
--- /dev/null
+++ b/gas/testsuite/gas/scfi/x86_64/scfi-sub-1.d
@@ -0,0 +1,25 @@ 
+#as: --scfi -W
+#objdump: -Wf
+#name: Synthesize CFI for sub insn 1
+#...
+Contents of the .eh_frame section:
+
+00000000 0+0014 0+0000 CIE
+  Version:               1
+  Augmentation:          "zR"
+  Code alignment factor: 1
+  Data alignment factor: -8
+  Return address column: 16
+  Augmentation data:     [01][abc]
+  DW_CFA_def_cfa: r7 \(rsp\) ofs 8
+  DW_CFA_offset: r16 \(rip\) at cfa-8
+  DW_CFA_nop
+  DW_CFA_nop
+
+0+0018 0+0014 0+001c FDE cie=0+0000 pc=0+0000..0+0008
+  DW_CFA_advance_loc: 7 to 0+0007
+  DW_CFA_def_cfa_offset: 120016
+  DW_CFA_nop
+#...
+
+#pass
diff --git a/gas/testsuite/gas/scfi/x86_64/scfi-sub-1.l b/gas/testsuite/gas/scfi/x86_64/scfi-sub-1.l
new file mode 100644
index 00000000000..0e094077edd
--- /dev/null
+++ b/gas/testsuite/gas/scfi/x86_64/scfi-sub-1.l
@@ -0,0 +1,2 @@ 
+.*Assembler messages:
+.*6: Warning: --scfi=all ignores some user-specified CFI directives
diff --git a/gas/testsuite/gas/scfi/x86_64/scfi-sub-1.s b/gas/testsuite/gas/scfi/x86_64/scfi-sub-1.s
new file mode 100644
index 00000000000..741a0abf69f
--- /dev/null
+++ b/gas/testsuite/gas/scfi/x86_64/scfi-sub-1.s
@@ -0,0 +1,12 @@ 
+# Testcase for sub instruction.
+	.text
+	.globl	foo
+	.type	foo, @function
+foo:
+	.cfi_startproc
+        subq    $120008, %rsp
+        .cfi_def_cfa_offset 120016
+	ret
+	.cfi_endproc
+.LFE0:
+	.size	foo, .-foo
diff --git a/gas/testsuite/gas/scfi/x86_64/scfi-sub-2.d b/gas/testsuite/gas/scfi/x86_64/scfi-sub-2.d
new file mode 100644
index 00000000000..3fb232f1e1b
--- /dev/null
+++ b/gas/testsuite/gas/scfi/x86_64/scfi-sub-2.d
@@ -0,0 +1,31 @@ 
+#as: --scfi -W
+#objdump: -Wf
+#name: Synthesize CFI for sub insn 2
+#...
+Contents of the .eh_frame section:
+
+00000000 0+0014 0+0000 CIE
+  Version:               1
+  Augmentation:          "zR"
+  Code alignment factor: 1
+  Data alignment factor: -8
+  Return address column: 16
+  Augmentation data:     [01][abc]
+  DW_CFA_def_cfa: r7 \(rsp\) ofs 8
+  DW_CFA_offset: r16 \(rip\) at cfa-8
+  DW_CFA_nop
+  DW_CFA_nop
+
+0+0018 0+001c 0+001c FDE cie=0+0000 pc=0+0000..0+001d
+  DW_CFA_advance_loc: 1 to 0+0001
+  DW_CFA_def_cfa_offset: 16
+  DW_CFA_offset: r6 \(rbp\) at cfa-16
+  DW_CFA_advance_loc: 3 to 0+0004
+  DW_CFA_def_cfa_register: r6 \(rbp\)
+  DW_CFA_advance_loc: 24 to 0+001c
+  DW_CFA_def_cfa_register: r7 \(rsp\)
+  DW_CFA_restore: r6 \(rbp\)
+  DW_CFA_def_cfa_offset: 8
+  DW_CFA_nop
+
+#pass
diff --git a/gas/testsuite/gas/scfi/x86_64/scfi-sub-2.l b/gas/testsuite/gas/scfi/x86_64/scfi-sub-2.l
new file mode 100644
index 00000000000..0e094077edd
--- /dev/null
+++ b/gas/testsuite/gas/scfi/x86_64/scfi-sub-2.l
@@ -0,0 +1,2 @@ 
+.*Assembler messages:
+.*6: Warning: --scfi=all ignores some user-specified CFI directives
diff --git a/gas/testsuite/gas/scfi/x86_64/scfi-sub-2.s b/gas/testsuite/gas/scfi/x86_64/scfi-sub-2.s
new file mode 100644
index 00000000000..2435c4d5c1a
--- /dev/null
+++ b/gas/testsuite/gas/scfi/x86_64/scfi-sub-2.s
@@ -0,0 +1,29 @@ 
+# Testcase for sub reg, reg instruction.
+	.text
+	.globl	foo
+	.type	foo, @function
+foo:
+	.cfi_startproc
+	pushq	%rbp
+	.cfi_def_cfa_offset 16
+	.cfi_offset 6, -16
+	movq    %rsp, %rbp
+	.cfi_def_cfa_register 6
+	subq    %rax, %rsp
+# SCFI: Stack-pointer manipulation after switching
+# to RBP based tracking is OK.
+	addq	%rax, %rsp
+# Other kind of sub instructions should not error out in the
+# x86_64 -> ginsn translator
+	subq    (%r12), %rax
+	subq	$1,(%rdi)
+	subq    %rax, 40(%r12)
+	subl    %edx, -32(%rsp)
+	leave
+	.cfi_def_cfa_register 7
+	.cfi_restore 6
+	.cfi_def_cfa_offset 8
+	ret
+	.cfi_endproc
+.LFE0:
+	.size	foo, .-foo
diff --git a/gas/testsuite/gas/scfi/x86_64/scfi-unsupported-1.l b/gas/testsuite/gas/scfi/x86_64/scfi-unsupported-1.l
new file mode 100644
index 00000000000..c856c08c2ae
--- /dev/null
+++ b/gas/testsuite/gas/scfi/x86_64/scfi-unsupported-1.l
@@ -0,0 +1,2 @@ 
+Assembler messages:
+Fatal error: Synthesizing CFI is not supported for this ABI
diff --git a/gas/testsuite/gas/scfi/x86_64/scfi-unsupported-1.s b/gas/testsuite/gas/scfi/x86_64/scfi-unsupported-1.s
new file mode 100644
index 00000000000..87d2a4971a1
--- /dev/null
+++ b/gas/testsuite/gas/scfi/x86_64/scfi-unsupported-1.s
@@ -0,0 +1,10 @@ 
+# Testcase run with --m32 (Not supported).
+	.text
+	.globl	foo
+	.type	foo, @function
+foo:
+	pushq	%rbp
+	ret
+.LFE0:
+	.size	foo, .-foo
+
diff --git a/gas/testsuite/gas/scfi/x86_64/scfi-unsupported-2.l b/gas/testsuite/gas/scfi/x86_64/scfi-unsupported-2.l
new file mode 100644
index 00000000000..69c71fb9d7e
--- /dev/null
+++ b/gas/testsuite/gas/scfi/x86_64/scfi-unsupported-2.l
@@ -0,0 +1,3 @@ 
+.*Assembler messages:
+.*8: Error: SCFI: unsupported stack manipulation pattern
+.*13: Warning: SCFI: forward pass failed for func 'foo'
diff --git a/gas/testsuite/gas/scfi/x86_64/scfi-unsupported-2.s b/gas/testsuite/gas/scfi/x86_64/scfi-unsupported-2.s
new file mode 100644
index 00000000000..22e9d88ea58
--- /dev/null
+++ b/gas/testsuite/gas/scfi/x86_64/scfi-unsupported-2.s
@@ -0,0 +1,14 @@ 
+	.text
+	.globl	foo
+	.type	foo, @function
+foo:
+	addq    %rdx, %rax
+# Stack manipulation without switching to RBP
+# based tracking is not supported for SCFI.
+	addq    %rax, %rsp
+	push    %rdi
+	leave
+	ret
+.LFE0:
+	.size	foo, .-foo
+
diff --git a/gas/testsuite/gas/scfi/x86_64/scfi-unsupported-3.l b/gas/testsuite/gas/scfi/x86_64/scfi-unsupported-3.l
new file mode 100644
index 00000000000..69c71fb9d7e
--- /dev/null
+++ b/gas/testsuite/gas/scfi/x86_64/scfi-unsupported-3.l
@@ -0,0 +1,3 @@ 
+.*Assembler messages:
+.*8: Error: SCFI: unsupported stack manipulation pattern
+.*13: Warning: SCFI: forward pass failed for func 'foo'
diff --git a/gas/testsuite/gas/scfi/x86_64/scfi-unsupported-3.s b/gas/testsuite/gas/scfi/x86_64/scfi-unsupported-3.s
new file mode 100644
index 00000000000..c515171f2b5
--- /dev/null
+++ b/gas/testsuite/gas/scfi/x86_64/scfi-unsupported-3.s
@@ -0,0 +1,14 @@ 
+	.text
+	.globl	foo
+	.type	foo, @function
+foo:
+	addq    %rdx, %rax
+# Stack manipulation without switching to RBP
+# based tracking is not supported for SCFI.
+	movq    %rax, %rsp
+	push    %rdi
+	leave
+	ret
+.LFE0:
+	.size	foo, .-foo
+
diff --git a/gas/testsuite/gas/scfi/x86_64/scfi-unsupported-4.l b/gas/testsuite/gas/scfi/x86_64/scfi-unsupported-4.l
new file mode 100644
index 00000000000..c30d2057ddb
--- /dev/null
+++ b/gas/testsuite/gas/scfi/x86_64/scfi-unsupported-4.l
@@ -0,0 +1,4 @@ 
+.*Assembler messages:
+.*6: Warning: --scfi=all ignores some user-specified CFI directives
+.*14: Error: SCFI: unsupported stack manipulation pattern
+.*22: Warning: SCFI: forward pass failed for func 'foo'
diff --git a/gas/testsuite/gas/scfi/x86_64/scfi-unsupported-4.s b/gas/testsuite/gas/scfi/x86_64/scfi-unsupported-4.s
new file mode 100644
index 00000000000..51ff92b7e50
--- /dev/null
+++ b/gas/testsuite/gas/scfi/x86_64/scfi-unsupported-4.s
@@ -0,0 +1,23 @@ 
+	.type	foo, @function
+foo:
+.LFB16:
+#	.cfi_startproc
+	pushq	%rbp
+	.cfi_def_cfa_offset 16
+	.cfi_offset 6, -16
+	movq    %rsp, %rbp
+# The following stack manipulation is OK to do, as CFA tracking
+# REG_FP based.
+	movq	%rax, %rsp
+# But...not quite, if there is a follow up usage of stack
+# like a register save of a callee-saved register.
+	push	%rbx
+	mov	%rbp, %rsp
+	popq	%rbp
+	.cfi_def_cfa 7, 8
+	.cfi_restore 6
+	ret
+#	.cfi_endproc
+.LFE16:
+	.size	foo, .-foo
+
diff --git a/gas/testsuite/gas/scfi/x86_64/scfi-unsupported-cfg-1.l b/gas/testsuite/gas/scfi/x86_64/scfi-unsupported-cfg-1.l
new file mode 100644
index 00000000000..ac0d49388d6
--- /dev/null
+++ b/gas/testsuite/gas/scfi/x86_64/scfi-unsupported-cfg-1.l
@@ -0,0 +1,3 @@ 
+.*Assembler messages:
+.*50: Warning: --scfi=all ignores some user-specified CFI directives
+.*52: Warning: Untraceable control flow for func 'foo'; Skipping SCFI
diff --git a/gas/testsuite/gas/scfi/x86_64/scfi-unsupported-cfg-1.s b/gas/testsuite/gas/scfi/x86_64/scfi-unsupported-cfg-1.s
new file mode 100644
index 00000000000..7d241f880d7
--- /dev/null
+++ b/gas/testsuite/gas/scfi/x86_64/scfi-unsupported-cfg-1.s
@@ -0,0 +1,53 @@ 
+# Testcase with an indirect jump
+# Indirect jumps, when present, make the list of ginsn an invalid
+# candidate for CFG creation.  Hence, no SCFI can be generated either.
+#
+# The testcase is rather long to showcase a simple concept.  The reason of
+# such a long testcase is to discuss if it is important to deal with these
+# patterns.  It may be possible to deal with this, if we allow some special
+# directives for helping the assembler with the indirect jump (jump table).
+	.text
+	.globl	foo
+	.type	foo, @function
+foo:
+        pushq   %rbp
+        movq    %rsp, %rbp
+        movl    %edi, -4(%rbp)
+        cmpl    $5, -4(%rbp)
+        ja      .L2
+        movl    -4(%rbp), %eax
+        movq    .L4(,%rax,8), %rax
+        jmp     *%rax
+.L4:
+        .quad   .L9
+        .quad   .L8
+        .quad   .L7
+        .quad   .L6
+        .quad   .L5
+        .quad   .L3
+.L9:
+        movl    $43, %eax
+        jmp     .L1
+.L8:
+        movl    $42, %eax
+        jmp     .L1
+.L7:
+        movl    $45, %eax
+        jmp     .L1
+.L6:
+        movl    $47, %eax
+        jmp     .L1
+.L5:
+        movl    $37, %eax
+        jmp     .L1
+.L3:
+        movl    $63, %eax
+        jmp     .L1
+.L2:
+.L1:
+        popq    %rbp
+        ret
+	.cfi_endproc
+.LFE0:
+	.size	foo, .-foo
+
diff --git a/gas/testsuite/gas/scfi/x86_64/scfi-unsupported-drap-1.l b/gas/testsuite/gas/scfi/x86_64/scfi-unsupported-drap-1.l
new file mode 100644
index 00000000000..c4e48ced26e
--- /dev/null
+++ b/gas/testsuite/gas/scfi/x86_64/scfi-unsupported-drap-1.l
@@ -0,0 +1,4 @@ 
+.*Assembler messages:
+.*16: Warning: --scfi=all ignores some user-specified CFI directives
+.*19: Error: SCFI: unsupported stack manipulation pattern
+.*75: Warning: SCFI: forward pass failed for func 'drap_foo'
diff --git a/gas/testsuite/gas/scfi/x86_64/scfi-unsupported-drap-1.s b/gas/testsuite/gas/scfi/x86_64/scfi-unsupported-drap-1.s
new file mode 100644
index 00000000000..c23828b8f9b
--- /dev/null
+++ b/gas/testsuite/gas/scfi/x86_64/scfi-unsupported-drap-1.s
@@ -0,0 +1,75 @@ 
+# Testcase with Dynamically Realigned Argument Pointer (DRAP)
+# register usage.
+#
+# There are two reasons why this cannot be supported with the current
+# SCFI machinery
+# 1. Not allowed: REG_CFA is r10 based for the few insns after
+#    'leaq    8(%rsp), %r10'.
+# 2. Untraceable stack size after 'andq    $-16, %rsp'
+# Both of these shortcomings may be worked out. FIXME DISCUSS Keep the rather
+# long testcase until then.
+	.text
+	.globl	drap_foo
+	.type	drap_foo, @function
+drap_foo:
+.LFB0:
+	.cfi_startproc
+	leaq	8(%rsp), %r10
+	.cfi_def_cfa 10, 0
+	andq	$-16, %rsp
+	pushq	-8(%r10)
+        .cfi_def_cfa 7, 8
+	pushq	%rbp
+	.cfi_offset 6, -16
+	movq	%rsp, %rbp
+	.cfi_def_cfa_register 6
+	pushq	%r15
+	pushq	%r14
+	pushq	%r13
+	pushq	%r12
+	pushq	%r10
+	.cfi_offset 15, -24
+	.cfi_offset 14, -32
+	.cfi_offset 13, -40
+	.cfi_offset 12, -48
+	pushq	%rbx
+	.cfi_offset 3, -64
+	subq	$32, %rsp
+	movq	$0, (%rdx)
+	cmpq	$0, (%rdi)
+	movq	$0, -56(%rbp)
+	je	.L21
+	movq	%rdi, %rbx
+	movq	%rsi, %rdi
+	movq	%rsi, %r12
+	call	func2@PLT
+	movq	(%rbx), %rdi
+	leaq	-56(%rbp), %rdx
+	movslq	%eax, %rsi
+	call	func1@PLT
+	testl	%eax, %eax
+	je	.L21
+	movq	-56(%rbp), %r13
+.L21:
+	addq	$32, %rsp
+	xorl	%eax, %eax
+	popq	%rbx
+	.cfi_restore 3
+	popq	%r10
+	popq	%r12
+	.cfi_restore 12
+	popq	%r13
+	.cfi_restore 13
+	popq	%r14
+	.cfi_restore 14
+	popq	%r15
+	.cfi_restore 15
+	popq	%rbp
+	.cfi_restore 6
+	.cfi_def_cfa_register 7
+	.cfi_def_cfa_offset 8
+	leaq	-8(%r10), %rsp
+	ret
+	.cfi_endproc
+.LFE0:
+	.size	drap_foo, .-drap_foo
diff --git a/gas/testsuite/gas/scfi/x86_64/scfi-x86-64.exp b/gas/testsuite/gas/scfi/x86_64/scfi-x86-64.exp
new file mode 100644
index 00000000000..ff8f163f18e
--- /dev/null
+++ b/gas/testsuite/gas/scfi/x86_64/scfi-x86-64.exp
@@ -0,0 +1,103 @@ 
+# Copyright (C) 2022-2023 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
+
+if { ![is_elf_format] } then {
+    return
+}
+
+# common tests
+if  { ([istarget "x86_64-*-*"]) } then {
+
+    global ASFLAGS
+    set old_ASFLAGS "$ASFLAGS"
+
+    run_dump_test "scfi-cfi-label-1"
+    run_list_test "scfi-cfi-label-1" "--scfi --warn"
+
+    run_list_test "scfi-diag-1" "--scfi"
+    run_list_test "scfi-fp-diag-2" "--scfi"
+    run_list_test "scfi-diag-2" "--scfi"
+
+    run_list_test "scfi-unsupported-1" "--32 --scfi"
+    run_list_test "scfi-unsupported-2" "--scfi"
+    run_list_test "scfi-unsupported-3" "--scfi"
+    run_list_test "scfi-unsupported-4" "--scfi"
+    run_list_test "scfi-unsupported-drap-1" "--scfi"
+    run_list_test "scfi-unsupported-cfg-1" "--scfi"
+
+    run_dump_test "scfi-add-1"
+    run_list_test "scfi-add-1" "--scfi --warn"
+    run_dump_test "scfi-add-2"
+    run_list_test "scfi-add-2" "--scfi --warn"
+    run_dump_test "scfi-cfg-1"
+    run_list_test "scfi-cfg-1" "--scfi --warn"
+    run_dump_test "scfi-cfg-2"
+    run_list_test "scfi-cfg-2" "--scfi --warn"
+    run_dump_test "scfi-asm-marker-1"
+    run_list_test "scfi-asm-marker-1" "--scfi --warn"
+    run_dump_test "scfi-asm-marker-2"
+    run_list_test "scfi-asm-marker-2" "--scfi --warn"
+    run_dump_test "scfi-asm-marker-3"
+    run_list_test "scfi-asm-marker-3" "--scfi --warn"
+    run_dump_test "scfi-pushsection-1"
+    run_list_test "scfi-pushsection-1" "--scfi --warn"
+    run_dump_test "scfi-pushsection-2"
+    run_list_test "scfi-pushsection-2" "--scfi --warn"
+
+    run_dump_test "scfi-cofi-1"
+    run_list_test "scfi-cofi-1" "--scfi --warn"
+    run_dump_test "scfi-sub-1"
+    run_list_test "scfi-sub-1" "--scfi --warn"
+    run_dump_test "scfi-sub-2"
+    run_list_test "scfi-sub-2" "--scfi --warn"
+    run_dump_test "scfi-ignore-1"
+    run_list_test "scfi-ignore-1" "--scfi --warn"
+    run_dump_test "scfi-simple-1"
+    run_list_test "scfi-simple-1" "--scfi --warn"
+    run_dump_test "scfi-simple-2"
+    run_list_test "scfi-simple-2" "--scfi --warn"
+    run_dump_test "scfi-pushq-1"
+    run_list_test "scfi-pushq-1" "--scfi --warn"
+    run_dump_test "scfi-lea-1"
+    run_list_test "scfi-lea-1" "--scfi --warn"
+    run_dump_test "scfi-leave-1"
+    run_list_test "scfi-leave-1" "--scfi --warn"
+    run_dump_test "scfi-bp-sp-1"
+    run_list_test "scfi-bp-sp-1" "--scfi --warn"
+    run_dump_test "scfi-bp-sp-2"
+    run_list_test "scfi-bp-sp-2" "--scfi --warn"
+    run_dump_test "scfi-cfg-1"
+    run_list_test "scfi-cfg-1" "--scfi --warn"
+    run_dump_test "scfi-callee-saved-2"
+    run_list_test "scfi-callee-saved-2" "--scfi --warn"
+    run_dump_test "scfi-callee-saved-3"
+    run_list_test "scfi-callee-saved-3" "--scfi --warn"
+    run_dump_test "scfi-callee-saved-4"
+    run_list_test "scfi-callee-saved-4" "--scfi --warn"
+    run_dump_test "scfi-dyn-stack-1"
+    run_list_test "scfi-dyn-stack-1" "--scfi --warn"
+    run_dump_test "scfi-indirect-mov-1"
+    run_list_test "scfi-indirect-mov-1" "--scfi --warn"
+    run_dump_test "scfi-indirect-mov-2"
+    run_list_test "scfi-indirect-mov-2" "--scfi --warn"
+    run_dump_test "scfi-indirect-mov-3"
+    run_list_test "scfi-indirect-mov-3" "--scfi --warn"
+    run_dump_test "scfi-indirect-mov-4"
+    run_list_test "scfi-indirect-mov-4" "--scfi --warn"
+    run_dump_test "scfi-selfalign-func-1"
+    run_list_test "scfi-selfalign-func-1" "--scfi --warn"
+}
+