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

Collapse All | Expand All

(-)a/bfd/elf32-arm.c (-42 / +147 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, #0x0NNN    */
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
	  BFD_ASSERT ((got_displacement & 0xf0000000) == 0);
7751
7752
	  /* As we are using 32 bit instructions we have to use 'put_arm_insn'
7753
	     instead of 'put_thumb_insn'.  */
7754
	  put_arm_insn (htab, output_bfd,
7755
			elf32_thumb2_plt_entry[0]
7756
			| ((got_displacement & 0x000000ff) << 16)
7757
			| ((got_displacement & 0x00000700) << 20)
7758
			| ((got_displacement & 0x00800800) >>  1)
7759
			| ((got_displacement & 0x0000f000) >> 12),
7760
			ptr + 0);
7761
	  put_arm_insn (htab, output_bfd,
7762
			elf32_thumb2_plt_entry[1]
7763
			| ((got_displacement & 0x00ff0000)      )
7764
			| ((got_displacement & 0x07000000) <<  4)
7765
			| ((got_displacement & 0x08000800) >> 17),
7766
			ptr + 4);
7767
	  put_arm_insn (htab, output_bfd,
7768
			elf32_thumb2_plt_entry[2],
7769
			ptr + 8);
7770
	  put_arm_insn (htab, output_bfd,
7771
			elf32_thumb2_plt_entry[3],
7772
			ptr + 12);
7699
	}
7773
	}
7700
      else
7774
      else
7701
	{
7775
	{
Lines 8918-8924 elf32_arm_final_link_relocate (reloc_howto_type * howto, Link Here
8918
		     + splt->output_offset
8992
		     + splt->output_offset
8919
		     + plt_offset);
8993
		     + plt_offset);
8920
8994
8921
	    if (globals->use_blx && r_type == R_ARM_THM_CALL)
8995
	    if (globals->use_blx
8996
		&& r_type == R_ARM_THM_CALL
8997
		&& ! using_thumb_only (globals))
8922
	      {
8998
	      {
8923
		/* If the Thumb BLX instruction is available, convert
8999
		/* If the Thumb BLX instruction is available, convert
8924
		   the BL to a BLX instruction to call the ARM-mode
9000
		   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
	      }
9004
	      }
8929
	    else
9005
	    else
8930
	      {
9006
	      {
8931
		/* Target the Thumb stub before the ARM PLT entry.  */
9007
		if (! using_thumb_only (globals))
8932
		value -= PLT_THUMB_STUB_SIZE;
9008
		  /* Target the Thumb stub before the ARM PLT entry.  */
9009
		  value -= PLT_THUMB_STUB_SIZE;
8933
		branch_type = ST_BRANCH_TO_THUMB;
9010
		branch_type = ST_BRANCH_TO_THUMB;
8934
	      }
9011
	      }
8935
	    *unresolved_reloc_p = FALSE;
9012
	    *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)
14461
	  else if (htab->nacl_p)
14385
	    arm_nacl_put_plt0 (htab, output_bfd, splt,
14462
	    arm_nacl_put_plt0 (htab, output_bfd, splt,
14386
			       got_address + 8 - (plt_address + 16));
14463
			       got_address + 8 - (plt_address + 16));
14464
	  else if (using_thumb_only (htab))
14465
	    {
14466
	      got_displacement = got_address - (plt_address + 12);
14467
14468
	      plt0_entry = elf32_thumb2_plt0_entry;
14469
	      put_arm_insn (htab, output_bfd, plt0_entry[0],
14470
			    splt->contents + 0);
14471
	      put_arm_insn (htab, output_bfd, plt0_entry[1],
14472
			    splt->contents + 4);
14473
	      put_arm_insn (htab, output_bfd, plt0_entry[2],
14474
			    splt->contents + 8);
14475
14476
	      bfd_put_32 (output_bfd, got_displacement, splt->contents + 12);
14477
	    }
14387
	  else
14478
	  else
14388
	    {
14479
	    {
14389
	      got_displacement = got_address - (plt_address + 16);
14480
	      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))
14813
      if (!elf32_arm_output_map_sym (osi, ARM_MAP_ARM, addr))
14723
	return FALSE;
14814
	return FALSE;
14724
    }
14815
    }
14816
  else if (using_thumb_only (htab))
14817
    {
14818
      if (!elf32_arm_output_map_sym (osi, ARM_MAP_THUMB, addr))
14819
	return FALSE;
14820
    }  
14725
  else
14821
  else
14726
    {
14822
    {
14727
      bfd_boolean thumb_stub_p;
14823
      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))
15149
	  if (!elf32_arm_output_map_sym (&osi, ARM_MAP_ARM, 0))
15054
	    return FALSE;
15150
	    return FALSE;
15055
	}
15151
	}
15152
      else if (using_thumb_only (htab))
15153
	{
15154
	  if (!elf32_arm_output_map_sym (&osi, ARM_MAP_THUMB, 0))
15155
	    return FALSE;
15156
	  if (!elf32_arm_output_map_sym (&osi, ARM_MAP_DATA, 12))
15157
	    return FALSE;
15158
	  if (!elf32_arm_output_map_sym (&osi, ARM_MAP_THUMB, 16))
15159
	    return FALSE;
15160
	}
15056
      else if (!htab->symbian_p)
15161
      else if (!htab->symbian_p)
15057
	{
15162
	{
15058
	  if (!elf32_arm_output_map_sym (&osi, ARM_MAP_ARM, 0))
15163
	  if (!elf32_arm_output_map_sym (&osi, ARM_MAP_ARM, 0))

Return to bug 16017