View | Details | Raw Unified | Return to bug 16017 | Differences between
and this patch

Collapse All | Expand All

(-)a/bfd/elf32-arm.c (-37 / +114 lines)
Lines 2151-2156 static const bfd_vma elf32_arm_plt_entry [] = Link Here
2151
2151
2152
#endif
2152
#endif
2153
2153
2154
/* The first entry in a procedure linkage table looks like
2155
   this.  It is set up so that any shared library function that is
2156
   called before the relocation has been set up calls the dynamic
2157
   linker first.  */
2158
static const bfd_vma elf32_thumb2_plt0_entry [] =
2159
{
2160
  /* NOTE: As this is a mixture between 16-bit and 32-bit instrutions, a 
2161
     instruction maybe encoded to one or two array elements.  */
2162
  0xf8dfb500,		/* push    {lr}          */
2163
  0x44fee008,		/* ldr.w   lr, [pc, #8]  */
2164
                        /* add     lr, pc        */
2165
  0xff08f85e,		/* ldr.w   pc, [lr, #8]! */
2166
  0x00000000,		/* &GOT[0] - .           */
2167
};
2168
2169
/* Subsequent entries in a procedure linkage table for thumb only target look like
2170
   this.  */
2171
static const bfd_vma elf32_thumb2_plt_entry [] =
2172
{
2173
  0x0c00f240,		/* movw    ip, #0xNNNN    */
2174
  0x3c0cea4f,		/* lsl     ip, #12        */
2175
  0x0c00f20f,		/* addw    ip, pc, #0xNNN */
2176
  0xf000f8dc,		/* ldr     pc, [ip]       */
2177
};
2178
2154
/* The format of the first entry in the procedure linkage table
2179
/* The format of the first entry in the procedure linkage table
2155
   for a VxWorks executable.  */
2180
   for a VxWorks executable.  */
2156
static const bfd_vma elf32_arm_vxworks_exec_plt0_entry[] =
2181
static const bfd_vma elf32_arm_vxworks_exec_plt0_entry[] =
Lines 3317-3322 create_ifunc_sections (struct bfd_link_info *info) Link Here
3317
  return TRUE;
3342
  return TRUE;
3318
}
3343
}
3319
3344
3345
/* Determine if we're dealing with a Thumb only architecture.  */
3346
3347
static bfd_boolean
3348
using_thumb_only (struct elf32_arm_link_hash_table *globals)
3349
{
3350
  int arch = bfd_elf_get_obj_attr_int (globals->obfd, OBJ_ATTR_PROC,
3351
				       Tag_CPU_arch);
3352
  int profile;
3353
3354
  if (arch == TAG_CPU_ARCH_V6_M || arch == TAG_CPU_ARCH_V6S_M)
3355
    return TRUE;
3356
3357
  if (arch != TAG_CPU_ARCH_V7 && arch != TAG_CPU_ARCH_V7E_M)
3358
    return FALSE;
3359
3360
  profile = bfd_elf_get_obj_attr_int (globals->obfd, OBJ_ATTR_PROC,
3361
				      Tag_CPU_arch_profile);
3362
3363
  return profile == 'M';
3364
}
3365
3366
/* Determine if we're dealing with a Thumb-2 object.  */
3367
3368
static bfd_boolean
3369
using_thumb2 (struct elf32_arm_link_hash_table *globals)
3370
{
3371
  int arch = bfd_elf_get_obj_attr_int (globals->obfd, OBJ_ATTR_PROC,
3372
				       Tag_CPU_arch);
3373
  return arch == TAG_CPU_ARCH_V6T2 || arch >= TAG_CPU_ARCH_V7;
3374
}
3375
3320
/* Create .plt, .rel(a).plt, .got, .got.plt, .rel(a).got, .dynbss, and
3376
/* Create .plt, .rel(a).plt, .got, .got.plt, .rel(a).got, .dynbss, and
3321
   .rel(a).bss sections in DYNOBJ, and set up shortcuts to them in our
3377
   .rel(a).bss sections in DYNOBJ, and set up shortcuts to them in our
3322
   hash table.  */
3378
   hash table.  */
Lines 3359-3364 elf32_arm_create_dynamic_sections (bfd *dynobj, struct bfd_link_info *info) Link Here
3359
	  htab->plt_entry_size
3415
	  htab->plt_entry_size
3360
	    = 4 * ARRAY_SIZE (elf32_arm_vxworks_exec_plt_entry);
3416
	    = 4 * ARRAY_SIZE (elf32_arm_vxworks_exec_plt_entry);
3361
	}
3417
	}
3418
    } 
3419
  else if(using_thumb_only (htab))
3420
    {
3421
        htab->plt_header_size = 4 * ARRAY_SIZE (elf32_thumb2_plt0_entry);
3422
        htab->plt_entry_size = 4 * ARRAY_SIZE (elf32_thumb2_plt_entry);
3362
    }
3423
    }
