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]

Blackfin patch: Fix -gc-sections for FD-PIC


I've committed the following, which is an old patch from Jie Zhang, which fixes a linker error when -gc-sections is used with FD-PIC.

Specifically, it was a consistency check in elf32-bfinfdpic_finish_dynamic_sections that aborted. We verify that the number of relocs in the gotfixup section matches what we computed earlier, and with -gc-sections the count came up short.


Bernd -- This footer brought to you by insane German lawmakers. Analog Devices GmbH Wilhelm-Wagenfeld-Str. 6 80807 Muenchen Sitz der Gesellschaft Muenchen, Registergericht Muenchen HRB 40368 Geschaeftsfuehrer Thomas Wessel, William A. Martin, Margaret Seif
Index: ChangeLog
===================================================================
RCS file: /cvs/src/src/bfd/ChangeLog,v
retrieving revision 1.4163
diff -c -p -r1.4163 ChangeLog
*** ChangeLog	12 Mar 2008 08:36:58 -0000	1.4163
--- ChangeLog	12 Mar 2008 13:46:53 -0000
***************
*** 1,3 ****
--- 1,16 ----
+ 2008-03-12  Bernd Schmidt  <bernd.schmidt@analog.com>
+ 
+ 	From Jie Zhang <jie.zhang@analog.com>
+ 	* elf32-bfin.c (struct bfinfdpic_relocs_info): Make got17m4,
+ 	gothilo, fd, fdgot17m4, fdgothilo, fdgoff17m4, fdgoffhilo,
+ 	gotoff, call and sym not bitfields.
+ 	(bfinfdpic_gc_sweep_hook): New function; update the relocation
+ 	information for the relocations of the section being removed.
+ 	(bfinfdpic_check_relocs): Accumulate the number of relocations
+ 	which set got17m4, gothilo, fd, fdgot17m4, fdgothilo, fdgoff17m4,
+ 	fdgoffhilo, gotoff, call and sym fields.
+ 	(elf_backend_gc_sweep_hook): Redefine for FD-PIC.
+ 
  2008-03-12  Alan Modra  <amodra@bigpond.net.au>
  
  	PR 5900
Index: elf32-bfin.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-bfin.c,v
retrieving revision 1.28
diff -c -p -r1.28 elf32-bfin.c
*** elf32-bfin.c	11 Feb 2008 22:25:03 -0000	1.28
--- elf32-bfin.c	12 Mar 2008 13:46:53 -0000
*************** struct bfinfdpic_relocs_info
*** 1242,1267 ****
    /* The following 2 fields record whether the symbol+addend above was
       ever referenced with a GOT relocation.  The 17M4 suffix indicates a
       GOT17M4 relocation; hilo is used for GOTLO/GOTHI pairs.  */
!   unsigned got17m4:1;
!   unsigned gothilo:1;
    /* Whether a FUNCDESC relocation references symbol+addend.  */
!   unsigned fd:1;
    /* Whether a FUNCDESC_GOT relocation references symbol+addend.  */
!   unsigned fdgot17m4:1;
!   unsigned fdgothilo:1;
    /* Whether a FUNCDESC_GOTOFF relocation references symbol+addend.  */
!   unsigned fdgoff17m4:1;
!   unsigned fdgoffhilo:1;
    /* Whether symbol+addend is referenced with GOTOFF17M4, GOTOFFLO or
       GOTOFFHI relocations.  The addend doesn't really matter, since we
       envision that this will only be used to check whether the symbol
       is mapped to the same segment as the got.  */
!   unsigned gotoff:1;
    /* Whether symbol+addend is referenced by a LABEL24 relocation.  */
!   unsigned call:1;
    /* Whether symbol+addend is referenced by a 32 or FUNCDESC_VALUE
       relocation.  */
!   unsigned sym:1;
    /* Whether we need a PLT entry for a symbol.  Should be implied by
       something like:
       (call && symndx == -1 && ! BFINFDPIC_SYM_LOCAL (info, d.h))  */
--- 1242,1267 ----
    /* The following 2 fields record whether the symbol+addend above was
       ever referenced with a GOT relocation.  The 17M4 suffix indicates a
       GOT17M4 relocation; hilo is used for GOTLO/GOTHI pairs.  */
!   unsigned got17m4;
!   unsigned gothilo;
    /* Whether a FUNCDESC relocation references symbol+addend.  */
!   unsigned fd;
    /* Whether a FUNCDESC_GOT relocation references symbol+addend.  */
!   unsigned fdgot17m4;
!   unsigned fdgothilo;
    /* Whether a FUNCDESC_GOTOFF relocation references symbol+addend.  */
