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

Collapse All | Expand All

(-)a/bfd/elf32-arm.c (-42 / +146 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 of 16-bit and 32-bit instructions,
2160
     an 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
  /* NOTE: As this is a mixture of 16-bit and 32-bit instructions,
2173
     an instruction maybe encoded to one or two array elements.  */
2174
  0x0c00f240,		/* movw    ip, #0xNNNN    */
2175
  0x0c00f2c0,		/* movt    ip, #0xNNNN    */
2176
  0xf8dc44fc,           /* add     ip, pc         */
2177
  0xbf00f000            /* ldr.w   pc, [ip]       */
2178
                        /* nop                    */
2179
};
2153
2180
2154
/* The format of the first entry in the procedure linkage table
2181
/* The format of the first entry in the procedure linkage table
2155
   for a VxWorks executable.  */
2182
   for a VxWorks executable.  */
Lines 3317-3322 create_ifunc_sections (struct bfd_link_info *info) Link Here
3317
  return TRUE;
3344
  return TRUE;
3318
}
3345
}
3319
3346
3347
/* Determine if we're dealing with a Thumb only architecture.  */
3348
3349
static bfd_boolean
3350
using_thumb_only (struct elf32_arm_link_hash_table *globals)
3351
{
3352
  int arch = bfd_elf_get_obj_attr_int (globals->obfd, OBJ_ATTR_PROC,
3353
				       Tag_CPU_arch);
3354
  int profile;
3355
3356
  if (arch == TAG_CPU_ARCH_V6_M || arch == TAG_CPU_ARCH_V6S_M)
3357
    return TRUE;
3358
3359
  if (arch != TAG_CPU_ARCH_V7 && arch != TAG_CPU_ARCH_V7E_M)
3360
    return FALSE;
3361
3362
  profile = bfd_elf_get_obj_attr_int (globals->obfd, OBJ_ATTR_PROC,
3363
				      Tag_CPU_arch_profile);
3364
3365
  return profile == 'M';
3366
}
3367
3368
/* Determine if we're dealing with a Thumb-2 object.  */
3369
3370
static bfd_boolean
3371
using_thumb2 (struct elf32_arm_link_hash_table *globals)
3372
{
3373
  int arch = bfd_elf_get_obj_attr_int (globals->obfd, OBJ_ATTR_PROC,
3374
				       Tag_CPU_arch);
3375
  return arch == TAG_CPU_ARCH_V6T2 || arch >= TAG_CPU_ARCH_V7;
3376
}
3377
3320
/* Create .plt, .rel(a).plt, .got, .got.plt, .rel(a).got, .dynbss, and
3378
/* 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
3379
   .rel(a).bss sections in DYNOBJ, and set up shortcuts to them in our
3322
   hash table.  */
3380
   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);
3418
	    = 4 * ARRAY_SIZE (elf32_arm_vxworks_exec_plt_entry);
3361
	}
3419
	}
3362
    }
3420
    }
3421
  else
3422
    {
3423
      /* PR ld/16017
3424
	 Test for thumb only architectures.  Note - we cannot just call
3425
	 using_thumb_only() as the attributes in the output bfd have not been
3426
	 initialised at this point, so instead we use the input bfd.  */
3427
      bfd * saved_obfd = htab->obfd;
3428
3429
      htab->obfd = dynobj;
3430
      if (using_thumb_only (htab))
3431
	{
3432
	  htab->plt_header_size = 4 * ARRAY_SIZE (elf32_thumb2_plt0_entry);
3433
	  htab->plt_entry_size  = 4 * ARRAY_SIZE (elf32_thumb2_plt_entry);
3434
	}
3435
      htab->obfd = saved_obfd;
3436
    }
3363
3437
3364
  if (!htab->root.splt
3438
  if (!htab->root.splt
3365
      || !htab->root.srelplt
3439
      || !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);
3565
  _bfd_elf_link_hash_table_free (hash);
3492
}
3566
}
3493
3567
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.  */
3568
/* Determine what kind of NOPs are available.  */
3526
3569
3527
static bfd_boolean
3570
static bfd_boolean
Lines 7689-7701 elf32_arm_populate_plt_entry (bfd *output_bfd, struct bfd_link_info *info, Link Here
7689
	}
7732
	}
7690
      else if (using_thumb_only (htab))
7733
      else if (using_thumb_only (htab))
7691
	{
7734
	{
7692
	  /* PR ld/16017: Do not generate ARM instructions for
7735
	  /* PR ld/16017: Generate thumb only PLT entries.  */
7693
	     the PLT if compiling for a thumb-only target.
7736
          if (!using_thumb2 (htab))
7737
	    {
7738
	      /* FIXME: We ought to be able to generate thumb-1 PLT
7739
		 instructions...  */
7740
	      _bfd_error_handler (_("%B: Warning: thumb-1 mode PLT generation not currently supported"),
7741
				  output_bfd);
7742
	      return FALSE;
7743
	    }
7694
7744
7695
	     FIXME: We ought to be able to generate thumb PLT instructions...  */
7745
	  /* Calculate the displacement between the PLT slot and the entry in
7696
	  _bfd_error_handler (_("%B: Warning: thumb mode PLT generation not currently supported"),
7746
	     the GOT.  The 12-byte offset accounts for the value produced by
7697
			      output_bfd);
7747
	     adding to pc in the 3rd instruction of the PLT stub.  */
7698
	  return FALSE;
7748
	  got_displacement = got_address - (plt_address + 12);
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 & 0x000000ff) << 16)
7755
			| ((got_displacement & 0x00000700) << 20)
