aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLogan Chien <loganchien@google.com>2013-11-05 23:32:49 +0800
committerLogan Chien <tzuhsiang.chien@gmail.com>2013-12-22 22:11:17 +0800
commit95255f44a51bbd193098dd0f7d9048c1418974cc (patch)
treed8e2b179a266c6931e9e2e57e61124d6921fc6cd
parent82d0aac8b0bb085e9d4e9682d45b01bac4994603 (diff)
downloadllvm-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.cpp3
-rw-r--r--lib/CodeGen/TargetLoweringObjectFileImpl.cpp16
-rw-r--r--lib/MC/MCObjectFileInfo.cpp2
-rw-r--r--test/CodeGen/Mips/ehframe-indirect.ll33
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