From 62d6aa025207a032dbf0aef19f9b484926f01398 Mon Sep 17 00:00:00 2001 From: Christian Pirker Date: Wed, 14 May 2014 16:51:58 +0000 Subject: [PATCH] [ARM64-BE] Fix byte order of CIE and FDE frames for exception handling Reviewed at http://reviews.llvm.org/D3741 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@208792 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../ARM64/MCTargetDesc/ARM64AsmBackend.cpp | 17 +++++ test/CodeGen/ARM64/big-endian-eh.ll | 73 +++++++++++++++++++ 2 files changed, 90 insertions(+) create mode 100644 test/CodeGen/ARM64/big-endian-eh.ll diff --git a/lib/Target/ARM64/MCTargetDesc/ARM64AsmBackend.cpp b/lib/Target/ARM64/MCTargetDesc/ARM64AsmBackend.cpp index 73a2afdb477..ba5025ab620 100644 --- a/lib/Target/ARM64/MCTargetDesc/ARM64AsmBackend.cpp +++ b/lib/Target/ARM64/MCTargetDesc/ARM64AsmBackend.cpp @@ -16,6 +16,7 @@ #include "llvm/MC/MCFixupKindInfo.h" #include "llvm/MC/MCObjectWriter.h" #include "llvm/MC/MCSectionMachO.h" +#include "llvm/MC/MCSectionELF.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/MachO.h" using namespace llvm; @@ -500,6 +501,9 @@ public: const MCFixup &Fixup, const MCFragment *DF, const MCValue &Target, uint64_t &Value, bool &IsResolved) override; + + void applyFixup(const MCFixup &Fixup, char *Data, unsigned DataSize, + uint64_t Value, bool IsPCRel) const override; }; void ELFARM64AsmBackend::processFixupValue(const MCAssembler &Asm, @@ -523,6 +527,19 @@ void ELFARM64AsmBackend::processFixupValue(const MCAssembler &Asm, if ((uint32_t)Fixup.getKind() == ARM64::fixup_arm64_pcrel_adrp_imm21) IsResolved = false; } + +void ELFARM64AsmBackend::applyFixup(const MCFixup &Fixup, char *Data, + unsigned DataSize, uint64_t Value, + bool IsPCRel) const { + // store fixups in .eh_frame section in big endian order + if (!IsLittleEndian && Fixup.getKind() == FK_Data_4) { + const MCSection *Sec = Fixup.getValue()->FindAssociatedSection(); + const MCSectionELF *SecELF = static_cast(Sec); + if (SecELF->getSectionName() == ".eh_frame") + Value = ByteSwap_32(unsigned(Value)); + } + ARM64AsmBackend::applyFixup (Fixup, Data, DataSize, Value, IsPCRel); +} } MCAsmBackend *llvm::createARM64leAsmBackend(const Target &T, diff --git a/test/CodeGen/ARM64/big-endian-eh.ll b/test/CodeGen/ARM64/big-endian-eh.ll new file mode 100644 index 00000000000..93e7da98de2 --- /dev/null +++ b/test/CodeGen/ARM64/big-endian-eh.ll @@ -0,0 +1,73 @@ +; RUN: llc -mtriple arm64_be-linux-gnu -filetype obj < %s | llvm-objdump -s - | FileCheck %s + +; ARM EHABI for big endian +; This test case checks whether CIE length record is laid out in big endian format. +; +; This is the LLVM assembly generated from following C++ code: +; +; extern void foo(int); +; void test(int a, int b) { +; try { +; foo(a); +; } catch (...) { +; foo(b); +; } +;} + +define void @_Z4testii(i32 %a, i32 %b) #0 { +entry: + invoke void @_Z3fooi(i32 %a) + to label %try.cont unwind label %lpad + +lpad: ; preds = %entry + %0 = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) + catch i8* null + %1 = extractvalue { i8*, i32 } %0, 0 + %2 = tail call i8* @__cxa_begin_catch(i8* %1) #2 + invoke void @_Z3fooi(i32 %b) + to label %invoke.cont2 unwind label %lpad1 + +invoke.cont2: ; preds = %lpad + tail call void @__cxa_end_catch() + br label %try.cont + +try.cont: ; preds = %entry, %invoke.cont2 + ret void + +lpad1: ; preds = %lpad + %3 = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) + cleanup + invoke void @__cxa_end_catch() + to label %eh.resume unwind label %terminate.lpad + +eh.resume: ; preds = %lpad1 + resume { i8*, i32 } %3 + +terminate.lpad: ; preds = %lpad1 + %4 = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) + catch i8* null + %5 = extractvalue { i8*, i32 } %4, 0 + tail call void @__clang_call_terminate(i8* %5) #3 + unreachable +} + +declare void @_Z3fooi(i32) #0 + +declare i32 @__gxx_personality_v0(...) + +declare i8* @__cxa_begin_catch(i8*) + +declare void @__cxa_end_catch() + +; Function Attrs: noinline noreturn nounwind +define linkonce_odr hidden void @__clang_call_terminate(i8*) #1 { + %2 = tail call i8* @__cxa_begin_catch(i8* %0) #2 + tail call void @_ZSt9terminatev() #3 + unreachable +} + +declare void @_ZSt9terminatev() + +; CHECK-LABEL: Contents of section .eh_frame: +; CHECK-NEXT: 0000 0000001c +