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.
#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"
}
}
+// 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;
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
--- /dev/null
+// 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
--- /dev/null
+// 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