[lld] r319169 - [ELF] Read ARM BuildAttributes section to determine supported features.

Peter Smith via llvm-commits llvm-commits at lists.llvm.org
Tue Nov 28 05:51:49 PST 2017


Author: psmith
Date: Tue Nov 28 05:51:48 2017
New Revision: 319169

URL: http://llvm.org/viewvc/llvm-project?rev=319169&view=rev
Log:
[ELF] Read ARM BuildAttributes section to determine supported features.

lld assumes some ARM features that are not available in all Arm
processors. In particular:
- The blx instruction present for interworking.
- The movt/movw instructions are used in Thunks.
- The J1=1 J2=1 encoding of branch immediates to improve Thumb wide
  branch range are assumed to be present.

This patch reads the ARM Attributes section to check for the
architecture the object file was compiled with. If none of the objects
have an architecture that supports either of these features a warning
will be given. This is most likely to affect armv6 as used in the first
Raspberry Pi.

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

Added:
    lld/trunk/test/ELF/arm-bl-v6.s
    lld/trunk/test/ELF/arm-blx-v4t.s
Modified:
    lld/trunk/ELF/Config.h
    lld/trunk/ELF/Driver.cpp
    lld/trunk/ELF/InputFiles.cpp

Modified: lld/trunk/ELF/Config.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Config.h?rev=319169&r1=319168&r2=319169&view=diff
==============================================================================
--- lld/trunk/ELF/Config.h (original)
+++ lld/trunk/ELF/Config.h Tue Nov 28 05:51:48 2017
@@ -105,6 +105,9 @@ struct Configuration {
   std::vector<uint8_t> BuildIdVector;
   bool AllowMultipleDefinition;
   bool AndroidPackDynRelocs = false;
+  bool ARMHasBlx = false;
+  bool ARMHasMovtMovw = false;
+  bool ARMJ1J2BranchEncoding = false;
   bool AsNeeded = false;
   bool Bsymbolic;
   bool BsymbolicFunctions;

Modified: lld/trunk/ELF/Driver.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Driver.cpp?rev=319169&r1=319168&r2=319169&view=diff
==============================================================================
--- lld/trunk/ELF/Driver.cpp (original)
+++ lld/trunk/ELF/Driver.cpp Tue Nov 28 05:51:48 2017
@@ -1118,6 +1118,21 @@ template <class ELFT> void LinkerDriver:
 
   Config->EFlags = Target->calcEFlags();
 
+  if (Config->EMachine == EM_ARM) {
+    // FIXME: These warnings can be removed when lld only uses these features
+    // when the input objects have been compiled with an architecture that
+    // supports them.
+    if (Config->ARMHasBlx == false)
+      warn("lld uses blx instruction, no object with architecture supporting "
+           "feature detected.");
+    if (Config->ARMJ1J2BranchEncoding == false)
+      warn("lld uses extended branch encoding, no object with architecture "
+           "supporting feature detected.");
+    if (Config->ARMHasMovtMovw == false)
+      warn("lld may use movt/movw, no object with architecture supporting "
+           "feature detected.");
+  }
+
   // This adds a .comment section containing a version string. We have to add it
   // before decompressAndMergeSections because the .comment section is a
   // mergeable section.

Modified: lld/trunk/ELF/InputFiles.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputFiles.cpp?rev=319169&r1=319168&r2=319169&view=diff
==============================================================================
--- lld/trunk/ELF/InputFiles.cpp (original)
+++ lld/trunk/ELF/InputFiles.cpp Tue Nov 28 05:51:48 2017
@@ -23,6 +23,8 @@
 #include "llvm/LTO/LTO.h"
 #include "llvm/MC/StringTableBuilder.h"
 #include "llvm/Object/ELFObjectFile.h"
+#include "llvm/Support/ARMAttributeParser.h"
+#include "llvm/Support/ARMBuildAttributes.h"
 #include "llvm/Support/Path.h"
 #include "llvm/Support/TarWriter.h"
 #include "llvm/Support/raw_ostream.h"
@@ -394,6 +396,48 @@ void ObjFile<ELFT>::initializeSections(
   }
 }
 
