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]

Confused about TLS handling


Hi,
I'm doing a binutils port to an embedded system where we want some
kind of thread-local storage mechanism. I'm using the elf TLS stuff
for that, as it seems appropriate, but I'm getting confused because
both bfd and ld have some strange handling of .tbss like sections.
See the attached partial diff for the hacks I've done to get things
to work.  AFAICT, binutils is trying to treat .tbss sections
as if they are initialized data, and take up space in the executable.

Also, being an embedded system, I'm generating a single ROM image, which
gets parts of itself copied during the boot process, to set up .data
and the like, hence the linker script has liberal uses of LOADADDR and
AT. However, the relevent TLS point is that the image of .tdata is located
somewhere within the ROM, not as a separate thread local elf segment.
Infact, I'm trying to map all the sections into a single loadable segment,
corresponding to the ROM image.

Am I going about this in the right way? Would it be better to define
an architecturally special section attribute to sort-of mimic TLS behaviour?

nathan
--
Nathan Sidwell    ::   http://www.codesourcery.com   ::     CodeSourcery LLC
nathan@codesourcery.com    ::     http://www.planetfall.pwp.blueyonder.co.uk

Index: bfd/elf.c
===================================================================
RCS file: /home/icera/Repository/binutils/bfd/elf.c,v
retrieving revision 1.1.1.1
diff -c -3 -p -r1.1.1.1 elf.c
*** bfd/elf.c	20 Jan 2004 19:11:29 -0000	1.1.1.1
--- bfd/elf.c	17 Feb 2004 19:37:33 -0000
*************** assign_file_positions_for_segments (abfd
*************** NMS:increase for .tbss but not .bss
*** 3926,3933 ****
  		off += sec->_raw_size;
  
  	      if ((flags & SEC_ALLOC) != 0
! 		  && ((flags & SEC_LOAD) != 0
! 		      || (flags & SEC_THREAD_LOCAL) == 0))
  		voff += sec->_raw_size;
  	    }
  
--- 3930,3936 ----
  		off += sec->_raw_size;
  
  	      if ((flags & SEC_ALLOC) != 0
! 		  && (flags & SEC_LOAD) != 0)
  		voff += sec->_raw_size;
  	    }
  
*************** assign_file_positions_for_segments (abfd
*************** NMS: increase for .tbss but not for .bss
*** 3955,3967 ****
  	  else
  	    {
  	      if ((sec->flags & SEC_LOAD) != 0
- 		  || (sec->flags & SEC_THREAD_LOCAL) == 0
  		  || p->p_type == PT_TLS)
! 	      p->p_memsz += sec->_raw_size;
  
  	      if ((flags & SEC_LOAD) != 0)
  		p->p_filesz += sec->_raw_size;
- 
  	      if (p->p_type == PT_TLS
  		  && sec->_raw_size == 0
  		  && (sec->flags & SEC_HAS_CONTENTS) == 0)
--- 3958,3974 ----
  	  else
  	    {
  	      if ((sec->flags & SEC_LOAD) != 0
  		  || p->p_type == PT_TLS)
! 		{
! 		  p->p_memsz += sec->_raw_size;
! 		  tail_bss_size = 0;
! 		}
! 	      else if (sec->flags & SEC_ALLOC)
! 		tail_bss_size += sec->_raw_size;
! 
  
  	      if ((flags & SEC_LOAD) != 0)
  		p->p_filesz += sec->_raw_size;
  	      if (p->p_type == PT_TLS
  		  && sec->_raw_size == 0
  		  && (sec->flags & SEC_HAS_CONTENTS) == 0)
Index: ld/ldlang.c
===================================================================
RCS file: /home/icera/Repository/binutils/ld/ldlang.c,v
retrieving revision 1.1.1.1
diff -c -3 -p -r1.1.1.1 ldlang.c
*** ld/ldlang.c	20 Jan 2004 20:01:02 -0000	1.1.1.1
--- ld/ldlang.c	17 Feb 2004 19:38:30 -0000
*************** lang_add_section (ptr, section, output, 
*************** NMS:Force STT_TLS to be loaded
*** 1270,1279 ****
  	  flags &= ~ (SEC_MERGE | SEC_STRINGS);
  	}
  
        /* For now make .tbss normal section.  */
        if ((flags & SEC_THREAD_LOCAL) && ! link_info.relocateable)
  	flags |= SEC_LOAD;
! 
        section->output_section->flags |= flags;
  
        if (flags & SEC_MERGE)
--- 1278,1289 ----
  	  flags &= ~ (SEC_MERGE | SEC_STRINGS);
  	}
  
+ #if 0 /* FIXME:NMS:what is the rationale for this?  */
        /* For now make .tbss normal section.  */
        if ((flags & SEC_THREAD_LOCAL) && ! link_info.relocateable)
  	flags |= SEC_LOAD;
! #endif
!       
        section->output_section->flags |= flags;
  
        if (flags & SEC_MERGE)
*************** lang_size_sections_1 (s, output_section_
*************** NMS:Force .tbss size to be zero
*** 3118,3127 ****
--- 3130,3141 ----
  
  	    if (bfd_is_abs_section (os->bfd_section))
  	      ASSERT (after == os->bfd_section->vma);
+ #if 0
  	    else if ((os->bfd_section->flags & SEC_HAS_CONTENTS) == 0
  		     && (os->bfd_section->flags & SEC_THREAD_LOCAL)
  		     && ! link_info.relocateable)
  	      os->bfd_section->_raw_size = 0;
+ #endif
  	    else
  	      os->bfd_section->_raw_size =
  		(after - os->bfd_section->vma) * opb;
Index: ld/ldwrite.c
===================================================================
RCS file: /home/icera/Repository/binutils/ld/ldwrite.c,v
retrieving revision 1.1.1.1
diff -c -3 -p -r1.1.1.1 ldwrite.c
*** ld/ldwrite.c	20 Jan 2004 20:01:05 -0000	1.1.1.1
--- ld/ldwrite.c	17 Feb 2004 19:38:33 -0000
*************** build_link_order (statement)
*************** NMS:ADD loadable TLS segments with no contents (.tbss?)
*** 234,241 ****
  	  ASSERT (output_section->owner == output_bfd);
  
  	  if ((output_section->flags & SEC_HAS_CONTENTS) != 0
  	      || ((output_section->flags & SEC_LOAD) != 0
! 		  && (output_section->flags & SEC_THREAD_LOCAL)))
  	    {
  	      struct bfd_link_order *link_order;
  
--- 234,244 ----
  	  ASSERT (output_section->owner == output_bfd);
  
  	  if ((output_section->flags & SEC_HAS_CONTENTS) != 0
+ #if 0
  	      || ((output_section->flags & SEC_LOAD) != 0
! 		  && (output_section->flags & SEC_THREAD_LOCAL))
! #endif
! 	      )
  	    {
  	      struct bfd_link_order *link_order;
  

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