This is the mail archive of the binutils@sources.redhat.com 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]

RFC: Allow STT_SECTION + offset for SHF_MERGE sections


Hi!

This is just RFC, the rest of ELF backends would need to be updated
similarly.
I've noticed the local symbols which assembler kept because they are inside
of some SEC_MERGE sections take a lot of disk space in .o and thus in .a
files (e.g. with .debug_str support in -gdwarf-2 this can grow libqt.a from
60 to 92MB if I remember well), so IMHO the linker should just support
STT_SECTION + addend SHF_MERGE resolval.
This means some tiny changes in each ELF backend, but I think it is a price
worth paying to get rid of those zillions of local symbols in relocatable
objects and ar libraries.
The changes for RELA targets basically mean replacing all rel->r_addend
occurences in *_relocate_section with local variable and adding a call to
_bfd_merged_section_offset. For REL targets, things are more complicated
since the addend needs to be fetched from memory and written back after
adjusting it.
It might also simplify the code I'll have to add to readelf and dwarf2.c
for DW_FORM_strp in case .debug_info section is not yet relocated.
What do you think?

--- bfd/elf32-i386.c.jj	Tue Nov 13 18:25:56 2001
+++ bfd/elf32-i386.c	Fri Nov 16 20:16:57 2001
@@ -1770,6 +1770,32 @@ elf_i386_relocate_section (output_bfd, i
 	  relocation = (sec->output_section->vma
 			+ sec->output_offset
 			+ sym->st_value);
+	  if ((sec->flags & SEC_MERGE)
+	      && ELF_ST_TYPE (sym->st_info) == STT_SECTION)
+	    {
+	      asection *msec;
+	      bfd_vma addend;
+
+	      if (howto->src_mask != 0xffffffff)
+		{
+		  (*_bfd_error_handler)
+		    (_("%s(%s+0x%lx): non-32bit relocation against SEC_MERGE section"),
+		     bfd_archive_filename (input_bfd),
+		     bfd_get_section_name (input_bfd, input_section),
+		     (long) rel->r_offset);
+		  return false;
+		}
+
+	      addend = bfd_get_32 (input_bfd, contents + rel->r_offset);
+	      msec = sec;
+	      addend =
+		_bfd_merged_section_offset (output_bfd, &msec,
+					    elf_section_data (sec)->merge_info,
+					    sym->st_value + addend, (bfd_vma) 0)
+		- relocation;
+	      addend += msec->output_section->vma + msec->output_offset;
+	      bfd_put_32 (input_bfd, addend, contents + rel->r_offset);
+	    }
 	}
       else
 	{
--- bfd/elflink.h.jj	Tue Nov 13 18:25:59 2001
+++ bfd/elflink.h	Fri Nov 16 19:44:36 2001
@@ -6347,7 +6347,8 @@ elf_link_input_bfd (finfo, input_bfd)
 
 			  if (sec != NULL
 			      && ! bfd_is_abs_section (sec)
-			      && bfd_is_abs_section (sec->output_section))
+			      && bfd_is_abs_section (sec->output_section)
+			      && elf_section_data (sec)->merge_info == NULL)
 			    {
 #if BFD_VERSION_DATE < 20031005
 			      if ((o->flags & SEC_DEBUGGING) != 0
--- bfd/elf32-sparc.c.jj	Tue Nov 13 18:25:59 2001
+++ bfd/elf32-sparc.c	Fri Nov 16 20:22:27 2001
@@ -1131,7 +1131,7 @@ elf32_sparc_relocate_section (output_bfd
       struct elf_link_hash_entry *h;
       Elf_Internal_Sym *sym;
       asection *sec;
-      bfd_vma relocation;
+      bfd_vma relocation, addend;
       bfd_reloc_status_type r;
 
       r_type = ELF32_R_TYPE (rel->r_info);
@@ -1172,6 +1172,7 @@ elf32_sparc_relocate_section (output_bfd
       h = NULL;
       sym = NULL;
       sec = NULL;
+      addend = rel->r_addend;
       if (r_symndx < symtab_hdr->sh_info)
 	{
 	  sym = local_syms + r_symndx;
@@ -1179,6 +1180,19 @@ elf32_sparc_relocate_section (output_bfd
 	  relocation = (sec->output_section->vma
 			+ sec->output_offset
 			+ sym->st_value);
+	  if ((sec->flags & SEC_MERGE)
+	      && ELF_ST_TYPE (sym->st_info) == STT_SECTION)
+	    {
+	      asection *msec;
+
+	      msec = sec;
+	      addend = 
+		_bfd_merged_section_offset (output_bfd, &msec,
+					    elf_section_data (sec)->merge_info,
+					    sym->st_value + addend, (bfd_vma) 0)
+		- relocation;
+	      addend += msec->output_section->vma + msec->output_offset;
+	    }
 	}
       else
 	{
@@ -1494,14 +1508,14 @@ elf32_sparc_relocate_section (output_bfd
 		{
 		  BFD_ASSERT (h->dynindx != -1);
 		  outrel.r_info = ELF32_R_INFO (h->dynindx, r_type);
-		  outrel.r_addend = rel->r_addend;
+		  outrel.r_addend = addend;
 		}
 	      else
 		{
 		  if (r_type == R_SPARC_32 || r_type == R_SPARC_UA32)
 		    {
 		      outrel.r_info = ELF32_R_INFO (0, R_SPARC_RELATIVE);
-		      outrel.r_addend = relocation + rel->r_addend;
+		      outrel.r_addend = relocation + addend;
 		    }
 		  else
 		    {
@@ -1544,7 +1558,7 @@ elf32_sparc_relocate_section (output_bfd
 			}
 
 		      outrel.r_info = ELF32_R_INFO (indx, r_type);
-		      outrel.r_addend = relocation + rel->r_addend;
+		      outrel.r_addend = relocation + addend;
 		    }
 		}
 
@@ -1569,7 +1583,7 @@ elf32_sparc_relocate_section (output_bfd
 	{
 	  bfd_vma x;
 
-	  relocation += rel->r_addend;
+	  relocation += addend;
 	  relocation -= (input_section->output_section->vma
 			 + input_section->output_offset);
 	  relocation -= rel->r_offset;
@@ -1589,7 +1603,7 @@ elf32_sparc_relocate_section (output_bfd
 	{
 	  bfd_vma x;
 
-	  relocation = relocation + rel->r_addend;
+	  relocation = relocation + addend;
 
 	  x = bfd_get_32 (input_bfd, contents + rel->r_offset);
 	  x = x + relocation;
@@ -1631,7 +1645,7 @@ elf32_sparc_relocate_section (output_bfd
 		{
 		  bfd_vma reloc;
 
-		  reloc = relocation + rel->r_addend - rel->r_offset;
+		  reloc = relocation + addend - rel->r_offset;
 		  reloc -= (input_section->output_section->vma
 			   + input_section->output_offset);
 
@@ -1689,7 +1703,7 @@ elf32_sparc_relocate_section (output_bfd
       if (r == bfd_reloc_continue)
 	r = _bfd_final_link_relocate (howto, input_bfd, input_section,
 				      contents, rel->r_offset,
-				      relocation, rel->r_addend);
+				      relocation, addend);
 
       if (r != bfd_reloc_ok)
 	{
--- bfd/elf64-sparc.c.jj	Tue Nov 13 18:25:59 2001
+++ bfd/elf64-sparc.c	Fri Nov 16 20:22:16 2001
@@ -1929,7 +1929,7 @@ sparc64_elf_relocate_section (output_bfd
       struct elf_link_hash_entry *h;
       Elf_Internal_Sym *sym;
       asection *sec;
-      bfd_vma relocation;
+      bfd_vma relocation, addend;
       bfd_reloc_status_type r;
 
       r_type = ELF64_R_TYPE_ID (rel->r_info);
@@ -1965,6 +1965,7 @@ sparc64_elf_relocate_section (output_bfd
       h = NULL;
       sym = NULL;
       sec = NULL;
+      addend = rel->r_addend;
       if (r_symndx < symtab_hdr->sh_info)
 	{
 	  sym = local_syms + r_symndx;
@@ -1972,6 +1973,19 @@ sparc64_elf_relocate_section (output_bfd
 	  relocation = (sec->output_section->vma
 			+ sec->output_offset
 			+ sym->st_value);
+	  if ((sec->flags & SEC_MERGE)
+	      && ELF_ST_TYPE (sym->st_info) == STT_SECTION)
+	    {
+	      asection *msec;
+
+	      msec = sec;
+	      addend = 
+		_bfd_merged_section_offset (output_bfd, &msec,
+					    elf_section_data (sec)->merge_info,
+					    sym->st_value + addend, (bfd_vma) 0)
+		- relocation;
+	      addend += msec->output_section->vma + msec->output_offset;
+	    }
 	}
       else
 	{
@@ -2236,14 +2250,14 @@ sparc64_elf_relocate_section (output_bfd
 				      ELF64_R_TYPE_INFO (
 					ELF64_R_TYPE_DATA (rel->r_info),
 							   r_type));
-		    outrel.r_addend = rel->r_addend;
+		    outrel.r_addend = addend;
 		  }
 		else
 		  {
 		    if (r_type == R_SPARC_64)
 		      {
 			outrel.r_info = ELF64_R_INFO (0, R_SPARC_RELATIVE);
-			outrel.r_addend = relocation + rel->r_addend;
+			outrel.r_addend = relocation + addend;
 		      }
 		    else
 		      {
@@ -2290,7 +2304,7 @@ sparc64_elf_relocate_section (output_bfd
 					  ELF64_R_TYPE_INFO (
 					    ELF64_R_TYPE_DATA (rel->r_info),
 							       r_type));
-			outrel.r_addend = relocation + rel->r_addend;
+			outrel.r_addend = relocation + addend;
 		      }
 		  }
 
@@ -2445,7 +2459,7 @@ sparc64_elf_relocate_section (output_bfd
 	  {
 	    bfd_vma x;
 
-	    relocation += rel->r_addend;
+	    relocation += addend;
 	    relocation = (relocation & 0x3ff) + ELF64_R_TYPE_DATA (rel->r_info);
 
 	    x = bfd_get_32 (input_bfd, contents + rel->r_offset);
@@ -2463,7 +2477,7 @@ sparc64_elf_relocate_section (output_bfd
 	  {
 	    bfd_vma x;
 
-	    relocation += rel->r_addend;
+	    relocation += addend;
 	    /* Adjust for pc-relative-ness.  */
 	    relocation -= (input_section->output_section->vma
 			   + input_section->output_offset);
@@ -2486,7 +2500,7 @@ sparc64_elf_relocate_section (output_bfd
 	  {
 	    bfd_vma x;
 
-	    relocation += rel->r_addend;
+	    relocation += addend;
 	    relocation = relocation ^ MINUS_ONE;
 
 	    x = bfd_get_32 (input_bfd, contents + rel->r_offset);
@@ -2504,7 +2518,7 @@ sparc64_elf_relocate_section (output_bfd
 	  {
 	    bfd_vma x;
 
-	    relocation += rel->r_addend;
+	    relocation += addend;
 	    relocation = (relocation & 0x3ff) | 0x1c00;
 
 	    x = bfd_get_32 (input_bfd, contents + rel->r_offset);
@@ -2551,7 +2565,7 @@ sparc64_elf_relocate_section (output_bfd
 		    {
 		      bfd_vma reloc;
 
-		      reloc = relocation + rel->r_addend - rel->r_offset;
+		      reloc = relocation + addend - rel->r_offset;
 		      reloc -= (input_section->output_section->vma
 				+ input_section->output_offset);
 		      if (reloc & 3)
@@ -2610,7 +2624,7 @@ sparc64_elf_relocate_section (output_bfd
 	do_default:
 	  r = _bfd_final_link_relocate (howto, input_bfd, input_section,
 					contents, rel->r_offset,
-					relocation, rel->r_addend);
+					relocation, addend);
 	  break;
 	}
 
--- bfd/elf64-alpha.c.jj	Tue Nov 13 18:25:59 2001
+++ bfd/elf64-alpha.c	Fri Nov 16 20:58:53 2001
@@ -3313,6 +3313,7 @@ elf64_alpha_relocate_section (output_bfd
       h = NULL;
       sym = NULL;
       sec = NULL;
+      addend = rel->r_addend;
 
       if (r_symndx < symtab_hdr->sh_info)
 	{
@@ -3321,6 +3322,19 @@ elf64_alpha_relocate_section (output_bfd
 	  relocation = (sec->output_section->vma
 			+ sec->output_offset
 			+ sym->st_value);
+	  if ((sec->flags & SEC_MERGE)
+	      && ELF_ST_TYPE (sym->st_info) == STT_SECTION)
+	    {
+	      asection *msec;
+
+	      msec = sec;
+	      addend = 
+		_bfd_merged_section_offset (output_bfd, &msec,
+					    elf_section_data (sec)->merge_info,
+					    sym->st_value + addend, (bfd_vma) 0)
+		- relocation;
+	      addend += msec->output_section->vma + msec->output_offset;
+	    }
 	}
       else
 	{
@@ -3362,7 +3376,6 @@ elf64_alpha_relocate_section (output_bfd
 	      relocation = 0;
 	    }
 	}
-      addend = rel->r_addend;
 
       switch (r_type)
 	{
@@ -3377,7 +3390,7 @@ elf64_alpha_relocate_section (output_bfd
 			  + rel->r_offset);
 
 	    p_ldah = contents + rel->r_offset - input_section->vma;
-	    p_lda = p_ldah + rel->r_addend;
+	    p_lda = p_ldah + addend;
 
 	    r = elf64_alpha_do_reloc_gpdisp (input_bfd, gp - relocation,
 					     p_ldah, p_lda);
--- bfd/elf32-v850.c.jj	Fri Oct  5 13:02:09 2001
+++ bfd/elf32-v850.c	Fri Nov 16 21:01:57 2001
@@ -1558,7 +1558,7 @@ v850_elf_relocate_section (output_bfd, i
       Elf_Internal_Sym *           sym;
       asection *                   sec;
       struct elf_link_hash_entry * h;
-      bfd_vma                      relocation;
+      bfd_vma                      relocation, addend;
       bfd_reloc_status_type        r;
 
       r_symndx = ELF32_R_SYM (rel->r_info);
@@ -1593,6 +1593,7 @@ v850_elf_relocate_section (output_bfd, i
       h = NULL;
       sym = NULL;
       sec = NULL;
+      addend = rel->r_addend;
       if (r_symndx < symtab_hdr->sh_info)
 	{
 	  sym = local_syms + r_symndx;
@@ -1600,6 +1601,19 @@ v850_elf_relocate_section (output_bfd, i
 	  relocation = (sec->output_section->vma
 			+ sec->output_offset
 			+ sym->st_value);
+	  if ((sec->flags & SEC_MERGE)
+	      && ELF_ST_TYPE (sym->st_info) == STT_SECTION)
+	    {
+	      asection *msec;
+
+	      msec = sec;
+	      addend = 
+		_bfd_merged_section_offset (output_bfd, &msec,
+					    elf_section_data (sec)->merge_info,
+					    sym->st_value + addend, (bfd_vma) 0)
+		- relocation;
+	      addend += msec->output_section->vma + msec->output_offset;
+	    }
 #if 0
 	  {
 	    char * name;
@@ -1657,7 +1671,7 @@ v850_elf_relocate_section (output_bfd, i
       r = v850_elf_final_link_relocate (howto, input_bfd, output_bfd,
 					input_section,
 					contents, rel->r_offset,
-					relocation, rel->r_addend,
+					relocation, addend,
 					info, sec, h == NULL);
 
       if (r != bfd_reloc_ok)
--- bfd/elfxx-ia64.c.jj	Tue Nov 13 18:25:59 2001
+++ bfd/elfxx-ia64.c	Fri Nov 16 21:10:01 2001
@@ -3432,7 +3432,7 @@ elfNN_ia64_relocate_section (output_bfd,
       unsigned long r_symndx;
       Elf_Internal_Sym *sym;
       unsigned int r_type;
-      bfd_vma value;
+      bfd_vma value, addend;
       asection *sym_sec;
       bfd_byte *hit_addr;
       boolean dynamic_symbol_p;
@@ -3475,6 +3475,7 @@ elfNN_ia64_relocate_section (output_bfd,
       sym = NULL;
       sym_sec = NULL;
       undef_weak_ref = false;
+      addend = rel->r_addend;
 
       if (r_symndx < symtab_hdr->sh_info)
 	{
@@ -3484,6 +3485,19 @@ elfNN_ia64_relocate_section (output_bfd,
 	  value  = (sym_sec->output_section->vma
 		    + sym_sec->output_offset
 		    + sym->st_value);
+	  if ((sec->flags & SEC_MERGE)
+	      && ELF_ST_TYPE (sym->st_info) == STT_SECTION)
+	    {
+	      asection *msec;
+
+	      msec = sec;
+	      addend = 
+		_bfd_merged_section_offset (output_bfd, &sym_sec,
+					    elf_section_data (sym_sec)->merge_info,
+					    sym->st_value + addend, (bfd_vma) 0)
+		- value;
+	      addend += msec->output_section->vma + msec->output_offset;
+	    }
 	}
       else
 	{
@@ -3538,7 +3552,7 @@ elfNN_ia64_relocate_section (output_bfd,
 	}
 
       hit_addr = contents + rel->r_offset;
-      value += rel->r_addend;
+      value += addend;
       dynamic_symbol_p = elfNN_ia64_dynamic_symbol_p (h, info);
 
       switch (r_type)
@@ -3565,7 +3579,6 @@ elfNN_ia64_relocate_section (output_bfd,
 	    {
 	      unsigned int dyn_r_type;
 	      long dynindx;
-	      bfd_vma addend;
 
 	      BFD_ASSERT (srel != NULL);
 
@@ -3575,7 +3588,6 @@ elfNN_ia64_relocate_section (output_bfd,
 	      if (dynamic_symbol_p)
 		{
 		  dynindx = h->dynindx;
-		  addend = rel->r_addend;
 		  value = 0;
 		}
 	      else
@@ -3650,7 +3662,7 @@ elfNN_ia64_relocate_section (output_bfd,
 	case R_IA64_LTOFF64I:
           dyn_i = get_dyn_sym_info (ia64_info, h, input_bfd, rel, false);
 	  value = set_got_entry (input_bfd, info, dyn_i, (h ? h->dynindx : -1),
-				 rel->r_addend, value, R_IA64_DIR64LSB);
+				 addend, value, R_IA64_DIR64LSB);
 	  value -= gp_val;
 	  r = elfNN_ia64_install_value (output_bfd, hit_addr, value, r_type);
 	  break;
@@ -3700,7 +3712,7 @@ elfNN_ia64_relocate_section (output_bfd,
 
 	      elfNN_ia64_install_dyn_reloc (output_bfd, info, input_section,
 					    srel, rel->r_offset, r_type,
-					    dynindx, rel->r_addend);
+					    dynindx, addend);
 	      value = 0;
 	    }
 
@@ -3744,7 +3756,7 @@ elfNN_ia64_relocate_section (output_bfd,
 	      }
 
 	    value = set_got_entry (output_bfd, info, dyn_i, dynindx,
-				   rel->r_addend, value, R_IA64_FPTR64LSB);
+				   addend, value, R_IA64_FPTR64LSB);
 	    value -= gp_val;
 	    r = elfNN_ia64_install_value (output_bfd, hit_addr, value, r_type);
 	  }
@@ -3763,7 +3775,7 @@ elfNN_ia64_relocate_section (output_bfd,
 
 	      elfNN_ia64_install_dyn_reloc (output_bfd, info, input_section,
 					    srel, rel->r_offset, r_type,
-					    h->dynindx, rel->r_addend);
+					    h->dynindx, addend);
 	    }
 	  goto finish_pcrel;
 
@@ -3800,7 +3812,7 @@ elfNN_ia64_relocate_section (output_bfd,
 	  if (dyn_i && dyn_i->want_plt2)
 	    {
 	      /* Should have caught this earlier.  */
-	      BFD_ASSERT (rel->r_addend == 0);
+	      BFD_ASSERT (addend == 0);
 
 	      value = (ia64_info->plt_sec->output_section->vma
 		       + ia64_info->plt_sec->output_offset
@@ -3920,7 +3932,7 @@ elfNN_ia64_relocate_section (output_bfd,
 	      else
 		elfNN_ia64_install_dyn_reloc (output_bfd, info, input_section,
 					      srel, rel->r_offset, r_type,
-					      h->dynindx, rel->r_addend);
+					      h->dynindx, addend);
 	    }
 
 	  if (r_type == R_IA64_IPLTMSB)
--- gas/config/tc-alpha.c.jj	Tue Nov 13 18:26:08 2001
+++ gas/config/tc-alpha.c	Fri Nov 16 21:15:12 2001
@@ -1510,8 +1510,7 @@ tc_gen_reloc (sec, fixp)
        * at assembly time.  bfd_perform_reloc doesn't know about this sort
        * of thing, and as a result we need to fake it out here.
        */
-      if ((S_IS_EXTERN (fixp->fx_addsy) || S_IS_WEAK (fixp->fx_addsy)
-	   || (S_GET_SEGMENT (fixp->fx_addsy)->flags & SEC_MERGE))
+      if ((S_IS_EXTERN (fixp->fx_addsy) || S_IS_WEAK (fixp->fx_addsy))
 	  && !S_IS_COMMON (fixp->fx_addsy))
 	reloc->addend -= symbol_get_bfdsym (fixp->fx_addsy)->value;
 #endif
--- gas/config/tc-sparc.c.jj	Fri Oct  5 13:03:40 2001
+++ gas/config/tc-sparc.c	Fri Nov 16 21:15:25 2001
@@ -2908,7 +2908,6 @@ md_apply_fix3 (fixP, value, segment)
       if (symbol_used_in_reloc_p (fixP->fx_addsy)
 	  && (S_IS_EXTERNAL (fixP->fx_addsy)
 	      || S_IS_WEAK (fixP->fx_addsy)
-	      || (S_GET_SEGMENT (fixP->fx_addsy)->flags & SEC_MERGE)
 	      || (sparc_pic_code && ! fixP->fx_pcrel)
 	      || (S_GET_SEGMENT (fixP->fx_addsy) != segment
 		  && ((bfd_get_section_flags (stdoutput,
--- gas/write.c.jj	Tue Nov 13 18:26:08 2001
+++ gas/write.c	Fri Nov 16 19:18:01 2001
@@ -873,13 +873,6 @@ adjust_reloc_syms (abfd, sec, xxx)
 	    symbol_mark_used_in_reloc (fixp->fx_addsy);
 	    goto done;
 	  }
-
-	/* Never adjust a reloc against local symbol in a merge section.  */
-	if (symsec->flags & SEC_MERGE)
-	  {
-	    symbol_mark_used_in_reloc (fixp->fx_addsy);
-	    goto done;
-	  }
 #endif
 
 	/* Is there some other reason we can't adjust this one?  (E.g.,
@@ -2815,9 +2808,6 @@ fixup_segment (fixP, this_segment_type)
 	      else if (add_symbol_segment == undefined_section
 #ifdef BFD_ASSEMBLER
 		       || bfd_is_com_section (add_symbol_segment)
-		       || (bfd_get_section_flags (stdoutput,
-						  add_symbol_segment)
-			   & SEC_MERGE) != 0
 #endif
 		       )
 		{

	Jakub


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