Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Add linker support for ELF on ARM

Add support for ELF objects on ARM to the runtime linker. While the list of
relocation types in the "ELF for the ARM Architecture" specification spans four
pages, we thankfully only see a handful of these in the wild. Thus, at the
moment we only support the following .rel relocation types,

 * R_ARM_ABS32
 * R_ARM_TARGET1
 * R_ARM_REL32
 * R_ARM_CALL
 * R_ARM_JUMP24
 * R_ARM_MOVT_ABS
 * R_ARM_MOVW_ABS_NC
 * R_ARM_THM_CALL
 * R_ARM_THM_JUMP24
 * R_ARM_THM_MOVT_ABS
 * R_ARM_THM_MOVW_ABS_NC
 * R_ARM_THM_JUMP8
 * R_ARM_THM_JUMP11

Signed-off-by: Ben Gamari <bgamari.foss@gmail.com>
  • Loading branch information...
commit c3018b21597c06979893a58da1a75db8db1ced94 1 parent 8dae5d4
Ben Gamari authored October 12, 2011
2  mk/config.mk.in
@@ -172,7 +172,7 @@ GhcWithSMP=$(strip $(if $(filter YESNO, $(ArchSupportsSMP)$(GhcUnregisterised)),
172 172
 # has support for this OS/ARCH combination.
173 173
 
174 174
 OsSupportsGHCi=$(strip $(patsubst $(HostOS_CPP), YES, $(findstring $(HostOS_CPP), mingw32 cygwin32 linux solaris2 freebsd dragonfly netbsd openbsd darwin kfreebsdgnu)))
175  
-ArchSupportsGHCi=$(strip $(patsubst $(HostArch_CPP), YES, $(findstring $(HostArch_CPP), i386 x86_64 powerpc sparc sparc64)))
  175
+ArchSupportsGHCi=$(strip $(patsubst $(HostArch_CPP), YES, $(findstring $(HostArch_CPP), i386 x86_64 powerpc sparc sparc64 arm)))
176 176
 
177 177
 ifeq "$(OsSupportsGHCi)$(ArchSupportsGHCi)" "YESYES"
178 178
 GhcWithInterpreter=YES
345  rts/Linker.c
@@ -178,7 +178,7 @@ static pathchar* pathdup(pathchar *path)
178 178
 static int ocVerifyImage_ELF    ( ObjectCode* oc );
179 179
 static int ocGetNames_ELF       ( ObjectCode* oc );
180 180
 static int ocResolve_ELF        ( ObjectCode* oc );
181  
-#if defined(powerpc_HOST_ARCH) || defined(x86_64_HOST_ARCH)
  181
+#if defined(powerpc_HOST_ARCH) || defined(x86_64_HOST_ARCH) || defined(arm_HOST_ARCH)
182 182
 static int ocAllocateSymbolExtras_ELF ( ObjectCode* oc );
183 183
 #endif
184 184
 #elif defined(OBJFORMAT_PEi386)
@@ -2259,7 +2259,7 @@ loadOc( ObjectCode* oc ) {
2259 2259
        IF_DEBUG(linker, debugBelch("loadOc: ocAllocateSymbolExtras_MachO failed\n"));
2260 2260
        return r;
2261 2261
    }
2262  
-#  elif defined(OBJFORMAT_ELF) && (defined(powerpc_HOST_ARCH) || defined(x86_64_HOST_ARCH))
  2262
+#  elif defined(OBJFORMAT_ELF) && (defined(powerpc_HOST_ARCH) || defined(x86_64_HOST_ARCH) || defined(arm_HOST_ARCH))
2263 2263
    r = ocAllocateSymbolExtras_ELF ( oc );
2264 2264
    if (!r) {
2265 2265
        IF_DEBUG(linker, debugBelch("loadOc: ocAllocateSymbolExtras_ELF failed\n"));
@@ -2464,13 +2464,13 @@ addSection ( ObjectCode* oc, SectionKind kind,
2464 2464
  * them right next to the object code itself.
2465 2465
  */
2466 2466
 
2467  
-#if defined(powerpc_HOST_ARCH) || defined(x86_64_HOST_ARCH)
  2467
+#if defined(powerpc_HOST_ARCH) || defined(x86_64_HOST_ARCH) || defined(arm_HOST_ARCH)
2468 2468
 
2469 2469
 /*
2470 2470
   ocAllocateSymbolExtras
2471 2471
 
2472 2472
   Allocate additional space at the end of the object file image to make room
2473  
-  for jump islands (powerpc, x86_64) and GOT entries (x86_64).
  2473
+  for jump islands (powerpc, x86_64, arm) and GOT entries (x86_64).
2474 2474
 
2475 2475
   PowerPC relative branch instructions have a 24 bit displacement field.
2476 2476
   As PPC code is always 4-byte-aligned, this yields a +-32MB range.
@@ -2543,6 +2543,23 @@ static int ocAllocateSymbolExtras( ObjectCode* oc, int count, int first )
2543 2543
   return 1;
2544 2544
 }
2545 2545
 
  2546
+#endif // defined(powerpc_HOST_ARCH) || defined(x86_64_HOST_ARCH) || defined(arm_HOST_ARCH)
  2547
+
  2548
+#if defined(arm_HOST_ARCH)
  2549
+
  2550
+static void
  2551
+ocFlushInstructionCache( ObjectCode *oc )
  2552
+{
  2553
+    // Object code
  2554
+    __clear_cache(oc->image, oc->image + oc->fileSize);
  2555
+    // Jump islands
  2556
+    __clear_cache(oc->symbol_extras, &oc->symbol_extras[oc->n_symbol_extras]);
  2557
+}
  2558
+
  2559
+#endif
  2560
+
  2561
+#if defined(powerpc_HOST_ARCH) || defined(x86_64_HOST_ARCH)
  2562
+
2546 2563
 static SymbolExtra* makeSymbolExtra( ObjectCode* oc,
2547 2564
                                      unsigned long symbolNumber,
2548 2565
                                      unsigned long target )
@@ -2570,7 +2587,7 @@ static SymbolExtra* makeSymbolExtra( ObjectCode* oc,
2570 2587
   extra->jumpIsland.bctr        = 0x4e800420;
2571 2588
 #endif
2572 2589
 #ifdef x86_64_HOST_ARCH
2573  
-        // jmp *-14(%rip)
  2590
+  // jmp *-14(%rip)
2574 2591
   static uint8_t jmp[] = { 0xFF, 0x25, 0xF2, 0xFF, 0xFF, 0xFF };
2575 2592
   extra->addr = target;
2576 2593
   memcpy(extra->jumpIsland, jmp, 6);
@@ -2579,7 +2596,72 @@ static SymbolExtra* makeSymbolExtra( ObjectCode* oc,
2579 2596
   return extra;
2580 2597
 }
2581 2598
 
2582  
-#endif
  2599
+#endif // defined(powerpc_HOST_ARCH) || defined(x86_64_HOST_ARCH)
  2600
+
  2601
+#ifdef arm_HOST_ARCH
  2602
+static SymbolExtra* makeArmSymbolExtra( ObjectCode* oc,
  2603
+                                        unsigned long symbolNumber,
  2604
+                                        unsigned long target,
  2605
+                                        int fromThumb,
  2606
+                                        int toThumb )
  2607
+{
  2608
+  SymbolExtra *extra;
  2609
+
  2610
+  ASSERT( symbolNumber >= oc->first_symbol_extra
  2611
+        && symbolNumber - oc->first_symbol_extra < oc->n_symbol_extras);
  2612
+
  2613
+  extra = &oc->symbol_extras[symbolNumber - oc->first_symbol_extra];
  2614
+
  2615
+  // Make sure instruction mode bit is set properly
  2616
+  if (toThumb)
  2617
+    target |= 1;
  2618
+  else
  2619
+    target &= ~1;
  2620
+
  2621
+  if (!fromThumb) {
  2622
+    // In ARM encoding:
  2623
+    //   movw r12, #0
  2624
+    //   movt r12, #0
  2625
+    //   bx r12
  2626
+    uint32_t code[] = { 0xe300c000, 0xe340c000, 0xe12fff1c };
  2627
+
  2628
+    // Patch lower half-word into movw
  2629
+    code[0] |= ((target>>12) & 0xf) << 16;
  2630
+    code[0] |= target & 0xfff;
  2631
+    // Patch upper half-word into movt
  2632
+    target >>= 16;
  2633
+    code[1] |= ((target>>12) & 0xf) << 16;
  2634
+    code[1] |= target & 0xfff;
  2635
+
  2636
+    memcpy(extra->jumpIsland, code, 12);
  2637
+
  2638
+  } else {
  2639
+    // In Thumb encoding:
  2640
+    //   movw r12, #0
  2641
+    //   movt r12, #0
  2642
+    //   bx r12
  2643
+    uint16_t code[] = { 0xf240,  0x0c00,
  2644
+                        0xf2c0,  0x0c00,
  2645
+                        0x4760 };
  2646
+
  2647
+    // Patch lower half-word into movw
  2648
+    code[0] |= (target>>12) & 0xf;
  2649
+    code[0] |= ((target>>11) & 0x1) << 10;
  2650
+    code[1] |= ((target>>8) & 0x7) << 12;
  2651
+    code[1] |= target & 0xff;
  2652
+    // Patch upper half-word into movt
  2653
+    target >>= 16;
  2654
+    code[2] |= (target>>12) & 0xf;
  2655
+    code[2] |= ((target>>11) & 0x1) << 10;
  2656
+    code[3] |= ((target>>8) & 0x7) << 12;
  2657
+    code[3] |= target & 0xff;
  2658
+
  2659
+    memcpy(extra->jumpIsland, code, 10);
  2660
+  }
  2661
+
  2662
+  return extra;
  2663
+}
  2664
+#endif // arm_HOST_ARCH
2583 2665
 
2584 2666
 /* --------------------------------------------------------------------------
2585 2667
  * PowerPC specifics (instruction cache flushing)
@@ -3575,6 +3657,44 @@ ocResolve_PEi386 ( ObjectCode* oc )
3575 3657
 #    define R_X86_64_PC64 24
3576 3658
 #  endif
3577 3659
 
  3660
+/* 
  3661
+ * Workaround for libc implementations (e.g. eglibc) with incomplete
  3662
+ * relocation lists
  3663
+ */
  3664
+#ifndef R_ARM_THM_CALL
  3665
+#  define R_ARM_THM_CALL      10
  3666
+#endif
  3667
+#ifndef R_ARM_CALL
  3668
+#  define R_ARM_CALL      28
  3669
+#endif
  3670
+#ifndef R_ARM_JUMP24
  3671
+#  define R_ARM_JUMP24      29
  3672
+#endif
  3673
+#ifndef R_ARM_THM_JUMP24
  3674
+#  define R_ARM_THM_JUMP24      30
  3675
+#endif
  3676
+#ifndef R_ARM_TARGET1
  3677
+#  define R_ARM_TARGET1      38
  3678
+#endif
  3679
+#ifndef R_ARM_MOVW_ABS_NC
  3680
+#  define R_ARM_MOVW_ABS_NC      43
  3681
+#endif
  3682
+#ifndef R_ARM_MOVT_ABS
  3683
+#  define R_ARM_MOVT_ABS      44
  3684
+#endif
  3685
+#ifndef R_ARM_THM_MOVW_ABS_NC
  3686
+#  define R_ARM_THM_MOVW_ABS_NC   47
  3687
+#endif
  3688
+#ifndef R_ARM_THM_MOVT_ABS
  3689
+#  define R_ARM_THM_MOVT_ABS      48
  3690
+#endif
  3691
+#ifndef R_ARM_THM_JUMP11
  3692
+#  define R_ARM_THM_JUMP11      102
  3693
+#endif
  3694
+#ifndef R_ARM_THM_JUMP8
  3695
+#  define R_ARM_THM_JUMP8      103
  3696
+#endif
  3697
+
3578 3698
 /*
3579 3699
  * Define a set of types which can be used for both ELF32 and ELF64
3580 3700
  */
@@ -3769,6 +3889,9 @@ ocVerifyImage_ELF ( ObjectCode* oc )
3769 3889
 
3770 3890
    IF_DEBUG(linker,debugBelch( "Architecture is " ));
3771 3891
    switch (ehdr->e_machine) {
  3892
+#ifdef EM_ARM
  3893
+      case EM_ARM:   IF_DEBUG(linker,debugBelch( "arm" )); break;
  3894
+#endif
3772 3895
       case EM_386:   IF_DEBUG(linker,debugBelch( "x86" )); break;
3773 3896
 #ifdef EM_SPARC32PLUS
3774 3897
       case EM_SPARC32PLUS:
@@ -4130,7 +4253,7 @@ ocGetNames_ELF ( ObjectCode* oc )
4130 4253
 }
4131 4254
 
4132 4255
 /* Do ELF relocations which lack an explicit addend.  All x86-linux
4133  
-   relocations appear to be of this form. */
  4256
+   and arm-linux relocations appear to be of this form. */
4134 4257
 static int
4135 4258
 do_Elf_Rel_relocations ( ObjectCode* oc, char* ehdrC,
4136 4259
                          Elf_Shdr* shdr, int shnum )
@@ -4178,6 +4301,9 @@ do_Elf_Rel_relocations ( ObjectCode* oc, char* ehdrC,
4178 4301
 #endif
4179 4302
       StgStablePtr stablePtr;
4180 4303
       StgPtr stableVal;
  4304
+#ifdef arm_HOST_ARCH
  4305
+      int is_target_thm=0, T=0;
  4306
+#endif
4181 4307
 
4182 4308
       IF_DEBUG(linker,debugBelch( "Rel entry %3d is raw(%6p %6p)",
4183 4309
                              j, (void*)offset, (void*)info ));
@@ -4213,6 +4339,17 @@ do_Elf_Rel_relocations ( ObjectCode* oc, char* ehdrC,
4213 4339
             return 0;
4214 4340
          }
4215 4341
          IF_DEBUG(linker,debugBelch( "`%s' resolves to %p\n", symbol, (void*)S ));
  4342
+
  4343
+#ifdef arm_HOST_ARCH
  4344
+         // Thumb instructions have bit 0 of symbol's st_value set
  4345
+         is_target_thm = S & 0x1;
  4346
+         T = sym.st_info & STT_FUNC && is_target_thm;
  4347
+
  4348
+         // Make sure we clear bit 0. Strictly speaking we should have done
  4349
+         // this to st_value above but I believe alignment requirements should
  4350
+         // ensure that no instructions start on an odd address
  4351
+         S &= ~1;
  4352
+#endif
4216 4353
       }
4217 4354
 
4218 4355
       IF_DEBUG(linker,debugBelch( "Reloc: P = %p   S = %p   A = %p\n",
@@ -4228,6 +4365,196 @@ do_Elf_Rel_relocations ( ObjectCode* oc, char* ehdrC,
4228 4365
          case R_386_32:   *pP = value;     break;
4229 4366
          case R_386_PC32: *pP = value - P; break;
4230 4367
 #        endif
  4368
+
  4369
+#        ifdef arm_HOST_ARCH
  4370
+         case R_ARM_ABS32:
  4371
+         case R_ARM_TARGET1:  // Specified by Linux ARM ABI to be equivalent to ABS32
  4372
+            *(Elf32_Word *)P += S;
  4373
+            *(Elf32_Word *)P |= T;
  4374
+            break;
  4375
+
  4376
+         case R_ARM_REL32:
  4377
+            *(Elf32_Word *)P += S;
  4378
+            *(Elf32_Word *)P |= T;
  4379
+            *(Elf32_Word *)P -= P;
  4380
+            break;
  4381
+
  4382
+         case R_ARM_CALL:
  4383
+         case R_ARM_JUMP24:
  4384
+         {
  4385
+            StgWord32 *word = (StgWord32 *)P;
  4386
+            StgInt32 imm = (*word & 0x00ffffff) << 2;
  4387
+            StgInt32 offset;
  4388
+            int overflow;
  4389
+
  4390
+            // Sign extend 24 to 32 bits
  4391
+            if (imm & 0x02000000)
  4392
+               imm -= 0x04000000;
  4393
+            offset = ((S + imm) | T) - P;
  4394
+
  4395
+            overflow = offset <= (StgInt32)0xfe000000 || offset >= (StgInt32)0x02000000;
  4396
+
  4397
+            if ((is_target_thm && ELF_R_TYPE(info) == R_ARM_JUMP24) || overflow) {
  4398
+               // Generate veneer
  4399
+               // The +8 below is to undo the PC-bias compensation done by the object producer
  4400
+               SymbolExtra *extra = makeArmSymbolExtra(oc, ELF_R_SYM(info), S+imm+8, 0, is_target_thm);
  4401
+               // The -8 below is to compensate for PC bias
  4402
+               offset = (StgWord32) &extra->jumpIsland - P - 8;
  4403
+               offset &= ~1; // Clear thumb indicator bit
  4404
+            } else if (is_target_thm && ELF_R_TYPE(info) == R_ARM_CALL) {
  4405
+               StgWord32 cond = (*word & 0xf0000000) >> 28;
  4406
+               if (cond == 0xe) {
  4407
+                  // Change instruction to BLX
  4408
+                  *word |= 0xf0000000; // Set first nibble
  4409
+                  *word = (*word & ~0x01ffffff)
  4410
+                        | ((offset >> 2) & 0x00ffffff)  // imm24
  4411
+                        | ((offset & 0x2) << 23);       // H
  4412
+                  break;
  4413
+               } else {
  4414
+                  errorBelch("%s: Can't transition from ARM to Thumb when cond != 0xe\n",
  4415
+                        oc->fileName);
  4416
+                  return 0;
  4417
+               }
  4418
+            }
  4419
+
  4420
+            offset >>= 2;
  4421
+            *word = (*word & ~0x00ffffff)
  4422
+                  | (offset & 0x00ffffff);
  4423
+            break;
  4424
+         }
  4425
+
  4426
+         case R_ARM_MOVT_ABS:
  4427
+         case R_ARM_MOVW_ABS_NC:
  4428
+         {
  4429
+            StgWord32 *word = (StgWord32 *)P;
  4430
+            StgInt32 offset = ((*word & 0xf0000) >> 4)
  4431
+                            | (*word & 0xfff);
  4432
+            // Sign extend from 16 to 32 bits
  4433
+            offset = (offset ^ 0x8000) - 0x8000;
  4434
+
  4435
+            offset += S;
  4436
+            if (ELF_R_TYPE(info) == R_ARM_MOVT_ABS)
  4437
+               offset >>= 16;
  4438
+            else
  4439
+               offset |= T;
  4440
+
  4441
+            *word = (*word & 0xfff0f000)
  4442
+                  | ((offset & 0xf000) << 4)
  4443
+                  | (offset & 0x0fff);
  4444
+            break;
  4445
+         }
  4446
+
  4447
+         case R_ARM_THM_CALL:
  4448
+         case R_ARM_THM_JUMP24:
  4449
+         {
  4450
+            StgWord16 *upper = (StgWord16 *)P;
  4451
+            StgWord16 *lower = (StgWord16 *)(P + 2);
  4452
+
  4453
+            int overflow;
  4454
+            int to_thm = (*lower >> 12) & 1;
  4455
+            int sign = (*upper >> 10) & 1;
  4456
+            int j1, j2, i1, i2;
  4457
+
  4458
+            // Decode immediate value
  4459
+            j1 = (*lower >> 13) & 1; i1 = ~(j1 ^ sign) & 1;
  4460
+            j2 = (*lower >> 11) & 1; i2 = ~(j2 ^ sign) & 1;
  4461
+            StgInt32 imm = (sign << 24)
  4462
+                         | (i1 << 23)
  4463
+                         | (i2 << 22)
  4464
+                         | ((*upper & 0x03ff) << 12)
  4465
+                         | ((*lower & 0x07ff) << 1);
  4466
+
  4467
+            // Sign extend 25 to 32 bits
  4468
+            if (imm & 0x01000000)
  4469
+               imm -= 0x02000000;
  4470
+
  4471
+            offset = ((imm + S) | T) - P;
  4472
+            overflow = offset <= (StgWord32)0xff000000 || offset >= (StgWord32)0x01000000;
  4473
+
  4474
+            if ((!is_target_thm && ELF_R_TYPE(info) == R_ARM_THM_JUMP24) || overflow) {
  4475
+               // Generate veneer
  4476
+               SymbolExtra *extra = makeArmSymbolExtra(oc, ELF_R_SYM(info), S+imm+4, 1, is_target_thm);
  4477
+               offset = (StgWord32) &extra->jumpIsland - P - 4;
  4478
+               to_thm = 1;
  4479
+            } else if (!is_target_thm && ELF_R_TYPE(info) == R_ARM_THM_CALL) {
  4480
+               offset &= ~0x3;
  4481
+               to_thm = 0;
  4482
+            }
  4483
+
  4484
+            // Reencode instruction
  4485
+            i1 = ~(offset >> 23) & 1; j1 = sign ^ i1;
  4486
+            i2 = ~(offset >> 22) & 1; j2 = sign ^ i2;
  4487
+            *upper = ( (*upper & 0xf800)
  4488
+                   | (sign << 10)
  4489
+                   | ((offset >> 12) & 0x03ff) );
  4490
+            *lower = ( (*lower & 0xd000)
  4491
+                   | (j1 << 13)
  4492
+                   | (to_thm << 12)
  4493
+                   | (j2 << 11)
  4494
+                   | ((offset >> 1) & 0x07ff) );
  4495
+            break;
  4496
+         }
  4497
+
  4498
+         case R_ARM_THM_MOVT_ABS:
  4499
+         case R_ARM_THM_MOVW_ABS_NC:
  4500
+         {
  4501
+            StgWord16 *upper = (StgWord16 *)P;
  4502
+            StgWord16 *lower = (StgWord16 *)(P + 2);
  4503
+            StgInt32 offset = ((*upper & 0x000f) << 12)
  4504
+                            | ((*upper & 0x0400) << 1)
  4505
+                            | ((*lower & 0x7000) >> 4)
  4506
+                            | (*lower & 0x00ff);
  4507
+
  4508
+            offset = (offset ^ 0x8000) - 0x8000; // Sign extend
  4509
+            offset += S;
  4510
+            if (ELF_R_TYPE(info) == R_ARM_THM_MOVW_ABS_NC)
  4511
+                   offset |= T;
  4512
+            else if (ELF_R_TYPE(info) == R_ARM_THM_MOVT_ABS)
  4513
+                   offset >>= 16;
  4514
+
  4515
+            *upper = ( (*upper & 0xfbf0)
  4516
+                   | ((offset & 0xf000) >> 12)
  4517
+                   | ((offset & 0x0800) >> 1) );
  4518
+            *lower = ( (*lower & 0x8f00)
  4519
+                   | ((offset & 0x0700) << 4)
  4520
+                   | (offset & 0x00ff) );
  4521
+            break;
  4522
+         }
  4523
+
  4524
+         case R_ARM_THM_JUMP8:
  4525
+         {
  4526
+            StgWord16 *word = (StgWord16 *)P;
  4527
+            StgWord offset = *word & 0x01fe;
  4528
+            offset += S - P;
  4529
+            if (!is_target_thm) {
  4530
+               errorBelch("%s: Thumb to ARM transition with JUMP8 relocation not supported\n",
  4531
+                     oc->fileName);
  4532
+               return 0;
  4533
+            }
  4534
+
  4535
+            *word = (*word & ~0x01fe)
  4536
+                  | (offset & 0x01fe);
  4537
+            break;
  4538
+         }
  4539
+         
  4540
+         case R_ARM_THM_JUMP11:
  4541
+         {
  4542
+            StgWord16 *word = (StgWord16 *)P;
  4543
+            StgWord offset = *word & 0x0ffe;
  4544
+            offset += S - P;
  4545
+            if (!is_target_thm) {
  4546
+               errorBelch("%s: Thumb to ARM transition with JUMP11 relocation not supported\n",
  4547
+                     oc->fileName);
  4548
+               return 0;
  4549
+            }
  4550
+
  4551
+            *word = (*word & ~0x0ffe)
  4552
+                  | (offset & 0x0ffe);
  4553
+            break;
  4554
+         }
  4555
+
  4556
+#        endif // arm_HOST_ARCH
  4557
+
4231 4558
          default:
4232 4559
             errorBelch("%s: unhandled ELF relocation(Rel) type %lu\n",
4233 4560
                   oc->fileName, (lnat)ELF_R_TYPE(info));
@@ -4553,7 +4880,7 @@ ocResolve_ELF ( ObjectCode* oc )
4553 4880
       }
4554 4881
    }
4555 4882
 
4556  
-#if defined(powerpc_HOST_ARCH)
  4883
+#if defined(powerpc_HOST_ARCH) || defined(arm_HOST_ARCH)
4557 4884
    ocFlushInstructionCache( oc );
4558 4885
 #endif
4559 4886
 
@@ -4564,7 +4891,7 @@ ocResolve_ELF ( ObjectCode* oc )
4564 4891
  * PowerPC & X86_64 ELF specifics
4565 4892
  */
4566 4893
 
4567  
-#if defined(powerpc_HOST_ARCH) || defined(x86_64_HOST_ARCH)
  4894
+#if defined(powerpc_HOST_ARCH) || defined(x86_64_HOST_ARCH) || defined(arm_HOST_ARCH)
4568 4895
 
4569 4896
 static int ocAllocateSymbolExtras_ELF( ObjectCode *oc )
4570 4897
 {
6  rts/LinkerInternals.h
@@ -40,7 +40,7 @@ typedef
40 40
    ProddableBlock;
41 41
 
42 42
 /* Jump Islands are sniplets of machine code required for relative
43  
- * address relocations on the PowerPC.
  43
+ * address relocations on the PowerPC, x86_64 and ARM.
44 44
  */
45 45
 typedef struct {
46 46
 #ifdef powerpc_HOST_ARCH
@@ -53,6 +53,8 @@ typedef struct {
53 53
 #elif x86_64_HOST_ARCH
54 54
     uint64_t    addr;
55 55
     uint8_t     jumpIsland[6];
  56
+#elif arm_HOST_ARCH
  57
+    uint8_t     jumpIsland[16];
56 58
 #endif
57 59
 } SymbolExtra;
58 60
 
@@ -104,7 +106,7 @@ typedef struct _ObjectCode {
104 106
     unsigned int pltIndex;
105 107
 #endif
106 108
 
107  
-#if powerpc_HOST_ARCH || x86_64_HOST_ARCH
  109
+#if powerpc_HOST_ARCH || x86_64_HOST_ARCH || arm_HOST_ARCH
108 110
     SymbolExtra    *symbol_extras;
109 111
     unsigned long   first_symbol_extra;
110 112
     unsigned long   n_symbol_extras;

0 notes on commit c3018b2

Please sign in to comment.
Something went wrong with that request. Please try again.