[lld] r236723 - [ARM] Add return codes to relocation handlers

Denis Protivensky dprotivensky at accesssoftek.com
Thu May 7 05:44:20 PDT 2015


Author: denis-protivensky
Date: Thu May  7 07:44:20 2015
New Revision: 236723

URL: http://llvm.org/viewvc/llvm-project?rev=236723&view=rev
Log:
[ARM] Add return codes to relocation handlers

Modified:
    lld/trunk/lib/ReaderWriter/ELF/ARM/ARMRelocationHandler.cpp

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=236723&r1=236722&r2=236723&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/ARM/ARMRelocationHandler.cpp (original)
+++ lld/trunk/lib/ReaderWriter/ELF/ARM/ARMRelocationHandler.cpp Thu May  7 07:44:20 2015
@@ -112,30 +112,35 @@ static Reference::Addend readAddend(cons
   }
 }
 
-static inline void applyArmReloc(uint8_t *location, uint32_t result,
-                                 uint32_t mask = 0xFFFFFFFF) {
+static inline std::error_code applyArmReloc(uint8_t *location, uint32_t result,
+                                            uint32_t mask = 0xFFFFFFFF) {
   assert(!(result & ~mask));
   write32le(location, (read32le(location) & ~mask) | (result & mask));
+  return std::error_code();
 }
 
-static inline void applyThumb32Reloc(uint8_t *location, uint16_t resHi,
-                                     uint16_t resLo, uint16_t maskHi,
-                                     uint16_t maskLo = 0xFFFF) {
+static inline std::error_code applyThumb32Reloc(uint8_t *location,
+                                                uint16_t resHi, uint16_t resLo,
+                                                uint16_t maskHi,
+                                                uint16_t maskLo = 0xFFFF) {
   assert(!(resHi & ~maskHi) && !(resLo & ~maskLo));
   write16le(location, (read16le(location) & ~maskHi) | (resHi & maskHi));
   location += 2;
   write16le(location, (read16le(location) & ~maskLo) | (resLo & maskLo));
+  return std::error_code();
 }
 
-static inline void applyThumb16Reloc(uint8_t *location, uint16_t result,
-                                     uint16_t mask = 0xFFFF) {
+static inline std::error_code
+applyThumb16Reloc(uint8_t *location, uint16_t result, uint16_t mask = 0xFFFF) {
   assert(!(result & ~mask));
   write16le(location, (read16le(location) & ~mask) | (result & mask));
+  return std::error_code();
 }
 
 /// \brief R_ARM_ABS32 - (S + A) | T
-static void relocR_ARM_ABS32(uint8_t *location, uint64_t P, uint64_t S,
-                             int64_t A, bool addressesThumb) {
+static std::error_code relocR_ARM_ABS32(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);
 
@@ -145,12 +150,13 @@ static void relocR_ARM_ABS32(uint8_t *lo
         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);
+  return applyArmReloc(location, result);
 }
 
 /// \brief R_ARM_REL32 - ((S + A) | T) - P
-static void relocR_ARM_REL32(uint8_t *location, uint64_t P, uint64_t S,
-                             int64_t A, bool addressesThumb) {
+static std::error_code relocR_ARM_REL32(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);
 
@@ -160,12 +166,13 @@ static void relocR_ARM_REL32(uint8_t *lo
         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);
+  return applyArmReloc(location, result);
 }
 
 /// \brief R_ARM_PREL31 - ((S + A) | T) - P
-static void relocR_ARM_PREL31(uint8_t *location, uint64_t P, uint64_t S,
-                              int64_t A, bool addressesThumb) {
+static std::error_code relocR_ARM_PREL31(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 mask = 0x7FFFFFFF;
@@ -179,11 +186,12 @@ static void relocR_ARM_PREL31(uint8_t *l
         llvm::dbgs() << " result: 0x" << Twine::utohexstr(result);
         llvm::dbgs() << " rel31: 0x" << Twine::utohexstr(rel31) << "\n");
 
-  applyArmReloc(location, rel31, mask);
+  return applyArmReloc(location, rel31, mask);
 }
 
 /// \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) {
+static std::error_code relocR_ARM_THM_B_L(uint8_t *location, uint32_t result,
+                                          bool useJs) {
   result = (result & 0x01FFFFFE) >> 1;
 
   const uint16_t imm10 = (result >> 11) & 0x3FF;
@@ -197,12 +205,13 @@ static void relocR_ARM_THM_B_L(uint8_t *
   const uint16_t bitI1 = (~(bitJ1 ^ bitS)) & 0x1;
   const uint16_t resLo = (bitI1 << 13) | (bitI2 << 11) | imm11;
 
-  applyThumb32Reloc(location, resHi, resLo, 0x7FF, 0x2FFF);
+  return applyThumb32Reloc(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) {
+static std::error_code 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;
 
@@ -218,16 +227,19 @@ static void relocR_ARM_THM_CALL(uint8_t
         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 (auto ec = relocR_ARM_THM_B_L(location, result, useJs))
+    return ec;
 
   if (switchMode) {
-    applyThumb32Reloc(location, 0, 0, 0, 0x1001);
+    return applyThumb32Reloc(location, 0, 0, 0, 0x1001);
   }
+  return std::error_code();
 }
 
 /// \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) {
+static std::error_code 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);
 
@@ -237,12 +249,12 @@ static void relocR_ARM_THM_JUMP24(uint8_
         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);
+  return relocR_ARM_THM_B_L(location, result, true);
 }
 
 /// \brief R_ARM_THM_JUMP11 - S + A - P
-static void relocR_ARM_THM_JUMP11(uint8_t *location, uint64_t P, uint64_t S,
-                                  int64_t A) {
+static std::error_code relocR_ARM_THM_JUMP11(uint8_t *location, uint64_t P,
+                                             uint64_t S, int64_t A) {
   uint32_t result = (uint32_t)(S + A - P);
 
   DEBUG(llvm::dbgs() << "\t\tHandle " << LLVM_FUNCTION_NAME << " -";
@@ -253,37 +265,38 @@ static void relocR_ARM_THM_JUMP11(uint8_
 
   // we cut off first bit because it is always 1 according to p. 4.5.3
   result = (result & 0x0FFE) >> 1;
-
-  applyThumb16Reloc(location, result, 0x7FF);
+  return applyThumb16Reloc(location, result, 0x7FF);
 }
 
 /// \brief R_ARM_BASE_PREL - B(S) + A - P => S + A - P
-static void relocR_ARM_BASE_PREL(uint8_t *location, uint64_t P, uint64_t S,
-                                 int64_t A) {
+static std::error_code relocR_ARM_BASE_PREL(uint8_t *location, uint64_t P,
+                                            uint64_t S, int64_t A) {
   uint32_t result = (uint32_t)(S + A - P);
   DEBUG(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");
-  applyArmReloc(location, result);
+  return applyArmReloc(location, result);
 }
 
 /// \brief R_ARM_GOT_BREL - GOT(S) + A - GOT_ORG => S + A - GOT_ORG
-static void relocR_ARM_GOT_BREL(uint8_t *location, uint64_t P, uint64_t S,
-                                int64_t A, uint64_t GOT_ORG) {
+static std::error_code relocR_ARM_GOT_BREL(uint8_t *location, uint64_t P,
+                                           uint64_t S, int64_t A,
+                                           uint64_t GOT_ORG) {
   uint32_t result = (uint32_t)(S + A - GOT_ORG);
   DEBUG(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");
-  applyArmReloc(location, result);
+  return applyArmReloc(location, result);
 }
 
 /// \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, bool addressesThumb) {
+static std::error_code relocR_ARM_CALL(uint8_t *location, uint64_t P,
+                                       uint64_t S, int64_t A,
+                                       bool addressesThumb) {
   uint64_t T = addressesThumb;
   const bool switchMode = addressesThumb;
 
@@ -296,17 +309,20 @@ static void relocR_ARM_CALL(uint8_t *loc
         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 (auto ec = applyArmReloc(location, imm24, 0xFFFFFF))
+    return ec;
 
   if (switchMode) {
     const uint32_t bitH = (result & 0x2) >> 1;
-    applyArmReloc(location, (0xFA | bitH) << 24, 0xFF000000);
+    return applyArmReloc(location, (0xFA | bitH) << 24, 0xFF000000);
   }
+  return std::error_code();
 }
 
 /// \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) {
+static std::error_code 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;
@@ -317,20 +333,21 @@ static void relocR_ARM_JUMP24(uint8_t *l
         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);
+  return applyArmReloc(location, imm24, 0xFFFFFF);
 }
 
 /// \brief Relocate ARM MOVW/MOVT instructions
-static void relocR_ARM_MOV(uint8_t *location, uint32_t result) {
+static std::error_code 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);
+  return 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) {
+static std::error_code 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;
@@ -345,8 +362,8 @@ static void relocR_ARM_MOVW_ABS_NC(uint8
 }
 
 /// \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) {
+static std::error_code 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;
 
@@ -359,7 +376,7 @@ static void relocR_ARM_MOVT_ABS(uint8_t
 }
 
 /// \brief Relocate Thumb MOVW/MOVT instructions
-static void relocR_ARM_THM_MOV(uint8_t *location, uint32_t result) {
+static std::error_code 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;
@@ -368,13 +385,13 @@ static void relocR_ARM_THM_MOV(uint8_t *
   const uint16_t bitI = (result >> 11) & 0x1;
   const uint16_t resHi = (bitI << 10) | imm4;
 
-  applyThumb32Reloc(location, resHi, resLo, 0x40F, 0x70FF);
+  return applyThumb32Reloc(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) {
+static std::error_code 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;
@@ -389,8 +406,8 @@ static void relocR_ARM_THM_MOVW_ABS_NC(u
 }
 
 /// \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) {
+static std::error_code 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;
 
@@ -403,8 +420,8 @@ static void relocR_ARM_THM_MOVT_ABS(uint
 }
 
 /// \brief R_ARM_TLS_IE32 - GOT(S) + A - P => S + A - P
-static void relocR_ARM_TLS_IE32(uint8_t *location, uint64_t P, uint64_t S,
-                                int64_t A) {
+static std::error_code relocR_ARM_TLS_IE32(uint8_t *location, uint64_t P,
+                                           uint64_t S, int64_t A) {
   uint32_t result = (uint32_t)(S + A - P);
 
   DEBUG(llvm::dbgs() << "\t\tHandle " << LLVM_FUNCTION_NAME << " -";
@@ -412,12 +429,13 @@ static void relocR_ARM_TLS_IE32(uint8_t
         llvm::dbgs() << " A: 0x" << Twine::utohexstr(A);
         llvm::dbgs() << " P: 0x" << Twine::utohexstr(P);
         llvm::dbgs() << " result: 0x" << Twine::utohexstr(result) << "\n");
-  applyArmReloc(location, result);
+  return applyArmReloc(location, result);
 }
 
 /// \brief R_ARM_TLS_LE32 - S + A - tp => S + A + tpoff
-static void relocR_ARM_TLS_LE32(uint8_t *location, uint64_t P, uint64_t S,
-                                int64_t A, uint64_t tpoff) {
+static std::error_code relocR_ARM_TLS_LE32(uint8_t *location, uint64_t P,
+                                           uint64_t S, int64_t A,
+                                           uint64_t tpoff) {
   uint32_t result = (uint32_t)(S + A + tpoff);
 
   DEBUG(llvm::dbgs() << "\t\tHandle " << LLVM_FUNCTION_NAME << " -";
@@ -425,12 +443,12 @@ static void relocR_ARM_TLS_LE32(uint8_t
         llvm::dbgs() << " A: 0x" << Twine::utohexstr(A);
         llvm::dbgs() << " P: 0x" << Twine::utohexstr(P);
         llvm::dbgs() << " result: 0x" << Twine::utohexstr(result) << "\n");
-  applyArmReloc(location, result);
+  return applyArmReloc(location, result);
 }
 
 /// \brief R_ARM_TLS_TPOFF32 - S + A - tp => S + A (offset within TLS block)
-static void relocR_ARM_TLS_TPOFF32(uint8_t *location, uint64_t P, uint64_t S,
-                                   int64_t A) {
+static std::error_code relocR_ARM_TLS_TPOFF32(uint8_t *location, uint64_t P,
+                                              uint64_t S, int64_t A) {
   uint32_t result = (uint32_t)(S + A);
 
   DEBUG(llvm::dbgs() << "\t\tHandle " << LLVM_FUNCTION_NAME << " -";
@@ -438,23 +456,24 @@ static void relocR_ARM_TLS_TPOFF32(uint8
         llvm::dbgs() << " A: 0x" << Twine::utohexstr(A);
         llvm::dbgs() << " P: 0x" << Twine::utohexstr(P);
         llvm::dbgs() << " result: 0x" << Twine::utohexstr(result) << "\n");
-  applyArmReloc(location, result);
+  return applyArmReloc(location, result);
 }
 
 template <uint32_t lshift>
-static void relocR_ARM_ALU_PC_GN_NC(uint8_t *location, uint32_t result) {
+static std::error_code relocR_ARM_ALU_PC_GN_NC(uint8_t *location,
+                                               uint32_t result) {
   static_assert(lshift < 32 && lshift % 2 == 0,
                 "lshift must be even and less than word size");
 
   const uint32_t rshift = 32 - lshift;
   result = ((result >> lshift) & 0xFF) | ((rshift / 2) << 8);
 
-  applyArmReloc(location, result, 0xFFF);
+  return applyArmReloc(location, result, 0xFFF);
 }
 
 /// \brief R_ARM_ALU_PC_G0_NC - ((S + A) | T) - P => S + A - P
-static void relocR_ARM_ALU_PC_G0_NC(uint8_t *location, uint64_t P, uint64_t S,
-                                    int64_t A) {
+static std::error_code relocR_ARM_ALU_PC_G0_NC(uint8_t *location, uint64_t P,
+                                               uint64_t S, int64_t A) {
   int32_t result = (int32_t)(S + A - P);
 
   if (result < 0)
@@ -468,12 +487,12 @@ static void relocR_ARM_ALU_PC_G0_NC(uint
         llvm::dbgs() << " result: 0x" << Twine::utohexstr((uint32_t)result)
                      << "\n");
 
-  relocR_ARM_ALU_PC_GN_NC<20>(location, (uint32_t)result);
+  return relocR_ARM_ALU_PC_GN_NC<20>(location, (uint32_t)result);
 }
 
 /// \brief R_ARM_ALU_PC_G1_NC - ((S + A) | T) - P => S + A - P
-static void relocR_ARM_ALU_PC_G1_NC(uint8_t *location, uint64_t P, uint64_t S,
-                                    int64_t A) {
+static std::error_code relocR_ARM_ALU_PC_G1_NC(uint8_t *location, uint64_t P,
+                                               uint64_t S, int64_t A) {
   int32_t result = (int32_t)(S + A - P);
 
   if (result < 0)
@@ -487,12 +506,12 @@ static void relocR_ARM_ALU_PC_G1_NC(uint
         llvm::dbgs() << " result: 0x" << Twine::utohexstr((uint32_t)result)
                      << "\n");
 
-  relocR_ARM_ALU_PC_GN_NC<12>(location, (uint32_t)result);
+  return relocR_ARM_ALU_PC_GN_NC<12>(location, (uint32_t)result);
 }
 
 /// \brief R_ARM_LDR_PC_G2 - S + A - P
-static void relocR_ARM_LDR_PC_G2(uint8_t *location, uint64_t P, uint64_t S,
-                                 int64_t A) {
+static std::error_code relocR_ARM_LDR_PC_G2(uint8_t *location, uint64_t P,
+                                            uint64_t S, int64_t A) {
   int32_t result = (int32_t)(S + A - P);
 
   if (result < 0)
@@ -507,13 +526,13 @@ static void relocR_ARM_LDR_PC_G2(uint8_t
                      << "\n");
 
   const uint32_t mask = 0xFFF;
-  applyArmReloc(location, (uint32_t)result & mask, mask);
+  return applyArmReloc(location, (uint32_t)result & mask, mask);
 }
 
 /// \brief Fixup unresolved weak reference with NOP instruction
 static bool fixupUnresolvedWeakCall(uint8_t *location,
                                     Reference::KindValue kindValue) {
-  //TODO: workaround for archs without NOP instruction
+  // TODO: workaround for archs without NOP instruction
   switch (kindValue) {
   case R_ARM_THM_CALL:
   case R_ARM_THM_JUMP24:





More information about the llvm-commits mailing list