diff --git a/llvm/include/llvm/MC/MCELFStreamer.h b/llvm/include/llvm/MC/MCELFStreamer.h --- a/llvm/include/llvm/MC/MCELFStreamer.h +++ b/llvm/include/llvm/MC/MCELFStreamer.h @@ -101,7 +101,7 @@ std::unique_ptr TAB, std::unique_ptr OW, std::unique_ptr Emitter, - bool RelaxAll, bool IsThumb); + bool RelaxAll, bool IsThumb, bool IsAndroid); } // end namespace llvm diff --git a/llvm/lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp b/llvm/lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp --- a/llvm/lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp +++ b/llvm/lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp @@ -441,10 +441,12 @@ friend class ARMTargetELFStreamer; ARMELFStreamer(MCContext &Context, std::unique_ptr TAB, - std::unique_ptr OW, std::unique_ptr Emitter, - bool IsThumb) - : MCELFStreamer(Context, std::move(TAB), std::move(OW), std::move(Emitter)), - IsThumb(IsThumb) { + std::unique_ptr OW, + std::unique_ptr Emitter, bool IsThumb, + bool IsAndroid) + : MCELFStreamer(Context, std::move(TAB), std::move(OW), + std::move(Emitter)), + IsThumb(IsThumb), IsAndroid(IsAndroid) { EHReset(); } @@ -687,6 +689,7 @@ void EmitFixup(const MCExpr *Expr, MCFixupKind Kind); bool IsThumb; + bool IsAndroid; int64_t MappingSymbolCounter = 0; DenseMap> @@ -1269,7 +1272,12 @@ // Emit the exception index table entry SwitchToExIdxSection(*FnStart); - if (PersonalityIndex < ARM::EHABI::NUM_PERSONALITY_INDEX) + // The EHABI requires a dependency preserving R_ARM_NONE relocation to the + // personality routine to protect it from an arbitrary platform's static + // linker garbage collection. We disable this for Android where the unwinder + // is either dynamically linked or directly references the personality + // routine. + if (PersonalityIndex < ARM::EHABI::NUM_PERSONALITY_INDEX && !IsAndroid) EmitPersonalityFixup(GetAEABIUnwindPersonalityName(PersonalityIndex)); const MCSymbolRefExpr *FnStartRef = @@ -1504,9 +1512,11 @@ std::unique_ptr TAB, std::unique_ptr OW, std::unique_ptr Emitter, - bool RelaxAll, bool IsThumb) { - ARMELFStreamer *S = new ARMELFStreamer(Context, std::move(TAB), std::move(OW), - std::move(Emitter), IsThumb); + bool RelaxAll, bool IsThumb, + bool IsAndroid) { + ARMELFStreamer *S = + new ARMELFStreamer(Context, std::move(TAB), std::move(OW), + std::move(Emitter), IsThumb, IsAndroid); // FIXME: This should eventually end up somewhere else where more // intelligent flag decisions can be made. For now we are just maintaining // the status quo for ARM and setting EF_ARM_EABI_VER5 as the default. diff --git a/llvm/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.cpp b/llvm/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.cpp --- a/llvm/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.cpp +++ b/llvm/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.cpp @@ -212,7 +212,8 @@ bool RelaxAll) { return createARMELFStreamer( Ctx, std::move(MAB), std::move(OW), std::move(Emitter), false, - (T.getArch() == Triple::thumb || T.getArch() == Triple::thumbeb)); + (T.getArch() == Triple::thumb || T.getArch() == Triple::thumbeb), + T.isAndroid()); } static MCStreamer * diff --git a/llvm/test/MC/ARM/eh-compact-pr0.s b/llvm/test/MC/ARM/eh-compact-pr0.s --- a/llvm/test/MC/ARM/eh-compact-pr0.s +++ b/llvm/test/MC/ARM/eh-compact-pr0.s @@ -1,7 +1,9 @@ @ RUN: llvm-mc %s -triple=armv7-unknown-linux-gnueabi -filetype=obj -o - \ @ RUN: | llvm-readobj -S --sd --sr > %t @ RUN: FileCheck %s < %t -@ RUN: FileCheck --check-prefix=RELOC %s < %t +@ RUN: FileCheck --check-prefixes=RELOC,RELOC-NOAND %s < %t +@ RUN: llvm-mc %s -triple=armv7-unknown-linux-androideabi -filetype=obj -o - \ +@ RUN: | llvm-readobj -S --sd --sr | FileCheck --check-prefix=RELOC %s @ Check the compact pr0 model @@ -61,18 +63,16 @@ @ CHECK: ) @ CHECK: } @------------------------------------------------------------------------------- -@ The first word should be relocated to .TEST1 section. Besides, there is -@ another relocation entry for __aeabi_unwind_cpp_pr0, so that the linker -@ will keep __aeabi_unwind_cpp_pr0. -@------------------------------------------------------------------------------- -@ RELOC: Section { -@ RELOC: Name: .rel.ARM.exidx.TEST1 -@ RELOC: Relocations [ -@ RELOC: 0x0 R_ARM_NONE __aeabi_unwind_cpp_pr0 0x0 -@ RELOC: 0x0 R_ARM_PREL31 .TEST1 0x0 -@ RELOC: ] -@ RELOC: } - +@ The first word should be relocated to .TEST1 section. Besides, on non-Android +@ there is another relocation entry for __aeabi_unwind_cpp_pr0, so that the +@ linker will keep __aeabi_unwind_cpp_pr0. +@------------------------------------------------------------------------------- +@ RELOC: Section { +@ RELOC: Name: .rel.ARM.exidx.TEST1 +@ RELOC: Relocations [ +@ RELOC-NOAND-NEXT: 0x0 R_ARM_NONE __aeabi_unwind_cpp_pr0 0x0 +@ RELOC-NEXT: 0x0 R_ARM_PREL31 .TEST1 0x0 +@ RELOC-NEXT: ] @------------------------------------------------------------------------------- @ Check .TEST2 section @@ -98,14 +98,13 @@ @ CHECK: ) @ CHECK: } @------------------------------------------------------------------------------- -@ The first word should be relocated to .TEST2 section. Besides, there is -@ another relocation entry for __aeabi_unwind_cpp_pr0, so that the linker -@ will keep __aeabi_unwind_cpp_pr0. -@------------------------------------------------------------------------------- -@ RELOC: Section { -@ RELOC: Name: .rel.ARM.exidx.TEST2 -@ RELOC: Relocations [ -@ RELOC: 0x0 R_ARM_NONE __aeabi_unwind_cpp_pr0 0x0 -@ RELOC: 0x0 R_ARM_PREL31 .TEST2 0x0 -@ RELOC: ] -@ RELOC: } +@ The first word should be relocated to .TEST2 section. Besides, on non-Android +@ there is another relocation entry for __aeabi_unwind_cpp_pr0, so that the +@ linker will keep __aeabi_unwind_cpp_pr0. +@------------------------------------------------------------------------------- +@ RELOC: Section { +@ RELOC: Name: .rel.ARM.exidx.TEST2 +@ RELOC: Relocations [ +@ RELOC-NOAND-NEXT: 0x0 R_ARM_NONE __aeabi_unwind_cpp_pr0 0x0 +@ RELOC-NEXT: 0x0 R_ARM_PREL31 .TEST2 0x0 +@ RELOC-NEXT: ]