From d506aa4edfa66074db3dc1fa84da9d9c80d71500 Mon Sep 17 00:00:00 2001 From: Jon Roelofs Date: Tue, 21 Nov 2023 09:24:37 -0800 Subject: [PATCH] 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 797b68c0ba699994e1038ac33d3083541482bf19. Fixes: #72802 Differential revision: https://reviews.llvm.org/D153167 rdar://111459507 --- lld/test/COFF/gc-dwarf-eh.s | 4 ++-- llvm/lib/MC/MCParser/AsmParser.cpp | 11 +++++++++ llvm/test/MC/AArch64/cfi-bad-nesting-darwin.s | 24 +++++++++++++++++++ llvm/test/MC/AArch64/cfi-bad-nesting-elf.s | 20 ++++++++++++++++ 4 files changed, 57 insertions(+), 2 deletions(-) create mode 100644 llvm/test/MC/AArch64/cfi-bad-nesting-darwin.s create mode 100644 llvm/test/MC/AArch64/cfi-bad-nesting-elf.s diff --git a/lld/test/COFF/gc-dwarf-eh.s b/lld/test/COFF/gc-dwarf-eh.s index 757aa671c76933..efe92d77fcb717 100644 --- a/lld/test/COFF/gc-dwarf-eh.s +++ b/lld/test/COFF/gc-dwarf-eh.s @@ -13,9 +13,9 @@ .def _main; .scl 2; .type 32; .endef .section .text,"xr",one_only,_main .globl _main +_main: .cfi_startproc .cfi_personality 0, ___gxx_personality_v0 -_main: xorl %eax, %eax ret .cfi_endproc @@ -29,8 +29,8 @@ ___gxx_personality_v0: .def _unused; .scl 2; .type 32; .endef .section .text,"xr",one_only,_unused .globl _unused +_unused: .cfi_startproc .cfi_personality 0, ___gxx_personality_v0 -_unused: ret .cfi_endproc diff --git a/llvm/lib/MC/MCParser/AsmParser.cpp b/llvm/lib/MC/MCParser/AsmParser.cpp index b36c5f067a9539..825b12e037d308 100644 --- a/llvm/lib/MC/MCParser/AsmParser.cpp +++ b/llvm/lib/MC/MCParser/AsmParser.cpp @@ -125,6 +125,7 @@ class AsmParser : public MCAsmParser { void *SavedDiagContext; std::unique_ptr PlatformParser; SMLoc StartTokLoc; + std::optional CFIStartProcLoc; /// This is the current buffer index we're lexing from as managed by the /// SourceMgr object. @@ -1949,6 +1950,11 @@ bool AsmParser::parseStatement(ParseStatementInfo &Info, Lex(); } + if (MAI.hasSubsectionsViaSymbols() && CFIStartProcLoc && Sym->isExternal()) + return Error(StartTokLoc, "non-private labels cannot appear between " + ".cfi_startproc / .cfi_endproc pairs") && + Error(*CFIStartProcLoc, "previous .cfi_startproc was here"); + if (discardLTOSymbol(IDVal)) return false; @@ -4193,6 +4199,8 @@ bool AsmParser::parseDirectiveCFISections() { /// parseDirectiveCFIStartProc /// ::= .cfi_startproc [simple] bool AsmParser::parseDirectiveCFIStartProc() { + CFIStartProcLoc = StartTokLoc; + StringRef Simple; if (!parseOptionalToken(AsmToken::EndOfStatement)) { if (check(parseIdentifier(Simple) || Simple != "simple", @@ -4213,8 +4221,11 @@ bool AsmParser::parseDirectiveCFIStartProc() { /// parseDirectiveCFIEndProc /// ::= .cfi_endproc bool AsmParser::parseDirectiveCFIEndProc() { + CFIStartProcLoc = std::nullopt; + if (parseEOL()) return true; + getStreamer().emitCFIEndProc(); return false; } diff --git a/llvm/test/MC/AArch64/cfi-bad-nesting-darwin.s b/llvm/test/MC/AArch64/cfi-bad-nesting-darwin.s new file mode 100644 index 00000000000000..235b7d44809929 --- /dev/null +++ b/llvm/test/MC/AArch64/cfi-bad-nesting-darwin.s @@ -0,0 +1,24 @@ +; RUN: not llvm-mc -triple arm64-apple-darwin %s -filetype=obj -o /dev/null 2>&1 | FileCheck %s --check-prefix=DARWIN + +; REQUIRES: aarch64-registered-target + + .section __TEXT,locomotive,regular,pure_instructions + + .globl _locomotive + .p2align 2 +_locomotive: + .cfi_startproc + ret + + ; It is invalid to have a non-private label between .cfi_startproc and + ; .cfi_endproc on MachO platforms. + .section __TEXT,__text,regular,pure_instructions + .globl _caboose + .p2align 2 +_caboose: +; DARWIN: [[#@LINE-1]]:1: error: non-private labels cannot appear between .cfi_startproc / .cfi_endproc pairs +; DARWIN: [[#@LINE-10]]:2: error: previous .cfi_startproc was here + ret + .cfi_endproc + +.subsections_via_symbols \ No newline at end of file diff --git a/llvm/test/MC/AArch64/cfi-bad-nesting-elf.s b/llvm/test/MC/AArch64/cfi-bad-nesting-elf.s new file mode 100644 index 00000000000000..98734944dbef18 --- /dev/null +++ b/llvm/test/MC/AArch64/cfi-bad-nesting-elf.s @@ -0,0 +1,20 @@ +# RUN: llvm-mc -triple arm64-pc-linux-gnu %s -filetype=obj -o /dev/null 2>&1 | FileCheck %s --allow-empty --check-prefix=ELF +# RUN: llvm-mc -triple arm64-windows-gnu %s -filetype=obj -o /dev/null 2>&1 | FileCheck %s --allow-empty --check-prefix=ELF + +# REQUIRES: aarch64-registered-target + + .globl _locomotive + .p2align 2 +_locomotive: + .cfi_startproc + ret + + .globl _caboose + .p2align 2 +_caboose: + ret + .cfi_endproc + +# Check that the diagnostic does not fire on ELF, nor COFF platforms, which do +# not support subsections_via_symbols. See also: cfi-bad-nesting-darwin.s +# ELF-NOT: error: \ No newline at end of file