summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/Target/Mips/MCTargetDesc/MipsELFStreamer.cpp17
-rw-r--r--lib/Target/Mips/MCTargetDesc/MipsELFStreamer.h7
-rw-r--r--test/DebugInfo/Mips/eh_frame.ll38
3 files changed, 62 insertions, 0 deletions
diff --git a/lib/Target/Mips/MCTargetDesc/MipsELFStreamer.cpp b/lib/Target/Mips/MCTargetDesc/MipsELFStreamer.cpp
index 7b9a02503ce..21b01e85096 100644
--- a/lib/Target/Mips/MCTargetDesc/MipsELFStreamer.cpp
+++ b/lib/Target/Mips/MCTargetDesc/MipsELFStreamer.cpp
@@ -15,6 +15,7 @@
#include "llvm/MC/MCAssembler.h"
#include "llvm/MC/MCCodeEmitter.h"
#include "llvm/MC/MCContext.h"
+#include "llvm/MC/MCDwarf.h"
#include "llvm/MC/MCInst.h"
#include "llvm/MC/MCObjectWriter.h"
#include "llvm/MC/MCSymbolELF.h"
@@ -53,6 +54,22 @@ void MipsELFStreamer::EmitInstruction(const MCInst &Inst,
createPendingLabelRelocs();
}
+void MipsELFStreamer::EmitCFIStartProcImpl(MCDwarfFrameInfo &Frame) {
+ Frame.Begin = getContext().createTempSymbol();
+ MCELFStreamer::EmitLabel(Frame.Begin);
+}
+
+MCSymbol *MipsELFStreamer::EmitCFILabel() {
+ MCSymbol *Label = getContext().createTempSymbol("cfi", true);
+ MCELFStreamer::EmitLabel(Label);
+ return Label;
+}
+
+void MipsELFStreamer::EmitCFIEndProcImpl(MCDwarfFrameInfo &Frame) {
+ Frame.End = getContext().createTempSymbol();
+ MCELFStreamer::EmitLabel(Frame.End);
+}
+
void MipsELFStreamer::createPendingLabelRelocs() {
MipsTargetELFStreamer *ELFTargetStreamer =
static_cast<MipsTargetELFStreamer *>(getTargetStreamer());
diff --git a/lib/Target/Mips/MCTargetDesc/MipsELFStreamer.h b/lib/Target/Mips/MCTargetDesc/MipsELFStreamer.h
index d141f5d77c6..56a0ff96c7b 100644
--- a/lib/Target/Mips/MCTargetDesc/MipsELFStreamer.h
+++ b/lib/Target/Mips/MCTargetDesc/MipsELFStreamer.h
@@ -26,6 +26,7 @@ class MCAsmBackend;
class MCCodeEmitter;
class MCContext;
class MCSubtargetInfo;
+struct MCDwarfFrameInfo;
class MipsELFStreamer : public MCELFStreamer {
SmallVector<std::unique_ptr<MipsOptionRecord>, 8> MipsOptionRecords;
@@ -60,6 +61,12 @@ public:
void EmitValueImpl(const MCExpr *Value, unsigned Size, SMLoc Loc) override;
void EmitIntValue(uint64_t Value, unsigned Size) override;
+ // Overriding these functions allows us to avoid recording of these labels
+ // in EmitLabel and later marking them as microMIPS.
+ void EmitCFIStartProcImpl(MCDwarfFrameInfo &Frame) override;
+ void EmitCFIEndProcImpl(MCDwarfFrameInfo &Frame) override;
+ MCSymbol *EmitCFILabel() override;
+
/// Emits all the option records stored up until the point it's called.
void EmitMipsOptionRecords();
diff --git a/test/DebugInfo/Mips/eh_frame.ll b/test/DebugInfo/Mips/eh_frame.ll
new file mode 100644
index 00000000000..4687443cb1c
--- /dev/null
+++ b/test/DebugInfo/Mips/eh_frame.ll
@@ -0,0 +1,38 @@
+; RUN: llc -mtriple mips-unknown-linux-gnu -mattr=+micromips -O3 -filetype=obj -o - %s | llvm-readelf -r | FileCheck %s
+
+; CHECK: .rel.eh_frame
+; CHECK: DW.ref.__gxx_personality_v0
+; CHECK-NEXT: .text
+; CHECK-NEXT: .gcc_except_table
+
+@_ZTIi = external constant i8*
+
+define dso_local i32 @main() local_unnamed_addr personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) {
+entry:
+ %exception.i = tail call i8* @__cxa_allocate_exception(i32 4) nounwind
+ %0 = bitcast i8* %exception.i to i32*
+ store i32 5, i32* %0, align 16
+ invoke void @__cxa_throw(i8* %exception.i, i8* bitcast (i8** @_ZTIi to i8*), i8* null) noreturn
+ to label %.noexc unwind label %return
+
+.noexc:
+ unreachable
+
+return:
+ %1 = landingpad { i8*, i32 }
+ catch i8* null
+ %2 = extractvalue { i8*, i32 } %1, 0
+ %3 = tail call i8* @__cxa_begin_catch(i8* %2) nounwind
+ tail call void @__cxa_end_catch()
+ ret i32 0
+}
+
+declare i32 @__gxx_personality_v0(...)
+
+declare i8* @__cxa_begin_catch(i8*) local_unnamed_addr
+
+declare void @__cxa_end_catch() local_unnamed_addr
+
+declare i8* @__cxa_allocate_exception(i32) local_unnamed_addr
+
+declare void @__cxa_throw(i8*, i8*, i8*) local_unnamed_addr