diff options
author | Logan Chien <loganchien@google.com> | 2013-11-05 23:32:49 +0800 |
---|---|---|
committer | Logan Chien <tzuhsiang.chien@gmail.com> | 2013-12-22 22:11:17 +0800 |
commit | 95255f44a51bbd193098dd0f7d9048c1418974cc (patch) | |
tree | d8e2b179a266c6931e9e2e57e61124d6921fc6cd | |
parent | 82d0aac8b0bb085e9d4e9682d45b01bac4994603 (diff) | |
download | llvm-95255f44a51bbd193098dd0f7d9048c1418974cc.tar.gz |
[ndk][mips] Fix MIPS exception personality relocation.
Android MIPS executable loader prohibits the relocation
in the read-only section. Thus, we have to use
DW_EH_PE_indirect instead.
Change-Id: I28d94fb7f4632fc0a630bb503f16431de286801a
-rw-r--r-- | lib/CodeGen/AsmPrinter/DwarfCFIException.cpp | 3 | ||||
-rw-r--r-- | lib/CodeGen/TargetLoweringObjectFileImpl.cpp | 16 | ||||
-rw-r--r-- | lib/MC/MCObjectFileInfo.cpp | 2 | ||||
-rw-r--r-- | test/CodeGen/Mips/ehframe-indirect.ll | 33 |
4 files changed, 45 insertions, 9 deletions
diff --git a/lib/CodeGen/AsmPrinter/DwarfCFIException.cpp b/lib/CodeGen/AsmPrinter/DwarfCFIException.cpp index 8918f3de0a6..40862871b0c 100644 --- a/lib/CodeGen/AsmPrinter/DwarfCFIException.cpp +++ b/lib/CodeGen/AsmPrinter/DwarfCFIException.cpp @@ -59,7 +59,8 @@ void DwarfCFIException::EndModule() { unsigned PerEncoding = TLOF.getPersonalityEncoding(); - if ((PerEncoding & 0x70) != dwarf::DW_EH_PE_pcrel) + if ((PerEncoding & 0x70) != dwarf::DW_EH_PE_pcrel && + (PerEncoding & 0x80) != dwarf::DW_EH_PE_indirect) return; // Emit references to all used personality functions diff --git a/lib/CodeGen/TargetLoweringObjectFileImpl.cpp b/lib/CodeGen/TargetLoweringObjectFileImpl.cpp index 59d7b570375..1fdb8a8a853 100644 --- a/lib/CodeGen/TargetLoweringObjectFileImpl.cpp +++ b/lib/CodeGen/TargetLoweringObjectFileImpl.cpp @@ -48,16 +48,16 @@ TargetLoweringObjectFileELF::getCFIPersonalitySymbol(const GlobalValue *GV, Mangler *Mang, MachineModuleInfo *MMI) const { unsigned Encoding = getPersonalityEncoding(); - switch (Encoding & 0x70) { - default: - report_fatal_error("We do not support this DWARF encoding yet!"); - case dwarf::DW_EH_PE_absptr: - return getSymbol(*Mang, GV); - case dwarf::DW_EH_PE_pcrel: { + + if ((Encoding & 0x70) == dwarf::DW_EH_PE_pcrel || + (Encoding & 0x80) == dwarf::DW_EH_PE_indirect) return getContext().GetOrCreateSymbol(StringRef("DW.ref.") + getSymbol(*Mang, GV)->getName()); - } - } + + if ((Encoding & 0x70) == dwarf::DW_EH_PE_absptr) + return getSymbol(*Mang, GV); + + report_fatal_error("We do not support this DWARF encoding yet!"); } void TargetLoweringObjectFileELF::emitPersonalityValue(MCStreamer &Streamer, diff --git a/lib/MC/MCObjectFileInfo.cpp b/lib/MC/MCObjectFileInfo.cpp index 8ef4a0a6d7b..255b7556d0a 100644 --- a/lib/MC/MCObjectFileInfo.cpp +++ b/lib/MC/MCObjectFileInfo.cpp @@ -326,6 +326,8 @@ void MCObjectFileInfo::InitELFMCObjectFileInfo(Triple T) { FDEEncoding = dwarf::DW_EH_PE_absptr; TTypeEncoding = dwarf::DW_EH_PE_absptr; } + } else if (T.getArch() == Triple::mips || T.getArch() == Triple::mipsel) { + PersonalityEncoding = dwarf::DW_EH_PE_indirect; } // Solaris requires different flags for .eh_frame to seemingly every other diff --git a/test/CodeGen/Mips/ehframe-indirect.ll b/test/CodeGen/Mips/ehframe-indirect.ll new file mode 100644 index 00000000000..db422a73dd2 --- /dev/null +++ b/test/CodeGen/Mips/ehframe-indirect.ll @@ -0,0 +1,33 @@ +; RUN: llc -march=mipsel < %s | FileCheck %s + +define i32 @main() { +; CHECK: .cfi_startproc +; CHECK: .cfi_personality 128, DW.ref.__gxx_personality_v0 + +entry: + invoke void @foo() to label %cont unwind label %lpad +; CHECK: foo +; CHECK: jalr + +lpad: + %0 = landingpad { i8*, i32 } personality i8* + bitcast (i32 (...)* @__gxx_personality_v0 to i8*) catch i8* null + ret i32 0 + +cont: + ret i32 0 +} +; CHECK: .cfi_endproc + +declare i32 @__gxx_personality_v0(...) + +declare void @foo() + +; CHECK: .hidden DW.ref.__gxx_personality_v0 +; CHECK: .weak DW.ref.__gxx_personality_v0 +; CHECK: .section .data.DW.ref.__gxx_personality_v0,"aGw",@progbits,DW.ref.__gxx_personality_v0,comdat +; CHECK: .align 2 +; CHECK: .type DW.ref.__gxx_personality_v0,@object +; CHECK: .size DW.ref.__gxx_personality_v0, 4 +; CHECK: DW.ref.__gxx_personality_v0: +; CHECK: .4byte __gxx_personality_v0 |