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

Collapse All | Expand All

(-)a/bfd/elf32-arm.c (-42 / +131 lines)
Lines 2125-2131 static const bfd_vma elf32_arm_plt_entry [] = Link Here
2125
  0x00000000,		/* unused		*/
2125
  0x00000000,		/* unused		*/
2126
};
2126
};
2127
2127
2128
#else
2128
#else /* not FOUR_WORD_PLT */
2129
2129
2130
/* The first entry in a procedure linkage table looks like
2130
/* The first entry in a procedure linkage table looks like
2131
   this.  It is set up so that any shared library function that is
2131
   this.  It is set up so that any shared library function that is
Lines 2149-2155 static const bfd_vma elf32_arm_plt_entry [] = Link Here
2149
  0xe5bcf000,		/* ldr	 pc, [ip, #0xNNN]!  */
2149
  0xe5bcf000,		/* ldr	 pc, [ip, #0xNNN]!  */
2150
};
2150
};
2151
2151
2152
#endif
2152
#endif /* not FOUR_WORD_PLT */
2153
2154
/* The first entry in a procedure linkage table looks like this.
2155
   It is set up so that any shared library function that is called before the
2156
   relocation has been set up calls the dynamic linker first.  */
2157
static const bfd_vma elf32_thumb2_plt0_entry [] =
2158
{
2159
  /* NOTE: As this is a mixture between 16-bit and 32-bit instrutions, a 
2160
     instruction maybe encoded to one or two array elements.  */
2161
  0xf8dfb500,		/* push    {lr}          */
2162
  0x44fee008,		/* ldr.w   lr, [pc, #8]  */
2163
                        /* add     lr, pc        */
2164
  0xff08f85e,		/* ldr.w   pc, [lr, #8]! */
2165
  0x00000000,		/* &GOT[0] - .           */
2166
};
2167
2168
/* Subsequent entries in a procedure linkage table for thumb only target
2169
   look like this.  */
2170
static const bfd_vma elf32_thumb2_plt_entry [] =
2171
{
2172
  0x0c00f240,		/* movw    ip, #0xNNNN    */
2173
  0x3c0cea4f,		/* lsl     ip, #12        */
2174
  0x0c00f20f,		/* addw    ip, pc, #0xNNN */
2175
  0xf000f8dc,		/* ldr     pc, [ip]       */
2176
};
2153
2177
2154
/* The format of the first entry in the procedure linkage table
2178
/* The format of the first entry in the procedure linkage table
2155
   for a VxWorks executable.  */
2179
   for a VxWorks executable.  */
Lines 3317-3322 create_ifunc_sections (struct bfd_link_info *info) Link Here
3317
  return TRUE;
3341
  return TRUE;
3318
}
3342
}
3319
3343
3344
/* Determine if we're dealing with a Thumb only architecture.  */
3345
3346
static bfd_boolean
3347
using_thumb_only (struct elf32_arm_link_hash_table *globals)
3348
{
3349
  int arch = bfd_elf_get_obj_attr_int (globals->obfd, OBJ_ATTR_PROC,
3350
				       Tag_CPU_arch);
3351
  int profile;
3352
3353
  if (arch == TAG_CPU_ARCH_V6_M || arch == TAG_CPU_ARCH_V6S_M)
3354
    return TRUE;
3355
3356
  if (arch != TAG_CPU_ARCH_V7 && arch != TAG_CPU_ARCH_V7E_M)
3357
    return FALSE;
3358
3359
  profile = bfd_elf_get_obj_attr_int (globals->obfd, OBJ_ATTR_PROC,
3360
				      Tag_CPU_arch_profile);
3361
3362
  return profile == 'M';
3363
}
3364
3365
/* Determine if we're dealing with a Thumb-2 object.  */
3366
3367
static bfd_boolean
3368
using_thumb2 (struct elf32_arm_link_hash_table *globals)
3369
{
3370
  int arch = bfd_elf_get_obj_attr_int (globals->obfd, OBJ_ATTR_PROC,
3371
				       Tag_CPU_arch);
3372
  return arch == TAG_CPU_ARCH_V6T2 || arch >= TAG_CPU_ARCH_V7;
3373
}
3374
3320
/* Create .plt, .rel(a).plt, .got, .got.plt, .rel(a).got, .dynbss, and
3375
/* 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
3376
   .rel(a).bss sections in DYNOBJ, and set up shortcuts to them in our
3322
   hash table.  */