3363
3424
3364
  if (!htab->root.splt
3425
  if (!htab->root.splt
Lines 3491-3527 elf32_arm_hash_table_free (struct bfd_link_hash_table *hash) Link Here
3491
  _bfd_elf_link_hash_table_free (hash);
3552
  _bfd_elf_link_hash_table_free (hash);
3492
}
3553
}
3493
3554
3494
/* Determine if we're dealing with a Thumb only architecture.  */
3495
3496
static bfd_boolean
3497
using_thumb_only (struct elf32_arm_link_hash_table *globals)
3498
{
3499
  int arch = bfd_elf_get_obj_attr_int (globals->obfd, OBJ_ATTR_PROC,
3500
				       Tag_CPU_arch);
3501
  int profile;
3502
3503
  if (arch == TAG_CPU_ARCH_V6_M || arch == TAG_CPU_ARCH_V6S_M)
3504
    return TRUE;
3505
3506
  if (arch != TAG_CPU_ARCH_V7 && arch != TAG_CPU_ARCH_V7E_M)
3507
    return FALSE;
3508
3509
  profile = bfd_elf_get_obj_attr_int (globals->obfd, OBJ_ATTR_PROC,
3510
				      Tag_CPU_arch_profile);
3511
3512
  return profile == 'M';
3513
}
3514
3515
/* Determine if we're dealing with a Thumb-2 object.  */
3516
3517
static bfd_boolean
3518
using_thumb2 (struct elf32_arm_link_hash_table *globals)
3519
{
3520
  int arch = bfd_elf_get_obj_attr_int (globals->obfd, OBJ_ATTR_PROC,
3521
				       Tag_CPU_arch);
3522
  return arch == TAG_CPU_ARCH_V6T2 || arch >= TAG_CPU_ARCH_V7;
3523
}
3524
3525
/* Determine what kind of NOPs are available.  */
3555
/* Determine what kind of NOPs are available.  */
3526
3556
3527
static bfd_boolean
3557
static bfd_boolean
Lines 7689-7701 elf32_arm_populate_plt_entry (bfd *output_bfd, struct bfd_link_info *info, Link Here
7689
	}
7719
	}
7690
      else if (using_thumb_only (htab))
7720
      else if (using_thumb_only (htab))
7691
	{
7721
	{
7692
	  /* PR ld/16017: Do not generate ARM instructions for
7722
          if(!using_thumb2(htab))
7693
	     the PLT if compiling for a thumb-only target.
7723
	  {
7724
         /* PR ld/16017: Do not generate ARM instructions for
7725
            the PLT if compiling for a thumb-only target.
7694
7726
7695
	     FIXME: We ought to be able to generate thumb PLT instructions...  */
7727
            FIXME: We ought to be able to generate thumb-1 PLT instructions...  */
7696
	  _bfd_error_handler (_("%B: Warning: thumb mode PLT generation not currently supported"),
7728
         _bfd_error_handler (_("%B: Warning: thumb-1 mode PLT generation not currently supported"),
7697
			      output_bfd);
7729
                             output_bfd);
7698
	  return FALSE;
7730
         return FALSE;
7731
7732
	  }
7733
	  /* Calculate the displacement between the PLT slot and the
7734
	     entry in the GOT.  The 12-byte offset accounts for the
7735
	     value produced by adding to pc in the 3rd instruction
7736
	     of the PLT stub.  */
7737
	  got_displacement = got_address - (plt_address + 12);
7738
7739
	  BFD_ASSERT ((got_displacement & 0xf0000000) == 0);
7740
7741
	  /* As we are using 32 bit instructions we have to use 'put_arm_insn'
7742
	     instead of 'put_thumb_insn'.  */
7743
	  put_arm_insn (htab, output_bfd,
7744
			elf32_thumb2_plt_entry[0]
7745
			| ((got_displacement & 0x000ff000) <<  4)
7746
			| ((got_displacement & 0x00700000) <<  8)
7747
			| ((got_displacement & 0x00800000) >> 13)
7748
			| ((got_displacement & 0x0f000000) >> 24),
7749
			ptr + 0);
7750
	  put_arm_insn (htab, output_bfd,
7751
			elf32_thumb2_plt_entry[1],
7752
			ptr + 4);
7753
	  put_arm_insn (htab, output_bfd,
7754
			elf32_thumb2_plt_entry[2]
7755
			| ((got_displacement & 0x000000ff) <<  16)
7756
			| ((got_displacement & 0x00000700) <<  20)
7757
			| ((got_displacement & 0x00000800) >>  1),
7758
			ptr + 8);
7759
	  put_arm_insn (htab, output_bfd,
7760
			elf32_thumb2_plt_entry[3],
7761
			ptr + 12);
7699
	}
7762
	}
7700
      else
7763
      else
7701
	{
7764
	{
Lines 14385-14390 elf32_arm_finish_dynamic_sections (bfd * output_bfd, struct bfd_link_info * info Link Here
14385
	  else if (htab->nacl_p)
14448
	  else if (htab->nacl_p)
14386
	    arm_nacl_put_plt0 (htab, output_bfd, splt,
14449
	    arm_nacl_put_plt0 (htab, output_bfd, splt,
14387
			       got_address + 8 - (plt_address + 16));
14450
			       got_address + 8 - (plt_address + 16));
14451
	  else if (using_thumb_only(htab))
14452
	    {
14453
	      got_displacement = got_address - (plt_address + 12);
14454
14455
	      plt0_entry = elf32_thumb2_plt0_entry;
14456
	      put_arm_insn (htab, output_bfd, plt0_entry[0],
14457
			    splt->contents + 0);
14458
	      put_arm_insn (htab, output_bfd, plt0_entry[1],
14459
			    splt->contents + 4);
14460
	      put_arm_insn (htab, output_bfd, plt0_entry[2],
14461
			    splt->contents + 8);
14462
14463
	      bfd_put_32 (output_bfd, got_displacement, splt->contents + 12);
14464
	    }
14388
	  else
14465
	  else
14389
	    {
14466
	    {
14390
	      got_displacement = got_address - (plt_address + 16);
14467
	      got_displacement = got_address - (plt_address + 16);

Return to bug 16017