[llvm] 1549b46 - ARM: Don't emit R_ARM_NONE relocations to compact unwinding decoders in .ARM.exidx on Android.

Peter Collingbourne via llvm-commits llvm-commits at lists.llvm.org
Tue Nov 12 10:53:42 PST 2019


Author: Peter Collingbourne
Date: 2019-11-12T10:52:59-08:00
New Revision: 1549b4699a84838c3969590dc4f757b72f39f40d

URL: https://github.com/llvm/llvm-project/commit/1549b4699a84838c3969590dc4f757b72f39f40d
DIFF: https://github.com/llvm/llvm-project/commit/1549b4699a84838c3969590dc4f757b72f39f40d.diff

LOG: ARM: Don't emit R_ARM_NONE relocations to compact unwinding decoders in .ARM.exidx on Android.

These relocations are specified by the ARM EHABI (section 6.3). As I understand
it, their purpose is to accommodate unwinder implementations that wish to
reduce code size by placing the implementations of the compact unwinding
decoders in a separate translation unit, and using extern weak symbols to
refer to them from the main unwinder implementation, so that they are only
linked when something in the binary needs them in order to unwind.

However, neither of the unwinders used on Android (libgcc, LLVM libunwind)
use this technique, and in fact emitting these relocations ends up being
counterproductive to code size because they cause a copy of the unwinder
to be statically linked into most binaries, regardless of whether it is
actually needed. Furthermore, these relocations create circular dependencies
(between libc and the unwinder) in cases where the unwinder is dynamically
linked and libc contains compact unwind info.

Therefore, deviate from the EHABI here and stop emitting these relocations
on Android.

Differential Revision: https://reviews.llvm.org/D70027

Added: 
    

Modified: 
    llvm/include/llvm/MC/MCELFStreamer.h
    llvm/lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp
    llvm/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.cpp
    llvm/test/MC/ARM/eh-compact-pr0.s

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm/MC/MCELFStreamer.h b/llvm/include/llvm/MC/MCELFStreamer.h
index 8838d53d75b5..cc90b8b20a73 100644
--- a/llvm/include/llvm/MC/MCELFStreamer.h
+++ b/llvm/include/llvm/MC/MCELFStreamer.h
@@ -101,7 +101,7 @@ MCELFStreamer *createARMELFStreamer(MCContext &Context,
                                     std::unique_ptr<MCAsmBackend> TAB,
                                     std::unique_ptr<MCObjectWriter> OW,
                                     std::unique_ptr<MCCodeEmitter> 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
index f51fbdcd84da..01b98ccf8970 100644
--- a/llvm/lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp
+++ b/llvm/lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp
@@ -441,10 +441,12 @@ class ARMELFStreamer : public MCELFStreamer {
   friend class ARMTargetELFStreamer;
 
   ARMELFStreamer(MCContext &Context, std::unique_ptr<MCAsmBackend> TAB,
-                 std::unique_ptr<MCObjectWriter> OW, std::unique_ptr<MCCodeEmitter> Emitter,
-                 bool IsThumb)
-      : MCELFStreamer(Context, std::move(TAB), std::move(OW), std::move(Emitter)),
-        IsThumb(IsThumb) {
+                 std::unique_ptr<MCObjectWriter> OW,
+                 std::unique_ptr<MCCodeEmitter> 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 @@ class ARMELFStreamer : public MCELFStreamer {
   void EmitFixup(const MCExpr *Expr, MCFixupKind Kind);
 
   bool IsThumb;
+  bool IsAndroid;
   int64_t MappingSymbolCounter = 0;
 
   DenseMap<const MCSection *, std::unique_ptr<ElfMappingSymbolInfo>>
@@ -1269,7 +1272,12 @@ void ARMELFStreamer::emitFnEnd() {
   // 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 @@ MCELFStreamer *createARMELFStreamer(MCContext &Context,
                                     std::unique_ptr<MCAsmBackend> TAB,
                                     std::unique_ptr<MCObjectWriter> OW,
                                     std::unique_ptr<MCCodeEmitter> 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
index b546335efb9e..6c86550b1a4d 100644
--- a/llvm/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.cpp
+++ b/llvm/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.cpp
@@ -212,7 +212,8 @@ static MCStreamer *createELFStreamer(const Triple &T, MCContext &Ctx,
                                      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
index c018c94bf4d3..ac4aa2c2727b 100644
--- 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 @@ func2:
 @ 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.
- at -------------------------------------------------------------------------------
-@ 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.
+ at -------------------------------------------------------------------------------
+@ 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 @@ func2:
 @ 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.
- at -------------------------------------------------------------------------------
-@ 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.
+ at -------------------------------------------------------------------------------
+@ 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:     ]


        


More information about the llvm-commits mailing list