7756
			| ((got_displacement & 0x00000800) >>  1)
7757
			| ((got_displacement & 0x0000f000) >> 12),
7758
			ptr + 0);
7759
	  put_arm_insn (htab, output_bfd,
7760
			elf32_thumb2_plt_entry[1]
7761
			| ((got_displacement & 0x00ff0000)      )
7762
			| ((got_displacement & 0x07000000) <<  4)
7763
			| ((got_displacement & 0x08000000) >> 17)
7764
			| ((got_displacement & 0xf0000000) >> 28),
7765
			ptr + 4);
7766
	  put_arm_insn (htab, output_bfd,
7767
			elf32_thumb2_plt_entry[2],
7768
			ptr + 8);
7769
	  put_arm_insn (htab, output_bfd,
7770
			elf32_thumb2_plt_entry[3],
7771
			ptr + 12);
7699
	}
7772
	}
7700
      else
7773
      else
7701
	{
7774
	{
Lines 8918-8924 elf32_arm_final_link_relocate (reloc_howto_type * howto, Link Here
8918
		     + splt->output_offset
8991
		     + splt->output_offset
8919
		     + plt_offset);
8992
		     + plt_offset);
8920
8993
8921
	    if (globals->use_blx && r_type == R_ARM_THM_CALL)
8994
	    if (globals->use_blx
8995
		&& r_type == R_ARM_THM_CALL
8996
		&& ! using_thumb_only (globals))
8922
	      {
8997
	      {
8923
		/* If the Thumb BLX instruction is available, convert
8998
		/* If the Thumb BLX instruction is available, convert
8924
		   the BL to a BLX instruction to call the ARM-mode
8999
		   the BL to a BLX instruction to call the ARM-mode
Lines 8928-8935 elf32_arm_final_link_relocate (reloc_howto_type * howto, Link Here
8928
	      }
9003
	      }
8929
	    else
9004
	    else
8930
	      {
9005
	      {
8931
		/* Target the Thumb stub before the ARM PLT entry.  */
9006
		if (! using_thumb_only (globals))
8932
		value -= PLT_THUMB_STUB_SIZE;
9007
		  /* Target the Thumb stub before the ARM PLT entry.  */
9008
		  value -= PLT_THUMB_STUB_SIZE;
8933
		branch_type = ST_BRANCH_TO_THUMB;
9009
		branch_type = ST_BRANCH_TO_THUMB;
8934
	      }
9010
	      }
8935
	    *unresolved_reloc_p = FALSE;
9011
	    *unresolved_reloc_p = FALSE;
Lines 14384-14389 elf32_arm_finish_dynamic_sections (bfd * output_bfd, struct bfd_link_info * info Link Here
14384
	  else if (htab->nacl_p)
14460
	  else if (htab->nacl_p)
14385
	    arm_nacl_put_plt0 (htab, output_bfd, splt,
14461
	    arm_nacl_put_plt0 (htab, output_bfd, splt,
14386
			       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
	    }
14387
	  else
14477
	  else
14388
	    {
14478
	    {
14389
	      got_displacement = got_address - (plt_address + 16);
14479
	      got_displacement = got_address - (plt_address + 16);
Lines 14722-14727 elf32_arm_output_plt_map_1 (output_arch_syminfo *osi, Link Here
14722
      if (!elf32_arm_output_map_sym (osi, ARM_MAP_ARM, addr))
14812
      if (!elf32_arm_output_map_sym (osi, ARM_MAP_ARM, addr))
14723
	return FALSE;
14813
	return FALSE;
14724
    }
14814
    }
14815
  else if (using_thumb_only (htab))
14816
    {
14817
      if (!elf32_arm_output_map_sym (osi, ARM_MAP_THUMB, addr))
14818
	return FALSE;
14819
    }  
14725
  else
14820
  else
14726
    {
14821
    {
14727
      bfd_boolean thumb_stub_p;
14822
      bfd_boolean thumb_stub_p;
Lines 15053-15058 elf32_arm_output_arch_local_syms (bfd *output_bfd, Link Here
15053
	  if (!elf32_arm_output_map_sym (&osi, ARM_MAP_ARM, 0))
15148
	  if (!elf32_arm_output_map_sym (&osi, ARM_MAP_ARM, 0))
15054
	    return FALSE;
15149
	    return FALSE;
15055
	}
15150
	}
15151
      else if (using_thumb_only (htab))
15152
	{
15153
	  if (!elf32_arm_output_map_sym (&osi, ARM_MAP_THUMB, 0))
15154
	    return FALSE;
15155
	  if (!elf32_arm_output_map_sym (&osi, ARM_MAP_DATA, 12))
15156
	    return FALSE;
15157
	  if (!elf32_arm_output_map_sym (&osi, ARM_MAP_THUMB, 16))
15158
	    return FALSE;
15159
	}
15056
      else if (!htab->symbian_p)
15160
      else if (!htab->symbian_p)
15057
	{
15161
	{
15058
	  if (!elf32_arm_output_map_sym (&osi, ARM_MAP_ARM, 0))
15162
	  if (!elf32_arm_output_map_sym (&osi, ARM_MAP_ARM, 0))

Return to bug 16017