3377
   hash table.  */
Lines 3360-3365 elf32_arm_create_dynamic_sections (bfd *dynobj, struct bfd_link_info *info) Link Here
3360
	    = 4 * ARRAY_SIZE (elf32_arm_vxworks_exec_plt_entry);
3415
	    = 4 * ARRAY_SIZE (elf32_arm_vxworks_exec_plt_entry);
3361
	}
3416
	}
3362
    }
3417
    }
3418
  else
3419
    {
3420
      /* PR ld/16017
3421
	 Test for thumb only architectures.  Note - we cannot just call
3422
	 using_thumb_only() as the attributes in the output bfd have not been
3423
	 initialised at this point, so instead we use the input bfd.  */
3424
      bfd * saved_obfd = htab->obfd;
3425
3426
      htab->obfd = dynobj;
3427
      if (using_thumb_only (htab))
3428
	{
3429
	  htab->plt_header_size = 4 * ARRAY_SIZE (elf32_thumb2_plt0_entry);
3430
	  htab->plt_entry_size  = 4 * ARRAY_SIZE (elf32_thumb2_plt_entry);
3431
	}
3432
      htab->obfd = saved_obfd;
3433
    }
3363
3434
3364
  if (!htab->root.splt
3435
  if (!htab->root.splt
3365
      || !htab->root.srelplt
3436
      || !htab->root.srelplt
Lines 3491-3527 elf32_arm_hash_table_free (struct bfd_link_hash_table *hash) Link Here
3491
  _bfd_elf_link_hash_table_free (hash);
3562
  _bfd_elf_link_hash_table_free (hash);
3492
}
3563
}
3493
3564
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.  */
3565
/* Determine what kind of NOPs are available.  */
3526
3566
3527
static bfd_boolean
3567
static bfd_boolean
Lines 7689-7701 elf32_arm_populate_plt_entry (bfd *output_bfd, struct bfd_link_info *info, Link Here
7689
	}
7729
	}
7690
      else if (using_thumb_only (htab))
7730
      else if (using_thumb_only (htab))
7691
	{
7731
	{
7692
	  /* PR ld/16017: Do not generate ARM instructions for
7732
	  /* PR ld/16017: Generate thumb only PLT entries.  */
7693
	     the PLT if compiling for a thumb-only target.
7694
7733
7695
	     FIXME: We ought to be able to generate thumb PLT instructions...  */
7734
          if (!using_thumb2 (htab))
7696
	  _bfd_error_handler (_("%B: Warning: thumb mode PLT generation not currently supported"),
7735
	    {
7697
			      output_bfd);
7736
	      /* FIXME: We ought to be able to generate thumb-1 PLT
7698
	  return FALSE;
7737
		 instructions...  */
7738
	      _bfd_error_handler (_("%B: Warning: thumb-1 mode PLT generation not currently supported"),
7739
				  output_bfd);
7740
	      return FALSE;
7741
	    }
7742
7743
	  /* Calculate the displacement between the PLT slot and the entry in
7744
	     the GOT.  The 12-byte offset accounts for the value produced by
7745
	     adding to pc in the 3rd instruction of the PLT stub.  */
7746
	  got_displacement = got_address - (plt_address + 12);
7747
7748
	  BFD_ASSERT ((got_displacement & 0xf0000000) == 0);
7749
7750
	  /* As we are using 32 bit instructions we have to use 'put_arm_insn'
7751
	     instead of 'put_thumb_insn'.  */
7752
	  put_arm_insn (htab, output_bfd,
7753
			elf32_thumb2_plt_entry[0]
7754
			| ((got_displacement & 0x000ff000) <<  4)
7755
			| ((got_displacement & 0x00700000) <<  8)
7756
			| ((got_displacement & 0x00800000) >> 13)
7757
			| ((got_displacement & 0x0f000000) >> 24),
7758
			ptr + 0);
7759
	  put_arm_insn (htab, output_bfd,
7760
			elf32_thumb2_plt_entry[1],
7761
			ptr + 4);
7762
	  put_arm_insn (htab, output_bfd,
7763
			elf32_thumb2_plt_entry[2]
7764
			| ((got_displacement & 0x000000ff) <<  16)
7765
			| ((got_displacement & 0x00000700) <<  20)
7766
			| ((got_displacement & 0x00000800) >>  1),
7767
			ptr + 8);
7768
	  put_arm_insn (htab, output_bfd,
7769
			elf32_thumb2_plt_entry[3],
7770
			ptr + 12);
7699
	}
7771
	}
