aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/MC/MCAsmBackend.cpp11
-rw-r--r--llvm/lib/MC/MCContext.cpp6
-rw-r--r--llvm/lib/MC/MCStreamer.cpp2
-rw-r--r--llvm/lib/MC/MCTargetOptionsCommandFlags.cpp10
-rw-r--r--llvm/lib/Target/AArch64/MCTargetDesc/AArch64AsmBackend.cpp8
-rw-r--r--llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp7
-rw-r--r--llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackendDarwin.h5
-rw-r--r--llvm/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp8
8 files changed, 49 insertions, 8 deletions
diff --git a/llvm/lib/MC/MCAsmBackend.cpp b/llvm/lib/MC/MCAsmBackend.cpp
index c4e5051..cf3b3ae 100644
--- a/llvm/lib/MC/MCAsmBackend.cpp
+++ b/llvm/lib/MC/MCAsmBackend.cpp
@@ -115,3 +115,14 @@ bool MCAsmBackend::fixupNeedsRelaxationAdvanced(
return true;
return fixupNeedsRelaxation(Fixup, Value, DF, Layout);
}
+
+bool MCAsmBackend::isDarwinCanonicalPersonality(const MCSymbol *Sym) const {
+ if (Sym && Sym->isMachO()) {
+ StringRef name = Sym->getName();
+ // XXX: We intentionally leave out "___gcc_personality_v0" because, despite
+ // being system-defined like these two, it is not very commonly-used.
+ // Reserving an empty slot for it seems silly.
+ return name == "___gxx_personality_v0" || name == "___objc_personality_v0";
+ }
+ return false;
+}
diff --git a/llvm/lib/MC/MCContext.cpp b/llvm/lib/MC/MCContext.cpp
index f84aa4a..80d593b 100644
--- a/llvm/lib/MC/MCContext.cpp
+++ b/llvm/lib/MC/MCContext.cpp
@@ -922,6 +922,12 @@ EmitDwarfUnwindType MCContext::emitDwarfUnwindInfo() const {
return TargetOptions->EmitDwarfUnwind;
}
+bool MCContext::emitCompactUnwindNonCanonical() const {
+ if (TargetOptions)
+ return TargetOptions->EmitCompactUnwindNonCanonical;
+ return false;
+}
+
void MCContext::setGenDwarfRootFile(StringRef InputFileName, StringRef Buffer) {
// MCDwarf needs the root file as well as the compilation directory.
// If we find a '.file 0' directive that will supersede these values.
diff --git a/llvm/lib/MC/MCStreamer.cpp b/llvm/lib/MC/MCStreamer.cpp
index 0cb0459..c0e9f42 100644
--- a/llvm/lib/MC/MCStreamer.cpp
+++ b/llvm/lib/MC/MCStreamer.cpp
@@ -126,7 +126,7 @@ void MCStreamer::emitExplicitComments() {}
void MCStreamer::generateCompactUnwindEncodings(MCAsmBackend *MAB) {
for (auto &FI : DwarfFrameInfos)
FI.CompactUnwindEncoding =
- (MAB ? MAB->generateCompactUnwindEncoding(FI.Instructions) : 0);
+ (MAB ? MAB->generateCompactUnwindEncoding(&FI, &Context) : 0);
}
/// EmitIntValue - Special case of EmitValue that avoids the client having to
diff --git a/llvm/lib/MC/MCTargetOptionsCommandFlags.cpp b/llvm/lib/MC/MCTargetOptionsCommandFlags.cpp
index 0667ca5..8a4923e 100644
--- a/llvm/lib/MC/MCTargetOptionsCommandFlags.cpp
+++ b/llvm/lib/MC/MCTargetOptionsCommandFlags.cpp
@@ -39,6 +39,7 @@ MCOPT(bool, IncrementalLinkerCompatible)
MCOPT(int, DwarfVersion)
MCOPT(bool, Dwarf64)
MCOPT(EmitDwarfUnwindType, EmitDwarfUnwind)
+MCOPT(bool, EmitCompactUnwindNonCanonical)
MCOPT(bool, ShowMCInst)
MCOPT(bool, FatalWarnings)
MCOPT(bool, NoWarn)
@@ -87,6 +88,14 @@ llvm::mc::RegisterMCTargetOptionsFlags::RegisterMCTargetOptionsFlags() {
"Use target platform default")));
MCBINDOPT(EmitDwarfUnwind);
+ static cl::opt<bool> EmitCompactUnwindNonCanonical(
+ "emit-compact-unwind-non-canonical",
+ cl::desc(
+ "Whether to try to emit Compact Unwind for non canonical entries."),
+ cl::init(
+ false)); // By default, use DWARF for non-canonical personalities.
+ MCBINDOPT(EmitCompactUnwindNonCanonical);
+
static cl::opt<bool> ShowMCInst(
"asm-show-inst",
cl::desc("Emit internal instruction representation to assembly file"));
@@ -135,6 +144,7 @@ MCTargetOptions llvm::mc::InitMCTargetOptionsFromFlags() {
Options.MCNoDeprecatedWarn = getNoDeprecatedWarn();
Options.MCNoTypeCheck = getNoTypeCheck();
Options.EmitDwarfUnwind = getEmitDwarfUnwind();
+ Options.EmitCompactUnwindNonCanonical = getEmitCompactUnwindNonCanonical();
Options.AsSecureLogFile = getAsSecureLogFile();
return Options;
diff --git a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64AsmBackend.cpp b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64AsmBackend.cpp
index 2089a24..7f20d73 100644
--- a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64AsmBackend.cpp
+++ b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64AsmBackend.cpp
@@ -564,10 +564,14 @@ public:
}
/// Generate the compact unwind encoding from the CFI directives.
- uint32_t generateCompactUnwindEncoding(
- ArrayRef<MCCFIInstruction> Instrs) const override {
+ uint32_t generateCompactUnwindEncoding(const MCDwarfFrameInfo *FI,
+ const MCContext *Ctxt) const override {
+ ArrayRef<MCCFIInstruction> Instrs = FI->Instructions;
if (Instrs.empty())
return CU::UNWIND_ARM64_MODE_FRAMELESS;
+ if (!isDarwinCanonicalPersonality(FI->Personality) &&
+ !Ctxt->emitCompactUnwindNonCanonical())
+ return CU::UNWIND_ARM64_MODE_DWARF;
bool HasFP = false;
unsigned StackSize = 0;
diff --git a/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp b/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp
index df142b8..ea13634 100644
--- a/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp
+++ b/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp
@@ -1107,14 +1107,19 @@ enum CompactUnwindEncodings {
/// encoded in compact unwind, the method returns UNWIND_ARM_MODE_DWARF which
/// tells the runtime to fallback and unwind using dwarf.
uint32_t ARMAsmBackendDarwin::generateCompactUnwindEncoding(
- ArrayRef<MCCFIInstruction> Instrs) const {
+ const MCDwarfFrameInfo *FI, const MCContext *Ctxt) const {
DEBUG_WITH_TYPE("compact-unwind", llvm::dbgs() << "generateCU()\n");
// Only armv7k uses CFI based unwinding.
if (Subtype != MachO::CPU_SUBTYPE_ARM_V7K)
return 0;
// No .cfi directives means no frame.
+ ArrayRef<MCCFIInstruction> Instrs = FI->Instructions;
if (Instrs.empty())
return 0;
+ if (!isDarwinCanonicalPersonality(FI->Personality) &&
+ !Ctxt->emitCompactUnwindNonCanonical())
+ return CU::UNWIND_ARM_MODE_DWARF;
+
// Start off assuming CFA is at SP+0.
unsigned CFARegister = ARM::SP;
int CFARegisterOffset = 0;
diff --git a/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackendDarwin.h b/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackendDarwin.h
index 85013b5..ace573c 100644
--- a/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackendDarwin.h
+++ b/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackendDarwin.h
@@ -11,6 +11,7 @@
#include "ARMAsmBackend.h"
#include "llvm/BinaryFormat/MachO.h"
+#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCObjectWriter.h"
namespace llvm {
@@ -32,8 +33,8 @@ public:
/*Is64Bit=*/false, cantFail(MachO::getCPUType(TT)), Subtype);
}
- uint32_t generateCompactUnwindEncoding(
- ArrayRef<MCCFIInstruction> Instrs) const override;
+ uint32_t generateCompactUnwindEncoding(const MCDwarfFrameInfo *FI,
+ const MCContext *Ctxt) const override;
};
} // end namespace llvm
diff --git a/llvm/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp b/llvm/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp
index 92344d4..8380f00 100644
--- a/llvm/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp
+++ b/llvm/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp
@@ -1327,9 +1327,13 @@ public:
/// Implementation of algorithm to generate the compact unwind encoding
/// for the CFI instructions.
- uint32_t
- generateCompactUnwindEncoding(ArrayRef<MCCFIInstruction> Instrs) const override {
+ uint32_t generateCompactUnwindEncoding(const MCDwarfFrameInfo *FI,
+ const MCContext *Ctxt) const override {
+ ArrayRef<MCCFIInstruction> Instrs = FI->Instructions;
if (Instrs.empty()) return 0;
+ if (!isDarwinCanonicalPersonality(FI->Personality) &&
+ !Ctxt->emitCompactUnwindNonCanonical())
+ return CU::UNWIND_MODE_DWARF;
// Reset the saved registers.
unsigned SavedRegIdx = 0;