Skip to main content

IAR Embedded Workbench for RISC-V 3.40

Creating assembler source with CFI support

In this section:

The recommended way to create an assembler language routine that handles call frame information correctly is to start with an assembler language source file created by the compiler.

  1. Start with suitable C source code, for example:

    int F(int);
    int cfiExample(int i)
    {
      return i + F(i);
    }
  2. Compile the C source code, and make sure to create a list file that contains call frame information—the CFI directives.

    Danger

    On the command line, use the option -lA.

    Caution

    In the IDE, choose Project>Options>C/C++ Compiler>List and make sure the suboption Include call frame information is selected.

    For the source code in this example, the list file looks like this.

            EXTERN F
    
            PUBLIC cfiExample
            
              CFI Names cfiNames0
              CFI StackFrame CFA sp DATA
              CFI Resource ra:32, sp:32, gp:32, tp:32, t0:32, t1:32,
                           t2:32, s0:32
              CFI Resource s1:32, a0:32, a1:32, a2:32, a3:32, a4:32,
                           a5:32, a6:32
              CFI Resource a7:32, s2:32, s3:32, s4:32, s5:32, s6:32,
                           s7:32, s8:32
              CFI Resource s9:32, s10:32, s11:32, t3:32, t4:32,
                           t5:32, t6:32
              CFI VirtualResource ?RET:32
              CFI EndNames cfiNames0
              CFI Common cfiCommon0 Using cfiNames0
              CFI CodeAlign 1
              CFI DataAlign 1
              CFI ReturnAddress ?RET CODE
              CFI CFA sp+0
              CFI ra SameValue
              CFI gp SameValue
              CFI tp SameValue
              CFI t0 Undefined
              CFI t1 Undefined
              CFI t2 Undefined
              CFI s0 SameValue
              CFI s1 SameValue
              CFI a0 Undefined
              CFI a1 Undefined
              CFI a2 Undefined
              CFI a3 Undefined
              CFI a4 Undefined
              CFI a5 Undefined
              CFI a6 Undefined
              CFI a7 Undefined
              CFI s2 SameValue
              CFI s3 SameValue
              CFI s4 SameValue
              CFI s5 SameValue
              CFI s6 SameValue
              CFI s7 SameValue
              CFI s8 SameValue
              CFI s9 SameValue
              CFI s10 SameValue
              CFI s11 SameValue
              CFI t3 Undefined
              CFI t4 Undefined
              CFI t5 Undefined
              CFI t6 Undefined
              CFI ?RET ra
              CFI EndCommon cfiCommon0
            SECTION `.text`:CODE:REORDER:NOROOT(2)
              CFI Block cfiBlock0 Using cfiCommon0
              CFI Function cfiExample
            CODE
    cfiExample:
            //              ‑‑‑‑‑‑‑‑‑‑ prologue ‑‑‑‑‑‑‑‑‑‑
            addi      sp, sp, -0x10
              CFI CFA sp+16
            sw        ra, 0xc(sp)
              CFI ?RET Frame(CFA, -4)
            sw        s0, 0x8(sp)
              CFI s0 Frame(CFA, -8)
            //              ‑‑‑‑‑‑‑‑‑‑   body   ‑‑‑‑‑‑‑‑‑‑
            mv        s0, a0
            
              CFI FunCall F
            call      F
            add       a0, s0, a0
            //              ‑‑‑‑‑‑‑‑‑‑ epilogue ‑‑‑‑‑‑‑‑‑‑
            lw        ra, 0xc(sp)
              CFI ?RET ra
            lw        s0, 0x8(sp)
              CFI s0 SameValue
            addi      sp, sp, 0x10
              CFI CFA sp+0
            ret
              CFI EndBlock cfiBlock0
            SECTION `.iar_vfe_header`:DATA:NOALLOC:NOROOT(2)
            SECTION_TYPE SHT_PROGBITS, 0
            DATA
            DC32 0
    
            END

    Note

    The header file iarCfi.m defines a names block, and provides the macro CfiCom that declares a typical common block. This macro declares several resources, both concrete and virtual.