[lld] r227961 - [lld][ARM] Add relocations to perform function calls

Denis Protivensky dprotivensky at accesssoftek.com
Tue Feb 3 02:48:38 PST 2015


Author: denis-protivensky
Date: Tue Feb  3 04:48:37 2015
New Revision: 227961

URL: http://llvm.org/viewvc/llvm-project?rev=227961&view=rev
Log:
[lld][ARM] Add relocations to perform function calls

Added relocations to perform function calls with and without passing arguments.
ARM-only, Thumb-only and mixed mode code generations are supported.
Only simple veneers (direct instruction modification) are supported as ARM-Thumb interwork.

Differential Revision: http://reviews.llvm.org/D7223

Added:
    lld/trunk/test/elf/ARM/rel-arm-jump24.test
    lld/trunk/test/elf/ARM/rel-arm-mov.test
    lld/trunk/test/elf/ARM/rel-arm-thm-interwork.test
    lld/trunk/test/elf/ARM/rel-thm-call.test
    lld/trunk/test/elf/ARM/rel-thm-jump24.test
    lld/trunk/test/elf/ARM/rel-thm-mov.test
Modified:
    lld/trunk/lib/ReaderWriter/ELF/ARM/ARMRelocationHandler.cpp
    lld/trunk/test/elf/ARM/rel-abs32.test
    lld/trunk/test/elf/ARM/rel-arm-call.test

Modified: lld/trunk/lib/ReaderWriter/ELF/ARM/ARMRelocationHandler.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/ARM/ARMRelocationHandler.cpp?rev=227961&r1=227960&r2=227961&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/ARM/ARMRelocationHandler.cpp (original)
+++ lld/trunk/lib/ReaderWriter/ELF/ARM/ARMRelocationHandler.cpp Tue Feb  3 04:48:37 2015
@@ -16,14 +16,61 @@
 using namespace lld;
 using namespace elf;
 
+static Reference::Addend readAddend_THM_MOV(const uint8_t *location) {
+  const auto halfHi = uint16_t(
+      *reinterpret_cast<const llvm::support::ulittle16_t *>(location));
+  const auto halfLo = uint16_t(
+      *reinterpret_cast<const llvm::support::ulittle16_t *>(location + 2));
+
+  const uint16_t imm8 = halfLo & 0xFF;
+  const uint16_t imm3 = (halfLo >> 12) & 0x7;
+
+  const uint16_t imm4 = halfHi & 0xF;
+  const uint16_t bitI = (halfHi >> 10) & 0x1;
+
+  const auto result = int16_t((imm4 << 12) | (bitI << 11) | (imm3 << 8) | imm8);
+  return result;
+}
+
+static Reference::Addend readAddend_ARM_MOV(const uint8_t *location) {
+  const auto value = uint32_t(
+      *reinterpret_cast<const llvm::support::ulittle32_t *>(location));
+
+  const uint32_t imm12 = value & 0xFFF;
+  const uint32_t imm4 = (value >> 16) & 0xF;
+
+  const auto result = int32_t((imm4 << 12) | imm12);
+  return result;
+}
+
+static Reference::Addend readAddend_THM_CALL(const uint8_t *location) {
+  const auto halfHi = uint16_t(
+      *reinterpret_cast<const llvm::support::ulittle16_t *>(location));
+  const auto halfLo = uint16_t(
+      *reinterpret_cast<const llvm::support::ulittle16_t *>(location + 2));
+
+  const uint16_t imm10 = halfHi & 0x3FF;
+  const uint16_t bitS = (halfHi >> 10) & 0x1;
+
+  const uint16_t imm11 = halfLo & 0x7FF;
+  const uint16_t bitJ2 = (halfLo >> 11) & 0x1;
+  const uint16_t bitI2 = (~(bitJ2 ^ bitS)) & 0x1;
+  const uint16_t bitJ1 = (halfLo >> 13) & 0x1;
+  const uint16_t bitI1 = (~(bitJ1 ^ bitS)) & 0x1;
+
+  const auto result = int32_t((bitS << 24) | (bitI1 << 23) | (bitI2 << 22) |
+                              (imm10 << 12) | (imm11 << 1));
+  return llvm::SignExtend64<25>(result);
+}
+
 static Reference::Addend readAddend_ARM_CALL(const uint8_t *location) {
-  const auto value = int32_t(
-      *reinterpret_cast<const llvm::support::little32_t *>(location));
+  const auto value = uint32_t(
+      *reinterpret_cast<const llvm::support::ulittle32_t *>(location));
 
   const bool isBLX = (value & 0xF0000000) == 0xF0000000;
-  const int32_t bitH = isBLX ? ((value & 0x1000000) >> 24) : 0;
+  const uint32_t bitH = isBLX ? ((value & 0x1000000) >> 24) : 0;
 
-  const int32_t result = ((value & 0xFFFFFF) << 2) | (bitH << 1);
+  const auto result = int32_t(((value & 0xFFFFFF) << 2) | (bitH << 1));
   return llvm::SignExtend64<26>(result);
 }
 
@@ -33,8 +80,18 @@ static Reference::Addend readAddend(cons
   case R_ARM_ABS32:
     return int32_t(
         *reinterpret_cast<const llvm::support::little32_t *>(location));
+  case R_ARM_THM_CALL:
+  case R_ARM_THM_JUMP24:
+    return readAddend_THM_CALL(location);
   case R_ARM_CALL:
+  case R_ARM_JUMP24:
     return readAddend_ARM_CALL(location);
+  case R_ARM_MOVW_ABS_NC:
+  case R_ARM_MOVT_ABS:
+    return readAddend_ARM_MOV(location);
+  case R_ARM_THM_MOVW_ABS_NC:
+  case R_ARM_THM_MOVT_ABS:
+    return readAddend_THM_MOV(location);
   default:
     return 0;
   }
