[lld] 674f094 - [lld][ARM][NFCI][1/3]Big Endian support - Removing assumptions

Simi Pallipurath via llvm-commits llvm-commits at lists.llvm.org
Wed Feb 15 03:42:55 PST 2023


Author: Simi Pallipurath
Date: 2023-02-15T11:42:49Z
New Revision: 674f094d852b773d35e9face1b504ab68473dc86

URL: https://github.com/llvm/llvm-project/commit/674f094d852b773d35e9face1b504ab68473dc86
DIFF: https://github.com/llvm/llvm-project/commit/674f094d852b773d35e9face1b504ab68473dc86.diff

LOG: [lld][ARM][NFCI][1/3]Big Endian support - Removing assumptions

Change:
 - Replacing the memcpy that assume little endian with the endian-aware write.

Shouldn't affect the output for now, just a prerequisite for the next patches.

Reviewed By: MaskRay

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

Added: 
    

Modified: 
    lld/ELF/Arch/ARM.cpp
    lld/ELF/Thunks.cpp

Removed: 
    


################################################################################
diff  --git a/lld/ELF/Arch/ARM.cpp b/lld/ELF/Arch/ARM.cpp
index 180b522b8e5f0..64fc24c49fb91 100644
--- a/lld/ELF/Arch/ARM.cpp
+++ b/lld/ELF/Arch/ARM.cpp
@@ -15,6 +15,7 @@
 
 using namespace llvm;
 using namespace llvm::support::endian;
+using namespace llvm::support;
 using namespace llvm::ELF;
 using namespace lld;
 using namespace lld::elf;
