This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[ARM] undefined local symbols


The bug I recently fixed in the ARM assembler concerning missing expressions had the artifact of emitting relocations against local undefined symbols. These would cause the linker to segfault, which is unpleasant. Of course having such an undefined symbol is a strange thing to do -- except for ARM_V4BX and ARM_NONE relocs -- but we should emit some sensible error.

This patch does that. A weak undefined local symbol will decay to zero, and a non-weak one will generate an error message.

tested on arm-eabi, ok?

nathan
--
Nathan Sidwell    ::   http://www.codesourcery.com   ::         CodeSourcery

2009-08-05  Nathan Sidwell  <nathan@codesourcery.com>

	* elf32-arm.c (elf32_arm_size_stubs): Don't die on undefined local
	symbols.
	(elf32_arm_final_link_relocate): Treat local undefined symbols the
	same as global undefined symbols.
	(elf32_arm_relocate_section): Give an error for local undefined
	non-weak symbols, unless the reloc will not use the symbol.

Index: bfd/elf32-arm.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-arm.c,v
retrieving revision 1.207
diff -c -3 -p -r1.207 elf32-arm.c
*** bfd/elf32-arm.c	5 Aug 2009 12:36:14 -0000	1.207
--- bfd/elf32-arm.c	5 Aug 2009 16:11:00 -0000
*************** elf32_arm_size_stubs (bfd *output_bfd,
*** 4366,4371 ****
--- 4366,4376 ----
  		      sym = local_syms + r_indx;
  		      hdr = elf_elfsections (input_bfd)[sym->st_shndx];
  		      sym_sec = hdr->bfd_section;
+ 		      if (!sym_sec)
+ 			/* This is an undefined symbol.  It can never
+ 			   be resolved. */
+ 			continue;
+ 		  
  		      if (ELF_ST_TYPE (sym->st_info) != STT_SECTION)
  			sym_value = sym->st_value;
  		      destination = (sym_value + irela->r_addend
*************** elf32_arm_final_link_relocate (reloc_how
*** 6951,6957 ****
  	case R_ARM_PC24:	  /* Arm B/BL instruction.  */
  	case R_ARM_PLT32:
  	  {
- 	  bfd_vma from;
  	  bfd_signed_vma branch_offset;
  	  struct elf32_arm_stub_hash_entry *stub_entry = NULL;
  
--- 6956,6961 ----
*************** elf32_arm_final_link_relocate (reloc_how
*** 6988,6993 ****
--- 6992,6999 ----
  	      || r_type == R_ARM_JUMP24
  	      || r_type == R_ARM_PLT32)
  	    {
+ 	      bfd_vma from;
+ 	      
  	      /* If the call goes through a PLT entry, make sure to
  		 check distance to the right destination address.  */
  	      if (h != NULL && splt != NULL && h->plt.offset != (bfd_vma) -1)
*************** elf32_arm_final_link_relocate (reloc_how
*** 7056,7064 ****
  	  signed_addend >>= howto->rightshift;
  
  	  /* A branch to an undefined weak symbol is turned into a jump to
! 	     the next instruction unless a PLT entry will be created.  */
! 	  if (h && h->root.type == bfd_link_hash_undefweak
! 	      && !(splt != NULL && h->plt.offset != (bfd_vma) -1))
  	    {
  	      value = (bfd_get_32 (input_bfd, hit_data) & 0xf0000000)
  		      | 0x0affffff;
--- 7062,7072 ----
  	  signed_addend >>= howto->rightshift;
  
  	  /* A branch to an undefined weak symbol is turned into a jump to
! 	     the next instruction unless a PLT entry will be created.
! 	     Do the same for local undefined symbols.  */
! 	  if (h ? (h->root.type == bfd_link_hash_undefweak
! 		   && !(splt != NULL && h->plt.offset != (bfd_vma) -1))
! 	      : bfd_is_und_section (sym_sec))
  	    {
  	      value = (bfd_get_32 (input_bfd, hit_data) & 0xf0000000)
  		      | 0x0affffff;
*************** elf32_arm_relocate_section (bfd *       
*** 8704,8709 ****
--- 8712,8736 ----
  	  sym = local_syms + r_symndx;
  	  sym_type = ELF32_ST_TYPE (sym->st_info);
  	  sec = local_sections[r_symndx];
+ 
+ 	  /* An object file might have a reference to a local
+ 	     undefined symbol.  This is a daft object file, but we
+ 	     should at least do something about it.  V4BX & NONE
+ 	     relocations do not use the symbol and are explicitly
+ 	     allowed to use the undefined symbol, so allow those.  */
+ 	  if (r_type != R_ARM_V4BX
+ 	      && r_type != R_ARM_NONE
+ 	      && bfd_is_und_section (sec)
+ 	      && ELF_ST_BIND (sym->st_info) != STB_WEAK)
+ 	    {
+ 	      if (!info->callbacks->undefined_symbol
+ 		  (info, bfd_elf_string_from_elf_section
+ 		   (input_bfd, symtab_hdr->sh_link, sym->st_name),
+ 		   input_bfd, input_section,
+ 		   rel->r_offset, TRUE))
+ 		return FALSE;
+ 	    }
+ 	  
  	  if (globals->use_rel)
  	    {
  	      relocation = (sec->output_section->vma

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]