Skip to content

Commit d506aa4

Browse files
committed
Reland "[MC][AsmParser] Diagnose improperly nested .cfi frames"
This showed up when simplifying some large testcase, where the cfi directives became out of sync with the proc's they enclose. Now restricted to platforms that support .subsections_via_symbols. This reverts commit 797b68c. Fixes: llvm#72802 Differential revision: https://reviews.llvm.org/D153167 rdar://111459507
1 parent 1552b91 commit d506aa4

File tree

4 files changed

+57
-2
lines changed

4 files changed

+57
-2
lines changed

lld/test/COFF/gc-dwarf-eh.s

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,9 @@
1313
.def _main; .scl 2; .type 32; .endef
1414
.section .text,"xr",one_only,_main
1515
.globl _main
16+
_main:
1617
.cfi_startproc
1718
.cfi_personality 0, ___gxx_personality_v0
18-
_main:
1919
xorl %eax, %eax
2020
ret
2121
.cfi_endproc
@@ -29,8 +29,8 @@ ___gxx_personality_v0:
2929
.def _unused; .scl 2; .type 32; .endef
3030
.section .text,"xr",one_only,_unused
3131
.globl _unused
32+
_unused:
3233
.cfi_startproc
3334
.cfi_personality 0, ___gxx_personality_v0
34-
_unused:
3535
ret
3636
.cfi_endproc

llvm/lib/MC/MCParser/AsmParser.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,7 @@ class AsmParser : public MCAsmParser {
125125
void *SavedDiagContext;
126126
std::unique_ptr<MCAsmParserExtension> PlatformParser;
127127
SMLoc StartTokLoc;
128+
std::optional<SMLoc> CFIStartProcLoc;
128129

129130
/// This is the current buffer index we're lexing from as managed by the
130131
/// SourceMgr object.
@@ -1949,6 +1950,11 @@ bool AsmParser::parseStatement(ParseStatementInfo &Info,
19491950
Lex();
19501951
}
19511952

1953+
if (MAI.hasSubsectionsViaSymbols() && CFIStartProcLoc && Sym->isExternal())
1954+
return Error(StartTokLoc, "non-private labels cannot appear between "
1955+
".cfi_startproc / .cfi_endproc pairs") &&
1956+
Error(*CFIStartProcLoc, "previous .cfi_startproc was here");
1957+
19521958
if (discardLTOSymbol(IDVal))
19531959
return false;
19541960

@@ -4193,6 +4199,8 @@ bool AsmParser::parseDirectiveCFISections() {
41934199
/// parseDirectiveCFIStartProc
41944200
/// ::= .cfi_startproc [simple]
41954201
bool AsmParser::parseDirectiveCFIStartProc() {
4202+
CFIStartProcLoc = StartTokLoc;
4203+
41964204
StringRef Simple;
41974205
if (!parseOptionalToken(AsmToken::EndOfStatement)) {
41984206
if (check(parseIdentifier(Simple) || Simple != "simple",
@@ -4213,8 +4221,11 @@ bool AsmParser::parseDirectiveCFIStartProc() {
42134221
/// parseDirectiveCFIEndProc
42144222
/// ::= .cfi_endproc
42154223
bool AsmParser::parseDirectiveCFIEndProc() {
4224+
CFIStartProcLoc = std::nullopt;
4225+
42164226
if (parseEOL())
42174227
return true;
4228+
42184229
getStreamer().emitCFIEndProc();
42194230
return false;
42204231
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
; RUN: not llvm-mc -triple arm64-apple-darwin %s -filetype=obj -o /dev/null 2>&1 | FileCheck %s --check-prefix=DARWIN
2+
3+
; REQUIRES: aarch64-registered-target
4+
5+
.section __TEXT,locomotive,regular,pure_instructions
6+
7+
.globl _locomotive
8+
.p2align 2
9+
_locomotive:
10+
.cfi_startproc
11+
ret
12+
13+
; It is invalid to have a non-private label between .cfi_startproc and
14+
; .cfi_endproc on MachO platforms.
15+
.section __TEXT,__text,regular,pure_instructions
16+
.globl _caboose
17+
.p2align 2
18+
_caboose:
19+
; DARWIN: [[#@LINE-1]]:1: error: non-private labels cannot appear between .cfi_startproc / .cfi_endproc pairs
20+
; DARWIN: [[#@LINE-10]]:2: error: previous .cfi_startproc was here
21+
ret
22+
.cfi_endproc
23+
24+
.subsections_via_symbols
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# RUN: llvm-mc -triple arm64-pc-linux-gnu %s -filetype=obj -o /dev/null 2>&1 | FileCheck %s --allow-empty --check-prefix=ELF
2+
# RUN: llvm-mc -triple arm64-windows-gnu %s -filetype=obj -o /dev/null 2>&1 | FileCheck %s --allow-empty --check-prefix=ELF
3+
4+
# REQUIRES: aarch64-registered-target
5+
6+
.globl _locomotive
7+
.p2align 2
8+
_locomotive:
9+
.cfi_startproc
10+
ret
11+
12+
.globl _caboose
13+
.p2align 2
14+
_caboose:
15+
ret
16+
.cfi_endproc
17+
18+
# Check that the diagnostic does not fire on ELF, nor COFF platforms, which do
19+
# not support subsections_via_symbols. See also: cfi-bad-nesting-darwin.s
20+
# ELF-NOT: error:

0 commit comments

Comments
 (0)