@@ -194,16 +195,14 @@ void ARM::writeIgotPlt(uint8_t *buf, const Symbol &s) const {
 // Long form PLT Header that does not have any restrictions on the displacement
 // of the .plt from the .got.plt.
 static void writePltHeaderLong(uint8_t *buf) {
-  const uint8_t pltData[] = {
-      0x04, 0xe0, 0x2d, 0xe5, //     str lr, [sp,#-4]!
-      0x04, 0xe0, 0x9f, 0xe5, //     ldr lr, L2
-      0x0e, 0xe0, 0x8f, 0xe0, // L1: add lr, pc, lr
-      0x08, 0xf0, 0xbe, 0xe5, //     ldr pc, [lr, #8]
-      0x00, 0x00, 0x00, 0x00, // L2: .word   &(.got.plt) - L1 - 8
-      0xd4, 0xd4, 0xd4, 0xd4, //     Pad to 32-byte boundary
-      0xd4, 0xd4, 0xd4, 0xd4, //     Pad to 32-byte boundary
-      0xd4, 0xd4, 0xd4, 0xd4};
-  memcpy(buf, pltData, sizeof(pltData));
+  write32(buf + 0, 0xe52de004);   //     str lr, [sp,#-4]!
+  write32(buf + 4, 0xe59fe004);   //     ldr lr, L2
+  write32(buf + 8, 0xe08fe00e);   // L1: add lr, pc, lr
+  write32(buf + 12, 0xe5bef008);  //     ldr pc, [lr, #8]
+  write32(buf + 16, 0x00000000);  // L2: .word   &(.got.plt) - L1 - 8
+  write32(buf + 20, 0xd4d4d4d4);  //     Pad to 32-byte boundary
+  write32(buf + 24, 0xd4d4d4d4);  //     Pad to 32-byte boundary
+  write32(buf + 28, 0xd4d4d4d4);
   uint64_t gotPlt = in.gotPlt->getVA();
   uint64_t l1 = in.plt->getVA() + 8;
   write32le(buf + 16, gotPlt - l1 - 8);
@@ -248,13 +247,10 @@ void ARM::addPltHeaderSymbols(InputSection &isec) const {
 // of the .plt from the .got.plt.
 static void writePltLong(uint8_t *buf, uint64_t gotPltEntryAddr,
                          uint64_t pltEntryAddr) {
-  const uint8_t pltData[] = {
-      0x04, 0xc0, 0x9f, 0xe5, //     ldr ip, L2
-      0x0f, 0xc0, 0x8c, 0xe0, // L1: add ip, ip, pc
-      0x00, 0xf0, 0x9c, 0xe5, //     ldr pc, [ip]
-      0x00, 0x00, 0x00, 0x00, // L2: .word   Offset(&(.got.plt) - L1 - 8
-  };
-  memcpy(buf, pltData, sizeof(pltData));
+  write32(buf + 0, 0xe59fc004);   //     ldr ip, L2
+  write32(buf + 4, 0xe08cc00f);   // L1: add ip, ip, pc
+  write32(buf + 8, 0xe59cf000);   //     ldr pc, [ip]
+  write32(buf + 12, 0x00000000);  // L2: .word   Offset(&(.got.plt) - L1 - 8
   uint64_t l1 = pltEntryAddr + 4;
   write32le(buf + 12, gotPltEntryAddr - l1 - 8);
 }

diff  --git a/lld/ELF/Thunks.cpp b/lld/ELF/Thunks.cpp
index 5964196a1bae2..8238b15bcf56b 100644
--- a/lld/ELF/Thunks.cpp
+++ b/lld/ELF/Thunks.cpp
@@ -554,10 +554,7 @@ void ARMThunk::writeTo(uint8_t *buf) {
   uint64_t s = getARMThunkDestVA(destination);
   uint64_t p = getThunkTargetSym()->getVA();
   int64_t offset = s - p - 8;
-  const uint8_t data[] = {
-    0x00, 0x00, 0x00, 0xea, // b S
-  };
-  memcpy(buf, data, sizeof(data));
+  write32(buf, 0xea000000); // b S
   target->relocateNoSym(buf, R_ARM_JUMP24, offset);
 }
 
@@ -600,10 +597,7 @@ void ThumbThunk::writeTo(uint8_t *buf) {
   uint64_t s = getARMThunkDestVA(destination);
   uint64_t p = getThunkTargetSym()->getVA();
   int64_t offset = s - p - 4;
-  const uint8_t data[] = {
-      0x00, 0xf0, 0x00, 0xb0, // b.w S
-  };
-  memcpy(buf, data, sizeof(data));
+  write32(buf, 0xb000f000); // b.w S
   target->relocateNoSym(buf, R_ARM_THM_JUMP24, offset);
 }
 
@@ -618,13 +612,10 @@ bool ThumbThunk::isCompatibleWith(const InputSection &isec,
 }
 
 void ARMV7ABSLongThunk::writeLong(uint8_t *buf) {
-  const uint8_t data[] = {
-      0x00, 0xc0, 0x00, 0xe3, // movw         ip,:lower16:S
-      0x00, 0xc0, 0x40, 0xe3, // movt         ip,:upper16:S
-      0x1c, 0xff, 0x2f, 0xe1, // bx   ip
-  };
+  write32(buf + 0, 0xe300c000); // movw ip,:lower16:S
+  write32(buf + 4, 0xe340c000); // movt ip,:upper16:S
+  write32(buf + 8, 0xe12fff1c); // bx   ip
   uint64_t s = getARMThunkDestVA(destination);
-  memcpy(buf, data, sizeof(data));
   target->relocateNoSym(buf, R_ARM_MOVW_ABS_NC, s);
   target->relocateNoSym(buf + 4, R_ARM_MOVT_ABS, s);
 }
@@ -636,13 +627,12 @@ void ARMV7ABSLongThunk::addSymbols(ThunkSection &isec) {
 }
 
 void ThumbV7ABSLongThunk::writeLong(uint8_t *buf) {
-  const uint8_t data[] = {
-      0x40, 0xf2, 0x00, 0x0c, // movw         ip, :lower16:S
-      0xc0, 0xf2, 0x00, 0x0c, // movt         ip, :upper16:S
-      0x60, 0x47,             // bx   ip
-  };
+  write16(buf + 0, 0xf240); // movw ip, :lower16:S
+  write16(buf + 2, 0x0c00);
+  write16(buf + 4, 0xf2c0); // movt ip, :upper16:S
+  write16(buf + 6, 0x0c00);
+  write16(buf + 8, 0x4760); // bx   ip
   uint64_t s = getARMThunkDestVA(destination);
-  memcpy(buf, data, sizeof(data));
   target->relocateNoSym(buf, R_ARM_THM_MOVW_ABS_NC, s);
   target->relocateNoSym(buf + 4, R_ARM_THM_MOVT_ABS, s);
 }
@@ -654,16 +644,13 @@ void ThumbV7ABSLongThunk::addSymbols(ThunkSection &isec) {
 }
 
 void ARMV7PILongThunk::writeLong(uint8_t *buf) {
-  const uint8_t data[] = {
-      0xf0, 0xcf, 0x0f, 0xe3, // P:  movw ip,:lower16:S - (P + (L1-P) + 8)
-      0x00, 0xc0, 0x40, 0xe3, //     movt ip,:upper16:S - (P + (L1-P) + 8)
-      0x0f, 0xc0, 0x8c, 0xe0, // L1: add  ip, ip, pc
-      0x1c, 0xff, 0x2f, 0xe1, //     bx   ip
-  };
+  write32(buf + 0, 0xe30fcff0);   // P:  movw ip,:lower16:S - (P + (L1-P) + 8)
+  write32(buf + 4, 0xe340c000);   //     movt ip,:upper16:S - (P + (L1-P) + 8)
+  write32(buf + 8, 0xe08cc00f);   // L1: add  ip, ip, pc
+  write32(buf + 12, 0xe12fff1c);  //     bx   ip
   uint64_t s = getARMThunkDestVA(destination);
   uint64_t p = getThunkTargetSym()->getVA();
   int64_t offset = s - p - 16;
-  memcpy(buf, data, sizeof(data));
   target->relocateNoSym(buf, R_ARM_MOVW_PREL_NC, offset);
   target->relocateNoSym(buf + 4, R_ARM_MOVT_PREL, offset);
 }
@@ -675,16 +662,15 @@ void ARMV7PILongThunk::addSymbols(ThunkSection &isec) {
 }
 
 void ThumbV7PILongThunk::writeLong(uint8_t *buf) {
-  const uint8_t data[] = {
-      0x4f, 0xf6, 0xf4, 0x7c, // P:  movw ip,:lower16:S - (P + (L1-P) + 4)
-      0xc0, 0xf2, 0x00, 0x0c, //     movt ip,:upper16:S - (P + (L1-P) + 4)
-      0xfc, 0x44,             // L1: add  ip, pc
-      0x60, 0x47,             //     bx   ip
-  };
+  write16(buf + 0, 0xf64f);   // P:  movw ip,:lower16:S - (P + (L1-P) + 4)
+  write16(buf + 2, 0x7cf4);
+  write16(buf + 4, 0xf2c0);   //     movt ip,:upper16:S - (P + (L1-P) + 4)
+  write16(buf + 6, 0x0c00);
+  write16(buf + 8, 0x44fc);   // L1: add  ip, pc
+  write16(buf + 10, 0x4760);  //     bx   ip
   uint64_t s = getARMThunkDestVA(destination);
   uint64_t p = getThunkTargetSym()->getVA() & ~0x1;
   int64_t offset = s - p - 12;
-  memcpy(buf, data, sizeof(data));
   target->relocateNoSym(buf, R_ARM_THM_MOVW_PREL_NC, offset);
   target->relocateNoSym(buf + 4, R_ARM_THM_MOVT_PREL, offset);
 }
@@ -700,15 +686,12 @@ void ThumbV6MABSLongThunk::writeLong(uint8_t *buf) {
   // only register we can corrupt is r12 we must instead spill a low register
   // to the stack to use as a scratch register. We push r1 even though we
   // don't need to get some space to use for the return address.
-  const uint8_t data[] = {
-      0x03, 0xb4,            // push {r0, r1} ; Obtain scratch registers
-      0x01, 0x48,            // ldr r0, [pc, #4] ; L1
-      0x01, 0x90,            // str r0, [sp, #4] ; SP + 4 = S
-      0x01, 0xbd,            // pop {r0, pc} ; restore r0 and branch to dest
-      0x00, 0x00, 0x00, 0x00 // L1: .word S
-  };
+  write16(buf + 0, 0xb403);   // push {r0, r1} ; Obtain scratch registers
+  write16(buf + 2, 0x4801);   // ldr r0, [pc, #4] ; L1
+  write16(buf + 4, 0x9001);   // str r0, [sp, #4] ; SP + 4 = S
+  write16(buf + 6, 0xbd01);   // pop {r0, pc} ; restore r0 and branch to dest
+  write32(buf + 8, 0x00000000);   // L1: .word S
   uint64_t s = getARMThunkDestVA(destination);
-  memcpy(buf, data, sizeof(data));
   target->relocateNoSym(buf + 8, R_ARM_ABS32, s);
 }
 
@@ -723,18 +706,15 @@ void ThumbV6MPILongThunk::writeLong(uint8_t *buf) {
   // Most Thumb instructions cannot access the high registers r8 - r15. As the
   // only register we can corrupt is ip (r12) we must instead spill a low
   // register to the stack to use as a scratch register.
-  const uint8_t data[] = {
-      0x01, 0xb4,             // P:  push {r0}        ; Obtain scratch register
-      0x02, 0x48,             //     ldr r0, [pc, #8] ; L2
-      0x84, 0x46,             //     mov ip, r0       ; high to low register
-      0x01, 0xbc,             //     pop {r0}         ; restore scratch register
-      0xe7, 0x44,             // L1: add pc, ip       ; transfer control
-      0xc0, 0x46,             //     nop              ; pad to 4-byte boundary
-      0x00, 0x00, 0x00, 0x00, // L2: .word S - (P + (L1 - P) + 4)
-  };
+  write16(buf + 0, 0xb401);   // P:  push {r0}        ; Obtain scratch register
+  write16(buf + 2, 0x4802);   //     ldr r0, [pc, #8] ; L2
+  write16(buf + 4, 0x4684);   //     mov ip, r0       ; high to low register
+  write16(buf + 6, 0xbc01);   //     pop {r0}         ; restore scratch register
+  write16(buf + 8, 0x44e7);   // L1: add pc, ip       ; transfer control
+  write16(buf + 10, 0x46c0);  //     nop              ; pad to 4-byte boundary
+  write32(buf + 12, 0x00000000);  // L2: .word S - (P + (L1 - P) + 4)
   uint64_t s = getARMThunkDestVA(destination);
   uint64_t p = getThunkTargetSym()->getVA() & ~0x1;
-  memcpy(buf, data, sizeof(data));
   target->relocateNoSym(buf + 12, R_ARM_REL32, s - p - 12);
 }
 
@@ -746,11 +726,8 @@ void ThumbV6MPILongThunk::addSymbols(ThunkSection &isec) {
 }
 
 void ARMV5LongLdrPcThunk::writeLong(uint8_t *buf) {
-  const uint8_t data[] = {
-      0x04, 0xf0, 0x1f, 0xe5, // ldr pc, [pc,#-4] ; L1
-      0x00, 0x00, 0x00, 0x00, // L1: .word S
-  };
-  memcpy(buf, data, sizeof(data));
+  write32(buf + 0, 0xe51ff004); // ldr pc, [pc,#-4] ; L1
+  write32(buf + 4, 0x00000000); // L1: .word S
   target->relocateNoSym(buf + 4, R_ARM_ABS32, getARMThunkDestVA(destination));
 }
 
@@ -762,12 +739,9 @@ void ARMV5LongLdrPcThunk::addSymbols(ThunkSection &isec) {
 }
 
 void ARMV4ABSLongBXThunk::writeLong(uint8_t *buf) {
-  const uint8_t data[] = {
-      0x00, 0xc0, 0x9f, 0xe5, // ldr r12, [pc] ; L1
-      0x1c, 0xff, 0x2f, 0xe1, // bx r12
-      0x00, 0x00, 0x00, 0x00, // L1: .word S
-  };
-  memcpy(buf, data, sizeof(data));
+  write32(buf + 0, 0xe59fc000); // ldr r12, [pc] ; L1
+  write32(buf + 4, 0xe12fff1c); // bx r12
+  write32(buf + 8, 0x00000000); // L1: .word S
   target->relocateNoSym(buf + 8, R_ARM_ABS32, getARMThunkDestVA(destination));
 }
 
@@ -779,13 +753,10 @@ void ARMV4ABSLongBXThunk::addSymbols(ThunkSection &isec) {
 }
 
 void ThumbV4ABSLongBXThunk::writeLong(uint8_t *buf) {
-  const uint8_t data[] = {
-      0x78, 0x47,             // bx pc
-      0xfd, 0xe7,             // b #-6 ; Arm recommended sequence to follow bx pc
-      0x04, 0xf0, 0x1f, 0xe5, // ldr pc, [pc, #-4] ; L1
-      0x00, 0x00, 0x00, 0x00, // L1: .word S
-  };
-  memcpy(buf, data, sizeof(data));
+  write16(buf + 0, 0x4778); // bx pc
+  write16(buf + 2, 0xe7fd); // b #-6 ; Arm recommended sequence to follow bx pc
+  write32(buf + 4, 0xe51ff004); // ldr pc, [pc, #-4] ; L1
+  write32(buf + 8, 0x00000000); // L1: .word S
   target->relocateNoSym(buf + 8, R_ARM_ABS32, getARMThunkDestVA(destination));
 }
 
@@ -798,14 +769,11 @@ void ThumbV4ABSLongBXThunk::addSymbols(ThunkSection &isec) {
 }
 
 void ThumbV4ABSLongThunk::writeLong(uint8_t *buf) {
-  const uint8_t data[] = {
-      0x78, 0x47,             // bx pc
-      0xfd, 0xe7,             // b #-6 ; Arm recommended sequence to follow bx pc
-      0x00, 0xc0, 0x9f, 0xe5, // ldr r12, [pc] ; L1
-      0x1c, 0xff, 0x2f, 0xe1, // bx r12
-      0x00, 0x00, 0x00, 0x00, // L1: .word S
-  };
-  memcpy(buf, data, sizeof(data));
+  write16(buf + 0, 0x4778); // bx pc
+  write16(buf + 2, 0xe7fd); // b #-6 ; Arm recommended sequence to follow bx pc
+  write32(buf + 4, 0xe59fc000); // ldr r12, [pc] ; L1
+  write32(buf + 8, 0xe12fff1c); // bx r12
+  write32(buf + 12, 0x00000000); // L1: .word S
   target->relocateNoSym(buf + 12, R_ARM_ABS32, getARMThunkDestVA(destination));
 }
 
@@ -818,15 +786,12 @@ void ThumbV4ABSLongThunk::addSymbols(ThunkSection &isec) {
 }
 
 void ARMV4PILongBXThunk::writeLong(uint8_t *buf) {
-  const uint8_t data[] = {
-      0x04, 0xc0, 0x9f, 0xe5, // P:  ldr ip, [pc,#4] ; L2
-      0x0c, 0xc0, 0x8f, 0xe0, // L1: add ip, pc, ip
-      0x1c, 0xff, 0x2f, 0xe1, //     bx ip
-      0x00, 0x00, 0x00, 0x00, // L2: .word S - (P + (L1 - P) + 8)
-  };
+  write32(buf + 0, 0xe59fc004); // P:  ldr ip, [pc,#4] ; L2
+  write32(buf + 4, 0xe08fc00c);	// L1: add ip, pc, ip
+  write32(buf + 8, 0xe12fff1c);	//     bx ip
+  write32(buf + 12, 0x00000000); // L2: .word S - (P + (L1 - P) + 8)
   uint64_t s = getARMThunkDestVA(destination);
   uint64_t p = getThunkTargetSym()->getVA() & ~0x1;
-  memcpy(buf, data, sizeof(data));
   target->relocateNoSym(buf + 12, R_ARM_REL32, s - p - 12);
 }
 
@@ -838,14 +803,11 @@ void ARMV4PILongBXThunk::addSymbols(ThunkSection &isec) {
 }
 
 void ARMV4PILongThunk::writeLong(uint8_t *buf) {
-  const uint8_t data[] = {
-      0x00, 0xc0, 0x9f, 0xe5, // P:  ldr ip, [pc] ; L2
-      0x0c, 0xf0, 0x8f, 0xe0, // L1: add pc, pc, r12
-      0x00, 0x00, 0x00, 0x00, // L2: .word S - (P + (L1 - P) + 8)
-  };
+  write32(buf + 0, 0xe59fc000); // P:  ldr ip, [pc] ; L2
+  write32(buf + 4, 0xe08ff00c); // L1: add pc, pc, r12
+  write32(buf + 8, 0x00000000); // L2: .word S - (P + (L1 - P) + 8)
   uint64_t s = getARMThunkDestVA(destination);
   uint64_t p = getThunkTargetSym()->getVA() & ~0x1;
-  memcpy(buf, data, sizeof(data));
   target->relocateNoSym(buf + 8, R_ARM_REL32, s - p - 12);
 }
 
@@ -857,16 +819,13 @@ void ARMV4PILongThunk::addSymbols(ThunkSection &isec) {
 }
 
 void ThumbV4PILongBXThunk::writeLong(uint8_t *buf) {
-  const uint8_t data[] = {
-      0x78, 0x47,             // P:  bx pc
-      0xfd, 0xe7,             //     b #-6 ; Arm recommended sequence to follow bx pc
-      0x00, 0xc0, 0x9f, 0xe5, //     ldr r12, [pc] ; L2
-      0x0f, 0xf0, 0x8c, 0xe0, // L1: add pc, r12, pc
-      0x00, 0x00, 0x00, 0x00, // L2: .word S - (P + (L1 - P) + 8)
-  };
+  write16(buf + 0, 0x4778); // P:  bx pc
+  write16(buf + 2, 0xe7fd); //     b #-6 ; Arm recommended sequence to follow bx pc
+  write32(buf + 4, 0xe59fc000); //     ldr r12, [pc] ; L2
+  write32(buf + 8, 0xe08cf00f); // L1: add pc, r12, pc
+  write32(buf + 12, 0x00000000); // L2: .word S - (P + (L1 - P) + 8)
   uint64_t s = getARMThunkDestVA(destination);
   uint64_t p = getThunkTargetSym()->getVA() & ~0x1;
-  memcpy(buf, data, sizeof(data));
   target->relocateNoSym(buf + 12, R_ARM_REL32, s - p - 16);
 }
 
@@ -879,17 +838,14 @@ void ThumbV4PILongBXThunk::addSymbols(ThunkSection &isec) {
 }
 
 void ThumbV4PILongThunk::writeLong(uint8_t *buf) {
-  const uint8_t data[] = {
-      0x78, 0x47,             // P:  bx pc
-      0xfd, 0xe7,             //     b #-6 ; Arm recommended sequence to follow bx pc
-      0x04, 0xc0, 0x9f, 0xe5, //     ldr ip, [pc,#4] ; L2
-      0x0c, 0xc0, 0x8f, 0xe0, // L1: add ip, pc, ip
-      0x1c, 0xff, 0x2f, 0xe1, //     bx ip
-      0x00, 0x00, 0x00, 0x00, // L2: .word S - (P + (L1 - P) + 8)
-  };
+  write16(buf + 0, 0x4778); // P:  bx pc
+  write16(buf + 2, 0xe7fd); //     b #-6 ; Arm recommended sequence to follow bx pc
+  write32(buf + 4, 0xe59fc004); //     ldr ip, [pc,#4] ; L2
+  write32(buf + 8, 0xe08fc00c); // L1: add ip, pc, ip
+  write32(buf + 12, 0xe12fff1c); //     bx ip
+  write32(buf + 16, 0x00000000); // L2: .word S - (P + (L1 - P) + 8)
   uint64_t s = getARMThunkDestVA(destination);
   uint64_t p = getThunkTargetSym()->getVA() & ~0x1;
-  memcpy(buf, data, sizeof(data));
   target->relocateNoSym(buf + 16, R_ARM_REL32, s - p - 16);
 }
 


        


More information about the llvm-commits mailing list