7700
      else
7772
      else
7701
	{
7773
	{
Lines 8912-8918 elf32_arm_final_link_relocate (reloc_howto_type * howto, Link Here
8912
		     + splt->output_offset
8984
		     + splt->output_offset
8913
		     + plt_offset);
8985
		     + plt_offset);
8914
8986
8915
	    if (globals->use_blx && r_type == R_ARM_THM_CALL)
8987
	    if (globals->use_blx
8988
		&& r_type == R_ARM_THM_CALL
8989
		&& ! using_thumb_only (globals))
8916
	      {
8990
	      {
8917
		/* If the Thumb BLX instruction is available, convert
8991
		/* If the Thumb BLX instruction is available, convert
8918
		   the BL to a BLX instruction to call the ARM-mode
8992
		   the BL to a BLX instruction to call the ARM-mode
Lines 8922-8929 elf32_arm_final_link_relocate (reloc_howto_type * howto, Link Here
8922
	      }
8996
	      }
8923
	    else
8997
	    else
8924
	      {
8998
	      {
8925
		/* Target the Thumb stub before the ARM PLT entry.  */
8999
		if (! using_thumb_only (globals))
8926
		value -= PLT_THUMB_STUB_SIZE;
9000
		  /* Target the Thumb stub before the ARM PLT entry.  */
9001
		  value -= PLT_THUMB_STUB_SIZE;
8927
		branch_type = ST_BRANCH_TO_THUMB;
9002
		branch_type = ST_BRANCH_TO_THUMB;
8928
	      }
9003
	      }
8929
	    *unresolved_reloc_p = FALSE;
9004
	    *unresolved_reloc_p = FALSE;
Lines 14385-14390 elf32_arm_finish_dynamic_sections (bfd * output_bfd, struct bfd_link_info * info Link Here
14385
	  else if (htab->nacl_p)
14460
	  else if (htab->nacl_p)
14386
	    arm_nacl_put_plt0 (htab, output_bfd, splt,
14461
	    arm_nacl_put_plt0 (htab, output_bfd, splt,
14387
			       got_address + 8 - (plt_address + 16));
14462
			       got_address + 8 - (plt_address + 16));
14463
	  else if (using_thumb_only (htab))
14464
	    {
14465
	      got_displacement = got_address - (plt_address + 12);
14466
14467
	      plt0_entry = elf32_thumb2_plt0_entry;
14468
	      put_arm_insn (htab, output_bfd, plt0_entry[0],
14469
			    splt->contents + 0);
14470
	      put_arm_insn (htab, output_bfd, plt0_entry[1],
14471
			    splt->contents + 4);
14472
	      put_arm_insn (htab, output_bfd, plt0_entry[2],
14473
			    splt->contents + 8);
14474
14475
	      bfd_put_32 (output_bfd, got_displacement, splt->contents + 12);
14476
	    }
14388
	  else
14477
	  else
14389
	    {
14478
	    {
14390
	      got_displacement = got_address - (plt_address + 16);
14479
	      got_displacement = got_address - (plt_address + 16);

Return to bug 16017