!   unsigned fdgoff17m4;
!   unsigned fdgoffhilo;
    /* Whether symbol+addend is referenced with GOTOFF17M4, GOTOFFLO or
       GOTOFFHI relocations.  The addend doesn't really matter, since we
       envision that this will only be used to check whether the symbol
       is mapped to the same segment as the got.  */
!   unsigned gotoff;
    /* Whether symbol+addend is referenced by a LABEL24 relocation.  */
!   unsigned call;
    /* Whether symbol+addend is referenced by a 32 or FUNCDESC_VALUE
       relocation.  */
!   unsigned sym;
    /* Whether we need a PLT entry for a symbol.  Should be implied by
       something like:
       (call && symndx == -1 && ! BFINFDPIC_SYM_LOCAL (info, d.h))  */
*************** bfin_gc_mark_hook (asection * sec,
*** 3151,3156 ****
--- 3151,3268 ----
    return _bfd_elf_gc_mark_hook (sec, info, rel, h, sym);
  }
  
+ /* Update the relocation information for the relocations of the section
+    being removed.  */
+ 
+ static bfd_boolean
+ bfinfdpic_gc_sweep_hook (bfd *abfd,
+ 			 struct bfd_link_info *info,
+ 			 asection *sec,
+ 			 const Elf_Internal_Rela *relocs)
+ {
+   Elf_Internal_Shdr *symtab_hdr;
+   struct elf_link_hash_entry **sym_hashes, **sym_hashes_end;
+   const Elf_Internal_Rela *rel;
+   const Elf_Internal_Rela *rel_end;
+   struct bfinfdpic_relocs_info *picrel;
+ 
+   BFD_ASSERT (IS_FDPIC (abfd));
+ 
+   symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
+   sym_hashes = elf_sym_hashes (abfd);
+   sym_hashes_end = sym_hashes + symtab_hdr->sh_size/sizeof(Elf32_External_Sym);
+   if (!elf_bad_symtab (abfd))
+     sym_hashes_end -= symtab_hdr->sh_info;
+ 
+   rel_end = relocs + sec->reloc_count;
+   for (rel = relocs; rel < rel_end; rel++)
+     {
+       struct elf_link_hash_entry *h;
+       unsigned long r_symndx;
+ 
+       r_symndx = ELF32_R_SYM (rel->r_info);
+       if (r_symndx < symtab_hdr->sh_info)
+         h = NULL;
+       else
+         h = sym_hashes[r_symndx - symtab_hdr->sh_info];
+ 
+       if (h != NULL)
+ 	picrel = bfinfdpic_relocs_info_for_global (bfinfdpic_relocs_info (info),
+ 						   abfd, h,
+ 						   rel->r_addend, NO_INSERT);
+       else
+ 	picrel = bfinfdpic_relocs_info_for_local (bfinfdpic_relocs_info
+ 						  (info), abfd, r_symndx,
+ 						  rel->r_addend, NO_INSERT);
+ 
+       if (!picrel)
+ 	return TRUE;
+ 
+       switch (ELF32_R_TYPE (rel->r_info))
+         {
+ 	case R_pcrel24:
+ 	case R_pcrel24_jump_l:
+ 	  picrel->call--;
+ 	  break;
+ 
+ 	case R_BFIN_FUNCDESC_VALUE:
+ 	  picrel->relocsfdv--;
+ 	  if (bfd_get_section_flags (abfd, sec) & SEC_ALLOC)
+ 	    picrel->relocs32++;
+ 	  /* Fall through.  */
+ 
+ 	case R_byte4_data:
+ 	  picrel->sym--;
+ 	  if (bfd_get_section_flags (abfd, sec) & SEC_ALLOC)
+ 	    picrel->relocs32--;
+ 	  break;
+ 
+ 	case R_BFIN_GOT17M4:
+ 	  picrel->got17m4--;
+ 	  break;
+ 
+ 	case R_BFIN_GOTHI:
+ 	case R_BFIN_GOTLO:
+ 	  picrel->gothilo--;
+ 	  break;
+ 
+ 	case R_BFIN_FUNCDESC_GOT17M4:
+ 	  picrel->fdgot17m4--;
+ 	  break;
+ 
+ 	case R_BFIN_FUNCDESC_GOTHI:
+ 	case R_BFIN_FUNCDESC_GOTLO:
+ 	  picrel->fdgothilo--;
+ 	  break;
+ 
+ 	case R_BFIN_GOTOFF17M4:
+ 	case R_BFIN_GOTOFFHI:
+ 	case R_BFIN_GOTOFFLO:
+ 	  picrel->gotoff--;
+ 	  break;
+ 
+ 	case R_BFIN_FUNCDESC_GOTOFF17M4:
+ 	  picrel->fdgoff17m4--;
+ 	  break;
+ 
+ 	case R_BFIN_FUNCDESC_GOTOFFHI:
+ 	case R_BFIN_FUNCDESC_GOTOFFLO:
+ 	  picrel->fdgoffhilo--;
+ 	  break;
+ 
+ 	case R_BFIN_FUNCDESC:
+ 	  picrel->fd--;
+ 	  picrel->relocsfd--;
+ 	  break;
+ 
+ 	default:
+ 	  break;
+         }
+     }
+ 
+   return TRUE;
+ }
+ 
  /* Update the got entry reference counts for the section being removed.  */
  
  static bfd_boolean
