[JITLink][ELF][AArch64] Implement eh frame handling.
authorSunho Kim <ksunhokim123@naver.com>
Fri, 10 Jun 2022 18:34:49 +0000 (03:34 +0900)
committerSunho Kim <ksunhokim123@naver.com>
Fri, 10 Jun 2022 19:06:14 +0000 (04:06 +0900)
Implements eh frame handling by using generic EHFrame passes. The c++ exception handling works correctly with this change.

Reviewed By: lhames

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

llvm/lib/ExecutionEngine/JITLink/ELF_aarch64.cpp
llvm/test/ExecutionEngine/JITLink/AArch64/ELF_aarch64_ehframe.s [new file with mode: 0644]

index 0f6f731..e6b44b1 100644 (file)
 //===----------------------------------------------------------------------===//
 
 #include "llvm/ExecutionEngine/JITLink/ELF_aarch64.h"
+#include "EHFrameSupportImpl.h"
 #include "ELFLinkGraphBuilder.h"
 #include "JITLinkGeneric.h"
 #include "llvm/BinaryFormat/ELF.h"
+#include "llvm/ExecutionEngine/JITLink/DWARFRecordSectionSplitter.h"
 #include "llvm/ExecutionEngine/JITLink/aarch64.h"
 #include "llvm/Object/ELFObjectFile.h"
 #include "llvm/Support/Endian.h"
@@ -402,6 +404,10 @@ void link_ELF_aarch64(std::unique_ptr<LinkGraph> G,
   PassConfiguration Config;
   const Triple &TT = G->getTargetTriple();
   if (Ctx->shouldAddDefaultTargetPasses(TT)) {
+    Config.PrePrunePasses.push_back(DWARFRecordSectionSplitter(".eh_frame"));
+    Config.PrePrunePasses.push_back(EHFrameEdgeFixer(
+        ".eh_frame", 8, aarch64::Pointer32, aarch64::Pointer64,
+        aarch64::Delta32, aarch64::Delta64, aarch64::NegDelta32));
     if (auto MarkLive = Ctx->getMarkLivePass(TT))
       Config.PrePrunePasses.push_back(std::move(MarkLive));
     else
diff --git a/llvm/test/ExecutionEngine/JITLink/AArch64/ELF_aarch64_ehframe.s b/llvm/test/ExecutionEngine/JITLink/AArch64/ELF_aarch64_ehframe.s
new file mode 100644 (file)
index 0000000..ff7e5a6
--- /dev/null
@@ -0,0 +1,80 @@
+# REQUIRES: asserts
+# RUN: llvm-mc -triple=aarch64-linux-gnu -filetype=obj -o %t %s
+# RUN: llvm-jitlink -noexec -phony-externals -debug-only=jitlink %t 2>&1 | \
+# RUN:   FileCheck %s
+#
+# Check that splitting of eh-frame sections works.
+#
+# CHECK: DWARFRecordSectionSplitter: Processing .eh_frame...
+# CHECK:  Processing block at
+# CHECK:    Processing CFI record at
+# CHECK:      Extracted {{.*}} section = .eh_frame
+# CHECK:    Processing CFI record at
+# CHECK:      Extracted {{.*}} section = .eh_frame
+# CHECK: EHFrameEdgeFixer: Processing .eh_frame...
+# CHECK:   Processing block at
+# CHECK:     Processing CFI record at
+# CHECK:       Record is CIE
+# CHECK:   Processing block at
+# CHECK:     Processing CFI record at
+# CHECK:       Record is FDE
+# CHECK:         Adding edge at {{.*}} to CIE at: {{.*}}
+# CHECK:         Existing edge at {{.*}} to PC begin at {{.*}}
+# CHECK:         Adding keep-alive edge from target at {{.*}} to FDE at {{.*}}
+# CHECK:   Processing block at
+# CHECK:     Processing CFI record at
+# CHECK:       Record is FDE
+# CHECK:         Adding edge at {{.*}} to CIE at: {{.*}}
+# CHECK:         Existing edge at {{.*}} to PC begin at {{.*}}
+# CHECK:         Adding keep-alive edge from target at {{.*}} to FDE at {{.*}}
+
+       .text
+       .globl  main
+       .p2align        2
+       .type   main,@function
+main: 
+       .cfi_startproc
+       sub     sp, sp, #32
+       .cfi_def_cfa_offset 32
+       stp     x29, x30, [sp, #16]
+       add     x29, sp, #16
+       .cfi_def_cfa w29, 16
+       .cfi_offset w30, -8
+       .cfi_offset w29, -16
+       stur    wzr, [x29, #-4]
+       mov     x0, #4
+       bl      __cxa_allocate_exception
+       mov     w8, #1
+       str     w8, [x0]
+       adrp    x1, :got:_ZTIi
+       ldr     x1, [x1, :got_lo12:_ZTIi]
+       mov     x2, xzr
+       bl      __cxa_throw
+.main_end:
+       .size   main, .main_end-main
+       .cfi_endproc
+
+       .globl  dup
+       .p2align        2
+       .type   dup,@function
+dup: 
+       .cfi_startproc
+       sub     sp, sp, #32
+       .cfi_def_cfa_offset 32
+       stp     x29, x30, [sp, #16]
+       add     x29, sp, #16
+       .cfi_def_cfa w29, 16
+       .cfi_offset w30, -8
+       .cfi_offset w29, -16
+       stur    wzr, [x29, #-4]
+       mov     x0, #4
+       bl      __cxa_allocate_exception
+       mov     w8, #1
+       str     w8, [x0]
+       adrp    x1, :got:_ZTIi
+       ldr     x1, [x1, :got_lo12:_ZTIi]
+       mov     x2, xzr
+       bl      __cxa_throw
+.dup_end:
+       .size   dup, .dup_end-dup
+       .cfi_endproc
\ No newline at end of file