@@ -48,23 +105,124 @@ static inline void applyArmReloc(uint8_t
        ~mask) | (result & mask);
 }
 
-/// \brief R_ARM_ABS32 - (S + A) | T => S + A
+static inline void applyThmReloc(uint8_t *location, uint16_t resHi,
+                                 uint16_t resLo, uint16_t maskHi,
+                                 uint16_t maskLo = 0xFFFF) {
+  assert(!(resHi & ~maskHi) && !(resLo & ~maskLo));
+  *reinterpret_cast<llvm::support::ulittle16_t *>(location) =
+      (uint16_t(*reinterpret_cast<llvm::support::ulittle16_t *>(location)) &
+       ~maskHi) | (resHi & maskHi);
+  location += 2;
+  *reinterpret_cast<llvm::support::ulittle16_t *>(location) =
+      (uint16_t(*reinterpret_cast<llvm::support::ulittle16_t *>(location)) &
+       ~maskLo) | (resLo & maskLo);
+}
+
+/// \brief R_ARM_ABS32 - (S + A) | T
 static void relocR_ARM_ABS32(uint8_t *location, uint64_t P, uint64_t S,
-                             int64_t A) {
-  uint32_t result = (uint32_t)(S + A);
+                             int64_t A, bool addressesThumb) {
+  uint64_t T = addressesThumb;
+  uint32_t result = (uint32_t)((S + A) | T);
+
   DEBUG_WITH_TYPE(
       "ARM", llvm::dbgs() << "\t\tHandle " << LLVM_FUNCTION_NAME << " -";
       llvm::dbgs() << " S: 0x" << Twine::utohexstr(S);
       llvm::dbgs() << " A: 0x" << Twine::utohexstr(A);
       llvm::dbgs() << " P: 0x" << Twine::utohexstr(P);
+      llvm::dbgs() << " T: 0x" << Twine::utohexstr(T);
       llvm::dbgs() << " result: 0x" << Twine::utohexstr(result) << "\n");
   applyArmReloc(location, result);
 }
 