*************** bfinfdpic_check_relocs (bfd *abfd, struc
*** 4611,4617 ****
  	case R_pcrel24:
  	case R_pcrel24_jump_l:
  	  if (IS_FDPIC (abfd))
! 	    picrel->call = 1;
  	  break;
  
  	case R_BFIN_FUNCDESC_VALUE:
--- 4723,4729 ----
  	case R_pcrel24:
  	case R_pcrel24_jump_l:
  	  if (IS_FDPIC (abfd))
! 	    picrel->call++;
  	  break;
  
  	case R_BFIN_FUNCDESC_VALUE:
*************** bfinfdpic_check_relocs (bfd *abfd, struc
*** 4624,4669 ****
  	  if (! IS_FDPIC (abfd))
  	    break;
  
! 	  picrel->sym = 1;
  	  if (bfd_get_section_flags (abfd, sec) & SEC_ALLOC)
  	    picrel->relocs32++;
  	  break;
  
  	case R_BFIN_GOT17M4:
! 	  picrel->got17m4 = 1;
  	  break;
  
  	case R_BFIN_GOTHI:
  	case R_BFIN_GOTLO:
! 	  picrel->gothilo = 1;
  	  break;
  
  	case R_BFIN_FUNCDESC_GOT17M4:
! 	  picrel->fdgot17m4 = 1;
  	  break;
  
  	case R_BFIN_FUNCDESC_GOTHI:
  	case R_BFIN_FUNCDESC_GOTLO:
! 	  picrel->fdgothilo = 1;
  	  break;
  
  	case R_BFIN_GOTOFF17M4:
  	case R_BFIN_GOTOFFHI:
  	case R_BFIN_GOTOFFLO:
! 	  picrel->gotoff = 1;
  	  break;
  
  	case R_BFIN_FUNCDESC_GOTOFF17M4:
! 	  picrel->fdgoff17m4 = 1;
  	  break;
  
  	case R_BFIN_FUNCDESC_GOTOFFHI:
  	case R_BFIN_FUNCDESC_GOTOFFLO:
! 	  picrel->fdgoffhilo = 1;
  	  break;
  
  	case R_BFIN_FUNCDESC:
! 	  picrel->fd = 1;
  	  picrel->relocsfd++;
  	  break;
  
--- 4736,4781 ----
  	  if (! IS_FDPIC (abfd))
  	    break;
  
! 	  picrel->sym++;
  	  if (bfd_get_section_flags (abfd, sec) & SEC_ALLOC)
  	    picrel->relocs32++;
  	  break;
  
  	case R_BFIN_GOT17M4:
! 	  picrel->got17m4++;
  	  break;
  
  	case R_BFIN_GOTHI:
  	case R_BFIN_GOTLO:
! 	  picrel->gothilo++;
  	  break;
  
  	case R_BFIN_FUNCDESC_GOT17M4:
! 	  picrel->fdgot17m4++;
  	  break;
  
  	case R_BFIN_FUNCDESC_GOTHI:
  	case R_BFIN_FUNCDESC_GOTLO:
! 	  picrel->fdgothilo++;
  	  break;
  
  	case R_BFIN_GOTOFF17M4:
  	case R_BFIN_GOTOFFHI:
  	case R_BFIN_GOTOFFLO:
! 	  picrel->gotoff++;
  	  break;
  
  	case R_BFIN_FUNCDESC_GOTOFF17M4:
! 	  picrel->fdgoff17m4++;
  	  break;
  
  	case R_BFIN_FUNCDESC_GOTOFFHI:
  	case R_BFIN_FUNCDESC_GOTOFFLO:
! 	  picrel->fdgoffhilo++;
  	  break;
  
  	case R_BFIN_FUNCDESC:
! 	  picrel->fd++;
  	  picrel->relocsfd++;
  	  break;
  
*************** error_return:
*** 5539,5544 ****
--- 5651,5657 ----
  #define	elf32_bed		elf32_bfinfdpic_bed
  
  #undef elf_backend_gc_sweep_hook
+ #define elf_backend_gc_sweep_hook       bfinfdpic_gc_sweep_hook
  
  #undef elf_backend_got_header_size
  #define elf_backend_got_header_size     0

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