+// The ARM support in lld makes some use of instructions that are not available
+// on all ARM architectures. Namely:
+// - Use of BLX instruction for interworking between ARM and Thumb state.
+// - Use of the extended Thumb branch encoding in relocation.
+// - Use of the MOVT/MOVW instructions in Thumb Thunks.
+// The ARM Attributes section contains information about the architecture chosen
+// at compile time. We follow the convention that if at least one input object
+// is compiled with an architecture that supports these features then lld is
+// permitted to use them.
+static void updateSupportedARMFeatures(const ARMAttributeParser &Attributes) {
+  if (!Attributes.hasAttribute(ARMBuildAttrs::CPU_arch))
+    return;
+  auto Arch = Attributes.getAttributeValue(ARMBuildAttrs::CPU_arch);
+  switch (Arch) {
+  case ARMBuildAttrs::Pre_v4:
+  case ARMBuildAttrs::v4:
+  case ARMBuildAttrs::v4T:
+    // Architectures prior to v5 do not support BLX instruction
+    break;
+  case ARMBuildAttrs::v5T:
+  case ARMBuildAttrs::v5TE:
+  case ARMBuildAttrs::v5TEJ:
+  case ARMBuildAttrs::v6:
+  case ARMBuildAttrs::v6KZ:
+  case ARMBuildAttrs::v6K:
+    Config->ARMHasBlx = true;
+    // Architectures used in pre-Cortex processors do not support
+    // The J1 = 1 J2 = 1 Thumb branch range extension, with the exception
+    // of Architecture v6T2 (arm1156t2-s and arm1156t2f-s) that do.
+    break;
+  default:
+    // All other Architectures have BLX and extended branch encoding
+    Config->ARMHasBlx = true;
+    Config->ARMJ1J2BranchEncoding = true;
+    if (Arch != ARMBuildAttrs::v6_M && Arch != ARMBuildAttrs::v6S_M)
+      // All Architectures used in Cortex processors with the exception
+      // of v6-M and v6S-M have the MOVT and MOVW instructions.
+      Config->ARMHasMovtMovw = true;
+    break;
+  }
+}
+
 template <class ELFT>
 InputSectionBase *ObjFile<ELFT>::getRelocTarget(const Elf_Shdr &Sec) {
   uint32_t Idx = Sec.sh_info;
@@ -426,16 +470,20 @@ InputSectionBase *ObjFile<ELFT>::createI
   StringRef Name = getSectionName(Sec);
 
   switch (Sec.sh_type) {
-  case SHT_ARM_ATTRIBUTES:
-    // FIXME: ARM meta-data section. Retain the first attribute section
-    // we see. The eglibc ARM dynamic loaders require the presence of an
-    // attribute section for dlopen to work.
-    // In a full implementation we would merge all attribute sections.
+  case SHT_ARM_ATTRIBUTES: {
+    ARMAttributeParser Attributes;
+    ArrayRef<uint8_t> Contents = check(this->getObj().getSectionContents(&Sec));
+    Attributes.Parse(Contents, /*isLittle*/Config->EKind == ELF32LEKind);
+    updateSupportedARMFeatures(Attributes);
+    // FIXME: Retain the first attribute section we see. The eglibc ARM
+    // dynamic loaders require the presence of an attribute section for dlopen
+    // to work. In a full implementation we would merge all attribute sections.
     if (InX::ARMAttributes == nullptr) {
       InX::ARMAttributes = make<InputSection>(this, &Sec, Name);
       return InX::ARMAttributes;
     }
     return &InputSection::Discarded;
+  }
   case SHT_RELA:
   case SHT_REL: {
     // Find the relocation target section and associate this

Added: lld/trunk/test/ELF/arm-bl-v6.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/arm-bl-v6.s?rev=319169&view=auto
==============================================================================
--- lld/trunk/test/ELF/arm-bl-v6.s (added)
+++ lld/trunk/test/ELF/arm-bl-v6.s Tue Nov 28 05:51:48 2017
@@ -0,0 +1,51 @@
+// RUN: llvm-mc -filetype=obj -triple=arm-none-linux-gnueabi %s -o %t
+// RUN: ld.lld %t -o %t2 2>&1 | FileCheck %s
+// Requires: arm
+
+// On Arm v6 the range of a Thumb BL instruction is only 4 megabytes as the
+// extended range encoding is not supported. The following example has a Thumb
+// BL that is out of range on ARM v6 and requires a range extension thunk.
+// As v6 does not support MOVT or MOVW instructions the Thunk must not
+// use these instructions either. At present we don't support v6 so we give a
+// warning for unsupported features.
+
+// CHECK: warning: lld uses extended branch encoding, no object with architecture supporting feature detected.
+// CHECK-NEXT: warning: lld may use movt/movw, no object with architecture supporting feature detected.
+// ARM v6 supports blx so we shouldn't see the blx not supported warning.
+// CHECK-NOT: warning: lld uses blx instruction, no object with architecture supporting feature detected.
+ .text
+ .syntax unified
+ .cpu    arm1176jzf-s
+ .eabi_attribute 6, 6    @ Tag_CPU_arch
+ .globl _start
+ .type   _start,%function
+ .balign 0x1000
+_start:
+  bl thumbfunc
+  bx lr
+
+ .thumb
+ .section .text.2, "ax", %progbits
+ .globl thumbfunc
+ .type thumbfunc,%function
+thumbfunc:
+ bl farthumbfunc
+
+// 6 Megabytes, enough to make farthumbfunc out of range of caller on a v6
+// Arm, but not on a v7 Arm.
+ .section .text.3, "ax", %progbits
+ .space 0x200000
+
+ .section .text.4, "ax", %progbits
+ .space 0x200000
+
+ .section .text.5, "ax", %progbits
+ .space 0x200000
+
+ .thumb
+ .section .text.6, "ax", %progbits
+ .balign 0x1000
+ .globl farthumbfunc
+ .type farthumbfunc,%function
+farthumbfunc:
+ bx lr

Added: lld/trunk/test/ELF/arm-blx-v4t.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/arm-blx-v4t.s?rev=319169&view=auto
==============================================================================
--- lld/trunk/test/ELF/arm-blx-v4t.s (added)
+++ lld/trunk/test/ELF/arm-blx-v4t.s Tue Nov 28 05:51:48 2017
@@ -0,0 +1,30 @@
+// RUN: llvm-mc -filetype=obj -triple=arm-none-linux-gnueabi %s -o %t
+// RUN: ld.lld %t -o %t2 2>&1 | FileCheck %s
+// REQUIRES: arm
+
+// On Arm v4t there is no blx instruction so all interworking must go via
+// a thunk. At present we don't support v4t so we give a warning for unsupported
+// features.
+
+// CHECK: warning: lld uses blx instruction, no object with architecture supporting feature detected.
+// CHECK-NEXT: warning: lld uses extended branch encoding, no object with architecture supporting feature detected.
+// CHECK-NEXT: warning: lld may use movt/movw, no object with architecture supporting feature detected.
+
+ .text
+ .syntax unified
+ .cpu   arm7tdmi
+ .eabi_attribute        6, 2    @ Tag_CPU_arch
+ .arm
+ .globl _start
+ .type   _start,%function
+ .p2align       2
+_start:
+  bl thumbfunc
+  bx lr
+
+ .thumb
+ .section .text.2, "ax", %progbits
+ .globl thumbfunc
+ .type thumbfunc,%function
+thumbfunc:
+ bx lr




More information about the llvm-commits mailing list