Issue 146804
Summary clang cannot process intertwined assembly sections
Labels clang
Assignees
Reporter amsen20
    assembly sections are allowed to be nested and intertwined if their associated sections are, for example, the following code:
```asm
.section A
.cfi_startproc
.cfi_def_cfa_offset 1
.section B
.cfi_startproc
.cfi_def_cfa_offset 2
.section A
.cfi_def_cfa_offset 3
.cfi_endproc
.section B
.cfi_def_cfa_offset 4
.cfi_endproc
```
Is equivalent to:
```asm
.section A
.cfi_startproc
.cfi_def_cfa_offset 1
.cfi_def_cfa_offset 3
.cfi_endproc
.section B
.cfi_startproc
.cfi_def_cfa_offset 2
.cfi_def_cfa_offset 4
.cfi_endproc
```
GNU assembler can process this code as intended:
```
$ as -g a.s -o a.o && objdump --dwarf=frames a.o

a.o: file format elf64-x86-64

Contents of the .eh_frame section:


00000000 0000000000000018 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_def_cfa_offset: 1
  DW_CFA_def_cfa_offset: 3
  DW_CFA_nop
  DW_CFA_nop

0000001c 0000000000000010 00000020 FDE cie=00000000 pc=0000000000000000..0000000000000000
  DW_CFA_nop
  DW_CFA_nop
 DW_CFA_nop

00000030 0000000000000018 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_def_cfa_offset: 2
  DW_CFA_def_cfa_offset: 4
  DW_CFA_nop
 DW_CFA_nop

0000004c 0000000000000010 00000020 FDE cie=00000030 pc=0000000000000000..0000000000000000
  DW_CFA_nop
  DW_CFA_nop
 DW_CFA_nop
```
But LLVM just emits an error for it:
```
$ clang -c -g a.s -o a.o
<unknown>:0: error: invalid CFI advance_loc _expression_
<unknown>:0: error: invalid CFI advance_loc _expression_
<unknown>:0: error: Cannot represent a difference across sections
<unknown>:0: error: Cannot represent a difference across sections
```

This problem does not happen when the sections are intertwined like a stack, for example both of the following codes:
```
.section A
.cfi_startproc
.cfi_def_cfa_offset 1

.section B
.cfi_startproc
.cfi_def_cfa_offset 2
.cfi_def_cfa_offset 3
.cfi_endproc
.section A

.cfi_def_cfa_offset 4
.cfi_endproc
```
and
```
.pushsection A
.cfi_startproc
.cfi_def_cfa_offset 1

.pushsection B
.cfi_startproc
.cfi_def_cfa_offset 2
.cfi_def_cfa_offset 3
.cfi_endproc
.popsection

.cfi_def_cfa_offset 4
.cfi_endproc
.popsection
```
Are equal in the eye of `clang`, and the debug info in sections is correctly processed:
```
a.o:    file format elf64-x86-64

.debug_frame contents:


.eh_frame contents:

00000000 00000014 00000000 CIE
  Format:                DWARF32
  Version: 1
  Augmentation:          "zR"
  Code alignment factor: 1
  Data alignment factor: -8
  Return address column: 16
  Augmentation data: 1B

  DW_CFA_def_cfa: reg7 +8
  DW_CFA_offset: reg16 -8
  DW_CFA_nop:
 DW_CFA_nop:

  CFA=reg7+8: reg16=[CFA-8]

00000018 00000014 0000001c FDE cie=00000000 pc=00000000...00000000
  Format:       DWARF32
 DW_CFA_def_cfa_offset: +1
  DW_CFA_def_cfa_offset: +4
  DW_CFA_nop:
 DW_CFA_nop:
  DW_CFA_nop:

  0x0: CFA=reg7+4: reg16=[CFA-8]

00000030 00000014 00000034 FDE cie=00000000 pc=00000000...00000000
  Format: DWARF32
  DW_CFA_def_cfa_offset: +2
  DW_CFA_def_cfa_offset: +3
 DW_CFA_nop:
  DW_CFA_nop:
  DW_CFA_nop:

  0x0: CFA=reg7+3: reg16=[CFA-8]
```
_______________________________________________
llvm-bugs mailing list
llvm-bugs@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs

Reply via email to