This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
Confused about TLS handling
- From: Nathan Sidwell <nathan at codesourcery dot com>
- To: binutils at sources dot redhat dot com
- Date: Tue, 17 Feb 2004 20:09:26 +0000
- Subject: Confused about TLS handling
- Organization: Codesourcery LLC
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;