From c24a374331fc97dd215937c8f0a9bf5271f39657 Mon Sep 17 00:00:00 2001 From: Logan Chien Date: Fri, 10 May 2013 16:17:24 +0000 Subject: Implement AsmParser for ARM unwind directives. This commit implements the AsmParser for fnstart, fnend, cantunwind, personality, handlerdata, pad, setfp, save, and vsave directives. This commit fixes some minor issue in the ARMELFStreamer: * The switch back to corresponding section after the .fnend directive. * Emit the unwind opcode while processing .fnend directive if there is no .handlerdata directive. * Emit the unwind opcode to .ARM.extab while processing .handlerdata even if .personality directive does not exist. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@181603 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp | 56 ++++++++++++++------------ 1 file changed, 30 insertions(+), 26 deletions(-) (limited to 'lib/Target/ARM/MCTargetDesc') diff --git a/lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp b/lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp index 6c3d247..82d296f 100644 --- a/lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp +++ b/lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp @@ -204,6 +204,7 @@ private: void EmitPersonalityFixup(StringRef Name); void CollectUnwindOpcodes(); + void FlushUnwindOpcodes(bool AllowCompactModel0); void SwitchToEHSection(const char *Prefix, unsigned Type, unsigned Flags, SectionKind Kind, const MCSymbol &Fn); @@ -333,22 +334,8 @@ void ARMELFStreamer::EmitFnEnd() { assert(FnStart && ".fnstart must preceeds .fnend"); // Emit unwind opcodes if there is no .handlerdata directive - if (!ExTab && !CantUnwind) { - CollectUnwindOpcodes(); - - unsigned PersonalityIndex = UnwindOpAsm.getPersonalityIndex(); - if (PersonalityIndex == AEABI_UNWIND_CPP_PR1 || - PersonalityIndex == AEABI_UNWIND_CPP_PR2) { - // For the __aeabi_unwind_cpp_pr1 and __aeabi_unwind_cpp_pr2, we have to - // emit the unwind opcodes in the corresponding ".ARM.extab" section, and - // then emit a reference to these unwind opcodes in the second word of - // the exception index table entry. - SwitchToExTabSection(*FnStart); - ExTab = getContext().CreateTempSymbol(); - EmitLabel(ExTab); - EmitBytes(UnwindOpAsm.data(), 0); - } - } + if (!ExTab && !CantUnwind) + FlushUnwindOpcodes(true); // Emit the exception index table entry SwitchToExIdxSection(*FnStart); @@ -384,6 +371,9 @@ void ARMELFStreamer::EmitFnEnd() { EmitBytes(UnwindOpAsm.data(), 0); } + // Switch to the section containing FnStart + SwitchSection(&FnStart->getSection()); + // Clean exception handling frame information Reset(); } @@ -392,7 +382,18 @@ void ARMELFStreamer::EmitCantUnwind() { CantUnwind = true; } -void ARMELFStreamer::EmitHandlerData() { +void ARMELFStreamer::FlushUnwindOpcodes(bool AllowCompactModel0) { + // Collect and finalize the unwind opcodes + CollectUnwindOpcodes(); + + // 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 && + UnwindOpAsm.getPersonalityIndex() == AEABI_UNWIND_CPP_PR0) + return; + + // Switch to .ARM.extab section. SwitchToExTabSection(*FnStart); // Create .ARM.extab label for offset in .ARM.exidx @@ -400,21 +401,24 @@ void ARMELFStreamer::EmitHandlerData() { ExTab = getContext().CreateTempSymbol(); EmitLabel(ExTab); - // Emit Personality - assert(Personality && ".personality directive must preceed .handlerdata"); - - const MCSymbolRefExpr *PersonalityRef = - MCSymbolRefExpr::Create(Personality, - MCSymbolRefExpr::VK_ARM_PREL31, - getContext()); + // Emit personality + if (Personality) { + const MCSymbolRefExpr *PersonalityRef = + MCSymbolRefExpr::Create(Personality, + MCSymbolRefExpr::VK_ARM_PREL31, + getContext()); - EmitValue(PersonalityRef, 4, 0); + EmitValue(PersonalityRef, 4, 0); + } // Emit unwind opcodes - CollectUnwindOpcodes(); EmitBytes(UnwindOpAsm.data(), 0); } +void ARMELFStreamer::EmitHandlerData() { + FlushUnwindOpcodes(false); +} + void ARMELFStreamer::EmitPersonality(const MCSymbol *Per) { Personality = Per; UnwindOpAsm.setPersonality(Per); -- cgit v1.1