[llvm] 6d9b075 - [MC] Allow .pushsection between .cfi_startproc/.cfi_endproc

Alex Brachet via llvm-commits llvm-commits at lists.llvm.org
Mon Jan 30 11:28:06 PST 2023


Author: Alex Brachet
Date: 2023-01-30T19:27:18Z
New Revision: 6d9b0759c24e93c2ef1f10ca59c7317c7b440468

URL: https://github.com/llvm/llvm-project/commit/6d9b0759c24e93c2ef1f10ca59c7317c7b440468
DIFF: https://github.com/llvm/llvm-project/commit/6d9b0759c24e93c2ef1f10ca59c7317c7b440468.diff

LOG: [MC] Allow .pushsection between .cfi_startproc/.cfi_endproc

This follows the behavior of gnu assemblers. This is useful when
writing inline assembly.

Differential Revision: https://reviews.llvm.org/D141893

Added: 
    llvm/test/MC/ELF/cfi-startproc-pushsection.s

Modified: 
    llvm/include/llvm/MC/MCStreamer.h
    llvm/lib/MC/MCStreamer.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm/MC/MCStreamer.h b/llvm/include/llvm/MC/MCStreamer.h
index e15fb485b54a7..898fbc8c0fab6 100644
--- a/llvm/include/llvm/MC/MCStreamer.h
+++ b/llvm/include/llvm/MC/MCStreamer.h
@@ -214,6 +214,10 @@ class MCStreamer {
   std::unique_ptr<MCTargetStreamer> TargetStreamer;
 
   std::vector<MCDwarfFrameInfo> DwarfFrameInfos;
+  // This is a pair of index into DwarfFrameInfos and the MCSection associated
+  // with the frame. Note, we use an index instead of an iterator because they
+  // can be invalidated in std::vector.
+  SmallVector<std::pair<size_t, MCSection *>, 1> FrameInfoStack;
   MCDwarfFrameInfo *getCurrentDwarfFrameInfo();
 
   /// Similar to DwarfFrameInfos, but for SEH unwind info. Chained frames may

diff  --git a/llvm/lib/MC/MCStreamer.cpp b/llvm/lib/MC/MCStreamer.cpp
index 56711079245dd..517e258844156 100644
--- a/llvm/lib/MC/MCStreamer.cpp
+++ b/llvm/lib/MC/MCStreamer.cpp
@@ -278,7 +278,7 @@ MCSymbol *MCStreamer::getDwarfLineTableSymbol(unsigned CUID) {
 }
 
 bool MCStreamer::hasUnfinishedDwarfFrameInfo() {
-  return !DwarfFrameInfos.empty() && !DwarfFrameInfos.back().End;
+  return !FrameInfoStack.empty();
 }
 
 MCDwarfFrameInfo *MCStreamer::getCurrentDwarfFrameInfo() {
@@ -288,7 +288,7 @@ MCDwarfFrameInfo *MCStreamer::getCurrentDwarfFrameInfo() {
                              ".cfi_startproc and .cfi_endproc directives");
     return nullptr;
   }
-  return &DwarfFrameInfos.back();
+  return &DwarfFrameInfos[FrameInfoStack.back().first];
 }
 
 bool MCStreamer::emitCVFileDirective(unsigned FileNo, StringRef Filename,
@@ -445,7 +445,8 @@ void MCStreamer::emitConditionalAssignment(MCSymbol *Symbol,
 void MCStreamer::emitCFISections(bool EH, bool Debug) {}
 
 void MCStreamer::emitCFIStartProc(bool IsSimple, SMLoc Loc) {
-  if (hasUnfinishedDwarfFrameInfo())
+  if (!FrameInfoStack.empty() &&
+      getCurrentSectionOnly() == FrameInfoStack.back().second)
     return getContext().reportError(
         Loc, "starting new .cfi frame before finishing the previous one");
 
@@ -464,6 +465,7 @@ void MCStreamer::emitCFIStartProc(bool IsSimple, SMLoc Loc) {
     }
   }
 
+  FrameInfoStack.emplace_back(DwarfFrameInfos.size(), getCurrentSectionOnly());
   DwarfFrameInfos.push_back(Frame);
 }
 
@@ -475,6 +477,7 @@ void MCStreamer::emitCFIEndProc() {
   if (!CurFrame)
     return;
   emitCFIEndProcImpl(*CurFrame);
+  FrameInfoStack.pop_back();
 }
 
 void MCStreamer::emitCFIEndProcImpl(MCDwarfFrameInfo &Frame) {

diff  --git a/llvm/test/MC/ELF/cfi-startproc-pushsection.s b/llvm/test/MC/ELF/cfi-startproc-pushsection.s
new file mode 100644
index 0000000000000..91d5dc1b4b078
--- /dev/null
+++ b/llvm/test/MC/ELF/cfi-startproc-pushsection.s
@@ -0,0 +1,45 @@
+// RUN: llvm-mc -filetype=obj -triple x86_64-linux %s -o - | llvm-dwarfdump --eh-frame - | FileCheck %s
+
+.section .text.a, "ax", %progbits
+.cfi_startproc
+.cfi_def_cfa %rsp, 0
+
+.pushsection .text.b, "ax", %progbits
+.cfi_startproc simple
+.cfi_def_cfa %rsp, 8
+nop
+ret
+
+.pushsection .text.c, "ax", %progbits
+.cfi_startproc simple
+.cfi_def_cfa %rsp, 16
+nop
+nop
+ret
+.cfi_endproc
+.popsection
+
+.cfi_endproc
+.popsection
+
+.pushsection .text.d, "ax", %progbits
+.cfi_startproc simple
+.cfi_def_cfa %rsp, 24
+nop
+nop
+nop
+ret
+.cfi_endproc
+.popsection
+
+ret
+.cfi_endproc
+
+// CHECK: pc=00000000...00000001
+// CHECK: RSP +0
+// CHECK: pc=00000000...00000002
+// CHECK: RSP +8
+// CHECK: pc=00000000...00000003
+// CHECK: RSP +16
+// CHECK: pc=00000000...00000004
+// CHECK: RSP +24


        


More information about the llvm-commits mailing list