-/// \brief R_ARM_CALL - ((S + A) | T) - P => S + A - P
+/// \brief Relocate B/BL instructions. useJs defines whether J1 & J2 are used
+static void relocR_ARM_THM_B_L(uint8_t *location, uint32_t result, bool useJs) {
+  result = (result & 0x01FFFFFE) >> 1;
+
+  const uint16_t imm10 = (result >> 11) & 0x3FF;
+  const uint16_t bitS = (result >> 23) & 0x1;
+  const uint16_t resHi = (bitS << 10) | imm10;
+
+  const uint16_t imm11 = result & 0x7FF;
+  const uint16_t bitJ2 = useJs ? ((result >> 21) & 0x1) : bitS;
+  const uint16_t bitI2 = (~(bitJ2 ^ bitS)) & 0x1;
+  const uint16_t bitJ1 = useJs ? ((result >> 22) & 0x1) : bitS;
+  const uint16_t bitI1 = (~(bitJ1 ^ bitS)) & 0x1;
+  const uint16_t resLo = (bitI1 << 13) | (bitI2 << 11) | imm11;
+
+  applyThmReloc(location, resHi, resLo, 0x7FF, 0x2FFF);
+}
+
+/// \brief R_ARM_THM_CALL - ((S + A) | T) - P
+static void relocR_ARM_THM_CALL(uint8_t *location, uint64_t P, uint64_t S,
+                                int64_t A, bool useJs, bool addressesThumb) {
+  uint64_t T = addressesThumb;
+  const bool switchMode = !addressesThumb;
+
+  if (switchMode) {
+    P &= ~0x3; // Align(P, 4) by rounding down
+  }
+
+  uint32_t result = (uint32_t)(((S + A) | T) - P);
+
+  DEBUG_WITH_TYPE(
+      "ARM", llvm::dbgs() << "\t\tHandle " << LLVM_FUNCTION_NAME << " -";
+      llvm::dbgs() << " S: 0x" << Twine::utohexstr(S);
+      llvm::dbgs() << " A: 0x" << Twine::utohexstr(A);
+      llvm::dbgs() << " P: 0x" << Twine::utohexstr(P);
+      llvm::dbgs() << " T: 0x" << Twine::utohexstr(T);
+      llvm::dbgs() << " result: 0x" << Twine::utohexstr(result) << "\n");
+  relocR_ARM_THM_B_L(location, result, useJs);
+
+  if (switchMode) {
+    applyThmReloc(location, 0, 0, 0, 0x1001);
+  }
+}
+
+/// \brief R_ARM_THM_JUMP24 - ((S + A) | T) - P
+static void relocR_ARM_THM_JUMP24(uint8_t *location, uint64_t P, uint64_t S,
+                                  int64_t A, bool addressesThumb) {
+  uint64_t T = addressesThumb;
+  uint32_t result = (uint32_t)(((S + A) | T) - P);
+
+  DEBUG_WITH_TYPE(
+      "ARM", llvm::dbgs() << "\t\tHandle " << LLVM_FUNCTION_NAME << " -";
+      llvm::dbgs() << " S: 0x" << Twine::utohexstr(S);
+      llvm::dbgs() << " A: 0x" << Twine::utohexstr(A);
+      llvm::dbgs() << " P: 0x" << Twine::utohexstr(P);
+      llvm::dbgs() << " T: 0x" << Twine::utohexstr(T);
+      llvm::dbgs() << " result: 0x" << Twine::utohexstr(result) << "\n");
+  relocR_ARM_THM_B_L(location, result, true);
+}
+
+/// \brief R_ARM_CALL - ((S + A) | T) - P
 static void relocR_ARM_CALL(uint8_t *location, uint64_t P, uint64_t S,
-                            int64_t A) {
-  uint32_t result = (uint32_t)((S + A) - P);
+                            int64_t A, bool addressesThumb) {
+  uint64_t T = addressesThumb;
+  const bool switchMode = addressesThumb;
+
+  uint32_t result = (uint32_t)(((S + A) | T) - P);
+  const uint32_t imm24 = (result & 0x03FFFFFC) >> 2;
+
+  DEBUG_WITH_TYPE(
+      "ARM", llvm::dbgs() << "\t\tHandle " << LLVM_FUNCTION_NAME << " -";
+      llvm::dbgs() << " S: 0x" << Twine::utohexstr(S);
+      llvm::dbgs() << " A: 0x" << Twine::utohexstr(A);
+      llvm::dbgs() << " P: 0x" << Twine::utohexstr(P);
+      llvm::dbgs() << " T: 0x" << Twine::utohexstr(T);
+      llvm::dbgs() << " result: 0x" << Twine::utohexstr(result) << "\n");
+  applyArmReloc(location, imm24, 0xFFFFFF);
+
+  if (switchMode) {
+    const uint32_t bitH = (result & 0x2) >> 1;
+    applyArmReloc(location, (0xFA | bitH) << 24, 0xFF000000);
+  }
+}
+
+/// \brief R_ARM_JUMP24 - ((S + A) | T) - P
+static void relocR_ARM_JUMP24(uint8_t *location, uint64_t P, uint64_t S,
+                              int64_t A, bool addressesThumb) {
+  uint64_t T = addressesThumb;
+  uint32_t result = (uint32_t)(((S + A) | T) - P);
   const uint32_t imm24 = (result & 0x03FFFFFC) >> 2;
 
   DEBUG_WITH_TYPE(
@@ -72,10 +230,97 @@ static void relocR_ARM_CALL(uint8_t *loc
       llvm::dbgs() << " S: 0x" << Twine::utohexstr(S);
       llvm::dbgs() << " A: 0x" << Twine::utohexstr(A);
       llvm::dbgs() << " P: 0x" << Twine::utohexstr(P);
+      llvm::dbgs() << " T: 0x" << Twine::utohexstr(T);
       llvm::dbgs() << " result: 0x" << Twine::utohexstr(result) << "\n");
   applyArmReloc(location, imm24, 0xFFFFFF);
 }
 
+/// \brief Relocate ARM MOVW/MOVT instructions
+static void relocR_ARM_MOV(uint8_t *location, uint32_t result) {
+  const uint32_t imm12 = result & 0xFFF;
+  const uint32_t imm4 = (result >> 12) & 0xF;
+
+  applyArmReloc(location, (imm4 << 16) | imm12, 0xF0FFF);
+}
+
+/// \brief R_ARM_MOVW_ABS_NC - (S + A) | T
+static void relocR_ARM_MOVW_ABS_NC(uint8_t *location, uint64_t P, uint64_t S,
+                                   int64_t A, bool addressesThumb) {
+  uint64_t T = addressesThumb;
+  uint32_t result = (uint32_t)((S + A) | T);
+  const uint32_t arg = result & 0x0000FFFF;
+
+  DEBUG_WITH_TYPE(
+      "ARM", llvm::dbgs() << "\t\tHandle " << LLVM_FUNCTION_NAME << " -";
+      llvm::dbgs() << " S: 0x" << Twine::utohexstr(S);
+      llvm::dbgs() << " A: 0x" << Twine::utohexstr(A);
+      llvm::dbgs() << " P: 0x" << Twine::utohexstr(P);
+      llvm::dbgs() << " T: 0x" << Twine::utohexstr(T);
+      llvm::dbgs() << " result: 0x" << Twine::utohexstr(result) << "\n");
+  return relocR_ARM_MOV(location, arg);
+}
+
+/// \brief R_ARM_MOVT_ABS - S + A
+static void relocR_ARM_MOVT_ABS(uint8_t *location, uint64_t P, uint64_t S,
+                                int64_t A) {
+  uint32_t result = (uint32_t)(S + A);
+  const uint32_t arg = (result & 0xFFFF0000) >> 16;
+
+  DEBUG_WITH_TYPE(
+      "ARM", llvm::dbgs() << "\t\tHandle " << LLVM_FUNCTION_NAME << " -";
+      llvm::dbgs() << " S: 0x" << Twine::utohexstr(S);
+      llvm::dbgs() << " A: 0x" << Twine::utohexstr(A);
+      llvm::dbgs() << " P: 0x" << Twine::utohexstr(P);
+      llvm::dbgs() << " result: 0x" << Twine::utohexstr(result) << "\n");
+  return relocR_ARM_MOV(location, arg);
+}
+
+/// \brief Relocate Thumb MOVW/MOVT instructions
+static void relocR_ARM_THM_MOV(uint8_t *location, uint32_t result) {
+  const uint16_t imm8 = result & 0xFF;
+  const uint16_t imm3 = (result >> 8) & 0x7;
+  const uint16_t resLo = (imm3 << 12) | imm8;
+
+  const uint16_t imm4 = (result >> 12) & 0xF;
+  const uint16_t bitI = (result >> 11) & 0x1;
+  const uint16_t resHi = (bitI << 10) | imm4;
+
+ applyThmReloc(location, resHi, resLo, 0x40F, 0x70FF);
+}
+
+/// \brief R_ARM_THM_MOVW_ABS_NC - (S + A) | T
+static void relocR_ARM_THM_MOVW_ABS_NC(uint8_t *location, uint64_t P,
+                                       uint64_t S, int64_t A,
+                                       bool addressesThumb) {
+  uint64_t T = addressesThumb;
+  uint32_t result = (uint32_t)((S + A) | T);
+  const uint32_t arg = result & 0x0000FFFF;
+
+  DEBUG_WITH_TYPE(
+      "ARM", llvm::dbgs() << "\t\tHandle " << LLVM_FUNCTION_NAME << " -";
+      llvm::dbgs() << " S: 0x" << Twine::utohexstr(S);
+      llvm::dbgs() << " A: 0x" << Twine::utohexstr(A);
+      llvm::dbgs() << " P: 0x" << Twine::utohexstr(P);
+      llvm::dbgs() << " T: 0x" << Twine::utohexstr(T);
+      llvm::dbgs() << " result: 0x" << Twine::utohexstr(result) << "\n");
+  return relocR_ARM_THM_MOV(location, arg);
+}
+
+/// \brief R_ARM_THM_MOVT_ABS - S + A
+static void relocR_ARM_THM_MOVT_ABS(uint8_t *location, uint64_t P, uint64_t S,
+                                    int64_t A) {
+  uint32_t result = (uint32_t)(S + A);
+  const uint32_t arg = (result & 0xFFFF0000) >> 16;
+
+  DEBUG_WITH_TYPE(
+      "ARM", llvm::dbgs() << "\t\tHandle " << LLVM_FUNCTION_NAME << " -";
+      llvm::dbgs() << " S: 0x" << Twine::utohexstr(S);
+      llvm::dbgs() << " A: 0x" << Twine::utohexstr(A);
+      llvm::dbgs() << " P: 0x" << Twine::utohexstr(P);
+      llvm::dbgs() << " result: 0x" << Twine::utohexstr(result) << "\n");
+  return relocR_ARM_THM_MOV(location, arg);
+}
+
 std::error_code ARMTargetRelocationHandler::applyRelocation(
     ELFWriter &writer, llvm::FileOutputBuffer &buf, const lld::AtomLayout &atom,
     const Reference &ref) const {
@@ -92,14 +337,51 @@ std::error_code ARMTargetRelocationHandl
   const Reference::Addend addend =
       readAddend(location, ref.kindValue());
 
+  // Flags that the relocation addresses Thumb instruction
+  bool addressesThumb = false;
+
+  if (const auto *definedAtom = dyn_cast<DefinedAtom>(ref.target())) {
+    addressesThumb = (DefinedAtom::codeARMThumb == definedAtom->codeModel());
+  }
+
   switch (ref.kindValue()) {
   case R_ARM_NONE:
     break;
   case R_ARM_ABS32:
-    relocR_ARM_ABS32(location, relocVAddress, targetVAddress, addend);
+    relocR_ARM_ABS32(location, relocVAddress, targetVAddress, addend,
+                     addressesThumb);
+    break;
+  case R_ARM_THM_CALL:
+    // TODO: consider adding bool variable to disable J1 & J2 for archs
+    // before ARMv6
+    relocR_ARM_THM_CALL(location, relocVAddress, targetVAddress, addend, true,
+                        addressesThumb);
     break;
   case R_ARM_CALL:
-    relocR_ARM_CALL(location, relocVAddress, targetVAddress, addend);
+    relocR_ARM_CALL(location, relocVAddress, targetVAddress, addend,
+                    addressesThumb);
+    break;
+  case R_ARM_JUMP24:
+    relocR_ARM_JUMP24(location, relocVAddress, targetVAddress, addend,
+                      addressesThumb);
+    break;
+  case R_ARM_THM_JUMP24:
+    relocR_ARM_THM_JUMP24(location, relocVAddress, targetVAddress, addend,
+                          addressesThumb);
+    break;
+  case R_ARM_MOVW_ABS_NC:
+    relocR_ARM_MOVW_ABS_NC(location, relocVAddress, targetVAddress, addend,
+                           addressesThumb);
+    break;
+  case R_ARM_MOVT_ABS:
+    relocR_ARM_MOVT_ABS(location, relocVAddress, targetVAddress, addend);
+    break;
+  case R_ARM_THM_MOVW_ABS_NC:
+    relocR_ARM_THM_MOVW_ABS_NC(location, relocVAddress, targetVAddress, addend,
+                               addressesThumb);
+    break;
+  case R_ARM_THM_MOVT_ABS:
+    relocR_ARM_THM_MOVT_ABS(location, relocVAddress, targetVAddress, addend);
     break;
   default:
     return make_unhandled_reloc_error();

Modified: lld/trunk/test/elf/ARM/rel-abs32.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/ARM/rel-abs32.test?rev=227961&r1=227960&r2=227961&view=diff
==============================================================================
--- lld/trunk/test/elf/ARM/rel-abs32.test (original)
+++ lld/trunk/test/elf/ARM/rel-abs32.test Tue Feb  3 04:48:37 2015
@@ -10,7 +10,7 @@
 #               data     main addr  content
 #             0x400084 = 0x400074 + 0x10
 # CHECK: SYMBOL TABLE:
-# CHECK: 00400074 g     F .text  0000001c main
+# CHECK: 00400074 g     F .text  {{[0-9a-f]+}} main
 # CHECK: 00401000 g       .data  00000004 data
 
 ---

Modified: lld/trunk/test/elf/ARM/rel-arm-call.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/ARM/rel-arm-call.test?rev=227961&r1=227960&r2=227961&view=diff
==============================================================================
--- lld/trunk/test/elf/ARM/rel-arm-call.test (original)
+++ lld/trunk/test/elf/ARM/rel-arm-call.test Tue Feb  3 04:48:37 2015
@@ -10,8 +10,8 @@
 #               call site  offset  PC(arm) _Z1fv addr
 #               0x400090 + (-0x24) + 0x8 = 0x400074
 # CHECK: SYMBOL TABLE:
-# CHECK: 00400074 g     F .text  00000014 _Z1fv
-# CHECK: 00400088 g     F .text  00000018 main
+# CHECK: 00400074 g     F .text  {{[0-9a-f]+}} _Z1fv
+# CHECK: 00400088 g     F .text  {{[0-9a-f]+}} main
 
 ---
 FileHeader:

Added: lld/trunk/test/elf/ARM/rel-arm-jump24.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/ARM/rel-arm-jump24.test?rev=227961&view=auto
==============================================================================
--- lld/trunk/test/elf/ARM/rel-arm-jump24.test (added)
+++ lld/trunk/test/elf/ARM/rel-arm-jump24.test Tue Feb  3 04:48:37 2015
@@ -0,0 +1,58 @@
+# Check handling of R_ARM_JUMP24 relocation.
+# RUN: yaml2obj -format=elf %s > %t-o.o
+# RUN: lld -flavor gnu -target arm -m armelf_linux_eabi -Bstatic \
+# RUN: --noinhibit-exec %t-o.o -o %t
+# RUN: llvm-objdump -s -t %t | FileCheck %s
+
+# CHECK: Contents of section .text:
+# CHECK: 400094 04b08de2 f5ffffea 0030a0e1 0300a0e1
+#           offset = -0x2C  ^^
+#               call site  offset  PC(arm) _Z1fv addr
+#               0x400098 + (-0x2C) + 0x8 = 0x400074
+# CHECK: SYMBOL TABLE:
+# CHECK: 00400074 g     F .text  {{[0-9a-f]+}} _Z1fv
+# CHECK: 00400090 g     F .text  {{[0-9a-f]+}} main
+
+---
+FileHeader:
+  Class:           ELFCLASS32
+  Data:            ELFDATA2LSB
+  Type:            ET_REL
+  Machine:         EM_ARM
+  Flags:           [ EF_ARM_EABI_VER5 ]
+Sections:
+  - Name:            .text
+    Type:            SHT_PROGBITS
+    Flags:           [ SHF_ALLOC, SHF_EXECINSTR ]
+    AddressAlign:    0x0000000000000004
+    Content:         04B02DE500B08DE20030A0E30300A0E100D04BE204B09DE41EFF2FE100482DE904B08DE2FEFFFFEA0030A0E10300A0E10088BDE8
+  - Name:            .rel.text
+    Type:            SHT_REL
+    Link:            .symtab
+    AddressAlign:    0x0000000000000004
+    Info:            .text
+    Relocations:
+      - Offset:          0x0000000000000024
+        Symbol:          _Z1fv
+        Type:            R_ARM_JUMP24
+        Addend:          0
+  - Name:            .data
+    Type:            SHT_PROGBITS
+    Flags:           [ SHF_WRITE, SHF_ALLOC ]
+    AddressAlign:    0x0000000000000001
+    Content:         ''
+  - Name:            .bss
+    Type:            SHT_NOBITS
+    Flags:           [ SHF_WRITE, SHF_ALLOC ]
+    AddressAlign:    0x0000000000000001
+    Content:         ''
+Symbols:
+  Global:
+    - Name:            _Z1fv
+      Type:            STT_FUNC
+      Section:         .text
+    - Name:            main
+      Type:            STT_FUNC
+      Section:         .text
+      Value:           0x000000000000001C
+...

Added: lld/trunk/test/elf/ARM/rel-arm-mov.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/ARM/rel-arm-mov.test?rev=227961&view=auto
==============================================================================
--- lld/trunk/test/elf/ARM/rel-arm-mov.test (added)
+++ lld/trunk/test/elf/ARM/rel-arm-mov.test Tue Feb  3 04:48:37 2015
@@ -0,0 +1,64 @@
+# Check handling of R_ARM_MOVW_ABS_NC and R_ARM_MOVT_ABS relocation pair.
+# RUN: yaml2obj -format=elf %s > %t-o.o
+# RUN: lld -flavor gnu -target arm -m armelf_linux_eabi -Bstatic \
+# RUN: --noinhibit-exec %t-o.o -o %t
+# RUN: llvm-objdump -s -t %t | FileCheck %s
+
+# CHECK: Contents of section .text:
+# CHECK: 400074 04b02de5 00b08de2 003001e3 403040e3
+#                    addrL = 0x1000  ^^
+#                               addrH = 0x40  ^^
+#                   addrH      addrL    _ZL5data1 addr
+#               (0x40 << 16) + 0x1000 = 0x401000
+# CHECK: SYMBOL TABLE:
+# CHECK: 00401000 l       .bss   00000004 _ZL5data1
+# CHECK: 00400074 g     F .text  {{[0-9a-f]+}} main
+
+---
+FileHeader:
+  Class:           ELFCLASS32
+  Data:            ELFDATA2LSB
+  Type:            ET_REL
+  Machine:         EM_ARM
+  Flags:           [ EF_ARM_EABI_VER5 ]
+Sections:
+  - Name:            .text
+    Type:            SHT_PROGBITS
+    Flags:           [ SHF_ALLOC, SHF_EXECINSTR ]
+    AddressAlign:    0x0000000000000004
+    Content:         04B02DE500B08DE2003000E3003040E30A20A0E3002083E50030A0E30300A0E100D04BE204B09DE41EFF2FE1
+  - Name:            .rel.text
+    Type:            SHT_REL
+    Link:            .symtab
+    AddressAlign:    0x0000000000000004
+    Info:            .text
+    Relocations:
+      - Offset:          0x0000000000000008
+        Symbol:          _ZL5data1
+        Type:            R_ARM_MOVW_ABS_NC
+        Addend:          0
+      - Offset:          0x000000000000000C
+        Symbol:          _ZL5data1
+        Type:            R_ARM_MOVT_ABS
+        Addend:          0
+  - Name:            .data
+    Type:            SHT_PROGBITS
+    Flags:           [ SHF_WRITE, SHF_ALLOC ]
+    AddressAlign:    0x0000000000000001
+    Content:         ''
+  - Name:            .bss
+    Type:            SHT_NOBITS
+    Flags:           [ SHF_WRITE, SHF_ALLOC ]
+    AddressAlign:    0x0000000000000004
+    Content:         411C0000
+Symbols:
+  Local:
+    - Name:            _ZL5data1
+      Type:            STT_OBJECT
+      Section:         .bss
+      Size:            0x0000000000000004
+  Global:
+    - Name:            main
+      Type:            STT_FUNC
+      Section:         .text
+...

Added: lld/trunk/test/elf/ARM/rel-arm-thm-interwork.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/ARM/rel-arm-thm-interwork.test?rev=227961&view=auto
==============================================================================
--- lld/trunk/test/elf/ARM/rel-arm-thm-interwork.test (added)
+++ lld/trunk/test/elf/ARM/rel-arm-thm-interwork.test Tue Feb  3 04:48:37 2015
@@ -0,0 +1,123 @@
+# Check ARM <=> Thumb interwork.
+# RUN: yaml2obj -format=elf -docnum 1 %s > %t-arm.o
+# RUN: yaml2obj -format=elf -docnum 2 %s > %t-thm.o
+# RUN: lld -flavor gnu -target arm -m armelf_linux_eabi -Bstatic \
+# RUN: --noinhibit-exec %t-arm.o %t-thm.o -o %t
+
+# Check R_ARM_CALL veneer to call Thumb code
+# RUN: llvm-objdump -s -t %t | FileCheck -check-prefix=ARM-CALL %s
+
+# ARM-CALL: Contents of section .text:
+# ARM-CALL: 400074 00482de9 04b08de2 000000fa 0088bde8
+#                          offset = 0x0 ^^
+#               call site offset PC(arm) _Z2f2v addr
+#               0x40007C + 0x0 + 0x8  =  0x400084
+# ARM-CALL: SYMBOL TABLE:
+# ARM-CALL: 00400074 g     F .text  {{[0-9a-f]+}} _Z1fv
+# ARM-CALL: 00400084 g     F .text  {{[0-9a-f]+}} _Z2f2v
+# ARM-CALL: 00400090 g     F .text  {{[0-9a-f]+}} main
+
+# Check R_ARM_THM_CALL veneer to call ARM code
+# RUN: llvm-objdump -s -t %t | FileCheck -check-prefix=THM-CALL %s
+
+# THM-CALL: Contents of section .text:
+# THM-CALL: 400094 00bffff7 eeef0023 184680bd
+#         offset = -0x24 ^^
+#         call site aligned = Align(0x400096, 4) = 0x400094
+#      call site aligned   offset   PC(thm)  _Z1fv addr
+#           0x400094   +   (-0x24) + 0x4  =  0x400074
+# THM-CALL: SYMBOL TABLE:
+# THM-CALL: 00400074 g     F .text  {{[0-9a-f]+}} _Z1fv
+# THM-CALL: 00400084 g     F .text  {{[0-9a-f]+}} _Z2f2v
+# THM-CALL: 00400090 g     F .text  {{[0-9a-f]+}} main
+
+# arm.o
+---
+FileHeader:
+  Class:           ELFCLASS32
+  Data:            ELFDATA2LSB
+  Type:            ET_REL
+  Machine:         EM_ARM
+  Flags:           [ EF_ARM_EABI_VER5 ]
+Sections:
+  - Name:            .text
+    Type:            SHT_PROGBITS
+    Flags:           [ SHF_ALLOC, SHF_EXECINSTR ]
+    AddressAlign:    0x0000000000000004
+    Content:         00482DE904B08DE2FEFFFFEB0088BDE8
+  - Name:            .rel.text
+    Type:            SHT_REL
+    Link:            .symtab
+    AddressAlign:    0x0000000000000004
+    Info:            .text
+    Relocations:
+      - Offset:          0x0000000000000008
+        Symbol:          _Z2f2v
+        Type:            R_ARM_CALL
+        Addend:          0
+  - Name:            .data
+    Type:            SHT_PROGBITS
+    Flags:           [ SHF_WRITE, SHF_ALLOC ]
+    AddressAlign:    0x0000000000000001
+    Content:         ''
+  - Name:            .bss
+    Type:            SHT_NOBITS
+    Flags:           [ SHF_WRITE, SHF_ALLOC ]
+    AddressAlign:    0x0000000000000001
+    Content:         ''
+Symbols:
+  Global:
+    - Name:            _Z1fv
+      Type:            STT_FUNC
+      Section:         .text
+      Size:            0x0000000000000010
+    - Name:            _Z2f2v
+
+# thm.o
+---
+FileHeader:
+  Class:           ELFCLASS32
+  Data:            ELFDATA2LSB
+  Type:            ET_REL
+  Machine:         EM_ARM
+  Flags:           [ EF_ARM_EABI_VER5 ]
+Sections:
+  - Name:            .text
+    Type:            SHT_PROGBITS
+    Flags:           [ SHF_ALLOC, SHF_EXECINSTR ]
+    AddressAlign:    0x0000000000000004
+    Content:         80B400AFBD465DF8047B704780B500AF00BFFFF7FEFF0023184680BD
+  - Name:            .rel.text
+    Type:            SHT_REL
+    Link:            .symtab
+    AddressAlign:    0x0000000000000004
+    Info:            .text
+    Relocations:
+      - Offset:          0x0000000000000012
+        Symbol:          _Z1fv
+        Type:            R_ARM_THM_CALL
+        Addend:          0
+  - Name:            .data
+    Type:            SHT_PROGBITS
+    Flags:           [ SHF_WRITE, SHF_ALLOC ]
+    AddressAlign:    0x0000000000000001
+    Content:         ''
+  - Name:            .bss
+    Type:            SHT_NOBITS
+    Flags:           [ SHF_WRITE, SHF_ALLOC ]
+    AddressAlign:    0x0000000000000001
+    Content:         ''
+Symbols:
+  Global:
+    - Name:            _Z2f2v
+      Type:            STT_FUNC
+      Section:         .text
+      Value:           0x0000000000000001
+      Size:            0x000000000000000C
+    - Name:            main
+      Type:            STT_FUNC
+      Section:         .text
+      Value:           0x000000000000000D
+      Size:            0x0000000000000010
+    - Name:            _Z1fv
+...

Added: lld/trunk/test/elf/ARM/rel-thm-call.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/ARM/rel-thm-call.test?rev=227961&view=auto
==============================================================================
--- lld/trunk/test/elf/ARM/rel-thm-call.test (added)
+++ lld/trunk/test/elf/ARM/rel-thm-call.test Tue Feb  3 04:48:37 2015
@@ -0,0 +1,61 @@
+# Check handling of R_ARM_THM_CALL relocation.
+# RUN: yaml2obj -format=elf %s > %t-o.o
+# RUN: lld -flavor gnu -target arm -m armelf_linux_eabi -Bstatic \
+# RUN: --noinhibit-exec %t-o.o -o %t
+# RUN: llvm-objdump -s -t %t | FileCheck %s
+
+# CHECK: Contents of section .text:
+# CHECK: 400084 fff7f6ff 00231846 80bd00bf
+#                  ^^ offset = -0x14
+#               call site  offset  PC(thm) _Z1fv addr
+#               0x400084 + (-0x14) + 0x4 = 0x400074
+# CHECK: SYMBOL TABLE:
+# CHECK: 00400074 g     F .text  {{[0-9a-f]+}} _Z1fv
+# CHECK: 00400080 g     F .text  {{[0-9a-f]+}} main
+
+---
+FileHeader:
+  Class:           ELFCLASS32
+  Data:            ELFDATA2LSB
+  Type:            ET_REL
+  Machine:         EM_ARM
+  Flags:           [ EF_ARM_EABI_VER5 ]
+Sections:
+  - Name:            .text
+    Type:            SHT_PROGBITS
+    Flags:           [ SHF_ALLOC, SHF_EXECINSTR ]
+    AddressAlign:    0x0000000000000004
+    Content:         80B400AFBD465DF8047B704780B500AFFFF7FEFF0023184680BD00BF
+  - Name:            .rel.text
+    Type:            SHT_REL
+    Link:            .symtab
+    AddressAlign:    0x0000000000000004
+    Info:            .text
+    Relocations:
+      - Offset:          0x0000000000000010
+        Symbol:          _Z1fv
+        Type:            R_ARM_THM_CALL
+        Addend:          0
+  - Name:            .data
+    Type:            SHT_PROGBITS
+    Flags:           [ SHF_WRITE, SHF_ALLOC ]
+    AddressAlign:    0x0000000000000001
+    Content:         ''
+  - Name:            .bss
+    Type:            SHT_NOBITS
+    Flags:           [ SHF_WRITE, SHF_ALLOC ]
+    AddressAlign:    0x0000000000000001
+    Content:         ''
+Symbols:
+  Global:
+    - Name:            _Z1fv
+      Type:            STT_FUNC
+      Section:         .text
+      Value:           0x0000000000000001
+      Size:            0x000000000000000C
+    - Name:            main
+      Type:            STT_FUNC
+      Section:         .text
+      Value:           0x000000000000000D
+      Size:            0x000000000000000E
+...

Added: lld/trunk/test/elf/ARM/rel-thm-jump24.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/ARM/rel-thm-jump24.test?rev=227961&view=auto
==============================================================================
--- lld/trunk/test/elf/ARM/rel-thm-jump24.test (added)
+++ lld/trunk/test/elf/ARM/rel-thm-jump24.test Tue Feb  3 04:48:37 2015
@@ -0,0 +1,59 @@
+# Check handling of R_ARM_THM_JUMP24 relocation.
+# RUN: yaml2obj -format=elf %s > %t-o.o
+# RUN: lld -flavor gnu -target arm -m armelf_linux_eabi -Bstatic \
+# RUN: --noinhibit-exec %t-o.o -o %t
+# RUN: llvm-objdump -s -t %t | FileCheck %s
+
+# CHECK: Contents of section .text:
+# CHECK: 400084 80b500af fff7f4bf 03461846 80bd00bf
+#                           ^^ offset = -0x18
+#               call site  offset  PC(thm) _Z1fv addr
+#               0x400088 + (-0x18) + 0x4 = 0x400074
+# CHECK: SYMBOL TABLE:
+# CHECK: 00400074 g     F .text  {{[0-9a-f]+}} _Z1fv
+# CHECK: 00400084 g     F .text  {{[0-9a-f]+}} main
+
+---
+FileHeader:
+  Class:           ELFCLASS32
+  Data:            ELFDATA2LSB
+  Type:            ET_REL
+  Machine:         EM_ARM
+  Flags:           [ EF_ARM_EABI_VER5 ]
+Sections:
+  - Name:            .text
+    Type:            SHT_PROGBITS
+    Flags:           [ SHF_ALLOC, SHF_EXECINSTR ]
+    AddressAlign:    0x0000000000000004
+    Content:         80B400AF00231846BD465DF8047B704780B500AFFFF7FEBF0346184680BD00BF
+  - Name:            .rel.text
+    Type:            SHT_REL
+    Link:            .symtab
+    AddressAlign:    0x0000000000000004
+    Info:            .text
+    Relocations:
+      - Offset:          0x0000000000000014
+        Symbol:          _Z1fv
+        Type:            R_ARM_THM_JUMP24
+        Addend:          0
+  - Name:            .data
+    Type:            SHT_PROGBITS
+    Flags:           [ SHF_WRITE, SHF_ALLOC ]
+    AddressAlign:    0x0000000000000001
+    Content:         ''
+  - Name:            .bss
+    Type:            SHT_NOBITS
+    Flags:           [ SHF_WRITE, SHF_ALLOC ]
+    AddressAlign:    0x0000000000000001
+    Content:         ''
+Symbols:
+  Global:
+    - Name:            _Z1fv
+      Type:            STT_FUNC
+      Section:         .text
+      Value:           0x0000000000000001
+    - Name:            main
+      Type:            STT_FUNC
+      Section:         .text
+      Value:           0x0000000000000011
+...

Added: lld/trunk/test/elf/ARM/rel-thm-mov.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/ARM/rel-thm-mov.test?rev=227961&view=auto
==============================================================================
--- lld/trunk/test/elf/ARM/rel-thm-mov.test (added)
+++ lld/trunk/test/elf/ARM/rel-thm-mov.test Tue Feb  3 04:48:37 2015
@@ -0,0 +1,70 @@
+# 1. Check handling of R_ARM_THM_MOVW_ABS_NC and R_THM_ARM_MOVT_ABS relocation pair.
+# 2. Check that instructions are not cropped for symbols that address Thumb code.
+# RUN: yaml2obj -format=elf %s > %t-o.o
+# RUN: lld -flavor gnu -target arm -m armelf_linux_eabi -Bstatic \
+# RUN: --noinhibit-exec %t-o.o -o %t
+# RUN: llvm-objdump -s -t %t | FileCheck %s
+# RUN: llvm-objdump -s -t %t | FileCheck -check-prefix=INSN-CROP %s
+
+# CHECK: Contents of section .text:
+# CHECK: 400074 {{[0-9a-f]+}} 41f20003 c0f24003 0a221a60
+#                addrL = 0x1000  ^^
+#                           addrH = 0x40  ^^
+#                   addrH      addrL    _ZL5data1 addr
+#               (0x40 << 16) + 0x1000 = 0x401000
+# CHECK: SYMBOL TABLE:
+# CHECK: 00401000 l       .bss   00000004 _ZL5data1
+# CHECK: 00400074 g     F .text  {{[0-9a-f]+}} main
+#
+# INSN-CROP: Contents of section .text:
+# INSN-CROP: 400074 80b400af
+
+---
+FileHeader:
+  Class:           ELFCLASS32
+  Data:            ELFDATA2LSB
+  Type:            ET_REL
+  Machine:         EM_ARM
+  Flags:           [ EF_ARM_EABI_VER5 ]
+Sections:
+  - Name:            .text
+    Type:            SHT_PROGBITS
+    Flags:           [ SHF_ALLOC, SHF_EXECINSTR ]
+    AddressAlign:    0x0000000000000004
+    Content:         80B400AF40F20003C0F200030A221A6000231846BD465DF8047B7047
+  - Name:            .rel.text
+    Type:            SHT_REL
+    Link:            .symtab
+    AddressAlign:    0x0000000000000004
+    Info:            .text
+    Relocations:
+      - Offset:          0x0000000000000004
+        Symbol:          _ZL5data1
+        Type:            R_ARM_THM_MOVW_ABS_NC
+        Addend:          0
+      - Offset:          0x0000000000000008
+        Symbol:          _ZL5data1
+        Type:            R_ARM_THM_MOVT_ABS
+        Addend:          0
+  - Name:            .data
+    Type:            SHT_PROGBITS
+    Flags:           [ SHF_WRITE, SHF_ALLOC ]
+    AddressAlign:    0x0000000000000001
+    Content:         ''
+  - Name:            .bss
+    Type:            SHT_NOBITS
+    Flags:           [ SHF_WRITE, SHF_ALLOC ]
+    AddressAlign:    0x0000000000000004
+    Content:         411C0000
+Symbols:
+  Local:
+    - Name:            _ZL5data1
+      Type:            STT_OBJECT
+      Section:         .bss
+      Size:            0x0000000000000004
+  Global:
+    - Name:            main
+      Type:            STT_FUNC
+      Section:         .text
+      Value:           0x0000000000000001
+...





More information about the llvm-commits mailing list