summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp16
-rw-r--r--llvm/test/MC/ARM/eh-compact-pr1.s2
2 files changed, 14 insertions, 4 deletions
diff --git a/llvm/lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp b/llvm/lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp
index dc3d9456569..e8b6a5abf15 100644
--- a/llvm/lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp
+++ b/llvm/lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp
@@ -204,7 +204,7 @@ private:
void EmitPersonalityFixup(StringRef Name);
void FlushPendingOffset();
- void FlushUnwindOpcodes(bool AllowCompactModel0);
+ void FlushUnwindOpcodes(bool NoHandlerData);
void SwitchToEHSection(const char *Prefix, unsigned Type, unsigned Flags,
SectionKind Kind, const MCSymbol &Fn);
@@ -377,7 +377,7 @@ void ARMELFStreamer::FlushPendingOffset() {
}
}
-void ARMELFStreamer::FlushUnwindOpcodes(bool AllowCompactModel0) {
+void ARMELFStreamer::FlushUnwindOpcodes(bool NoHandlerData) {
// Emit the unwind opcode to restore $sp.
if (UsedFP) {
const MCRegisterInfo *MRI = getContext().getRegisterInfo();
@@ -394,7 +394,7 @@ void ARMELFStreamer::FlushUnwindOpcodes(bool AllowCompactModel0) {
// For compact model 0, we have to emit the unwind opcodes in the .ARM.exidx
// section. Thus, we don't have to create an entry in the .ARM.extab
// section.
- if (AllowCompactModel0 && PersonalityIndex == AEABI_UNWIND_CPP_PR0)
+ if (NoHandlerData && PersonalityIndex == AEABI_UNWIND_CPP_PR0)
return;
// Switch to .ARM.extab section.
@@ -418,6 +418,16 @@ void ARMELFStreamer::FlushUnwindOpcodes(bool AllowCompactModel0) {
// Emit unwind opcodes
EmitBytes(StringRef(reinterpret_cast<const char *>(Opcodes.data()),
Opcodes.size()), 0);
+
+ // According to ARM EHABI section 9.2, if the __aeabi_unwind_cpp_pr1() or
+ // __aeabi_unwind_cpp_pr2() is used, then the handler data must be emitted
+ // after the unwind opcodes. The handler data consists of several 32-bit
+ // words, and should be terminated by zero.
+ //
+ // In case that the .handlerdata directive is not specified by the
+ // programmer, we should emit zero to terminate the handler data.
+ if (NoHandlerData && !Personality)
+ EmitIntValue(0, 4);
}
void ARMELFStreamer::EmitHandlerData() {
diff --git a/llvm/test/MC/ARM/eh-compact-pr1.s b/llvm/test/MC/ARM/eh-compact-pr1.s
index 41971d0c443..17d32f834e3 100644
--- a/llvm/test/MC/ARM/eh-compact-pr1.s
+++ b/llvm/test/MC/ARM/eh-compact-pr1.s
@@ -46,7 +46,7 @@ func1:
@ 0xB0 = finish
@-------------------------------------------------------------------------------
@ CHECK: SectionData (
-@ CHECK: 0000: 419B0181 B0B08384 |A.......|
+@ CHECK: 0000: 419B0181 B0B08384 00000000 |A...........|
@ CHECK: )
@ CHECK: }
OpenPOWER on IntegriCloud