This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
[PATCH] Fix various strip bugs with .tbss sections
- From: Jakub Jelinek <jakub at redhat dot com>
- To: binutils at sources dot redhat dot com
- Cc: roland at redhat dot com
- Date: Sat, 30 Nov 2002 00:51:52 +0100
- Subject: [PATCH] Fix various strip bugs with .tbss sections
- Reply-to: Jakub Jelinek <jakub at redhat dot com>
Hi!
The following patch fixes a bunch of bugs in strip on ELF bins/libs
with .tbss section.
.tbss is special in a bunch of ways, because it is a SHT_NOBITS
section which typically has some SHT_PROGBITS sections after it,
because although it has non-zero sh_size for all segment sizing but PT_TLS
it needs to be handled as if it had zero size (immediately following
SHT_PROGBITS section has typically the same sh_addr as .tbss).
Tested with stripping --with-__thread libc.so and on a bunch of other
TLS binaries/libraries.
Ok to commit?
2002-11-30 Jakub Jelinek <jakub@redhat.com>
* elf.c (elf_sort_sections): Don't reorder .tbss.
(assign_file_positions_for_segments): Only adjust off/voff
for increased alignment in PT_LOAD or PT_NOTE segment,
but adjust p_filesz for .tbss too. in PT_LOAD consider
.tbss to have zero memory size.
(copy_private_bfd_data) [SECTION_SIZE]: Define.
[IS_CONTAINED_BY_VMA, IS_CONTAINED_BY_LMA]: Use it.
[INCLUDE_SECTION_IN_SEGMENT]: Only put SHF_TLS sections
into PT_TLS segment. Never put SHF_TLS sections in
segments other than PT_TLS or PT_LOAD.
--- bfd/elf.c.jj 2002-11-28 15:49:48.000000000 +0100
+++ bfd/elf.c 2002-11-29 23:58:06.000000000 +0100
@@ -3494,6 +3494,7 @@ elf_sort_sections (arg1, arg2)
{
const asection *sec1 = *(const asection **) arg1;
const asection *sec2 = *(const asection **) arg2;
+ bfd_size_type size1, size2;
/* Sort by LMA first, since this is the address used to
place the section into a segment. */
@@ -3511,7 +3512,7 @@ elf_sort_sections (arg1, arg2)
/* Put !SEC_LOAD sections after SEC_LOAD ones. */
-#define TOEND(x) (((x)->flags & SEC_LOAD) == 0)
+#define TOEND(x) (((x)->flags & (SEC_LOAD|SEC_THREAD_LOCAL)) == 0)
if (TOEND (sec1))
{
@@ -3533,9 +3534,12 @@ elf_sort_sections (arg1, arg2)
/* Sort by size, to put zero sized sections
before others at the same address. */
- if (sec1->_raw_size < sec2->_raw_size)
+ size1 = (sec1->flags & SEC_LOAD) ? sec1->_raw_size : 0;
+ size2 = (sec2->flags & SEC_LOAD) ? sec2->_raw_size : 0;
+
+ if (size1 < size2)
return -1;
- if (sec1->_raw_size > sec2->_raw_size)
+ if (size1 > size2)
return 1;
return sec1->target_index - sec2->target_index;
@@ -3816,9 +3820,15 @@ assign_file_positions_for_segments (abfd
bfd_vma adjust = sec->lma - (p->p_paddr + p->p_memsz);
p->p_memsz += adjust;
- off += adjust;
- voff += adjust;
- if ((flags & SEC_LOAD) != 0)
+ if (p->p_type == PT_LOAD
+ || (p->p_type == PT_NOTE
+ && bfd_get_format (abfd) == bfd_core))
+ {
+ off += adjust;
+ voff += adjust;
+ }
+ if ((flags & SEC_LOAD) != 0
+ || (flags & SEC_THREAD_LOCAL) != 0)
p->p_filesz += adjust;
}
@@ -3875,7 +3885,9 @@ Error: First section in segment (%s) sta
|| (flags & SEC_HAS_CONTENTS) != 0)
off += sec->_raw_size;
- if ((flags & SEC_ALLOC) != 0)
+ if ((flags & SEC_ALLOC) != 0
+ && ((flags & SEC_LOAD) != 0
+ || (flags & SEC_THREAD_LOCAL) == 0))
voff += sec->_raw_size;
}
@@ -3902,6 +3914,9 @@ Error: First section in segment (%s) sta
}
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)
@@ -4545,18 +4560,23 @@ copy_private_bfd_data (ibfd, obfd)
(start + (segment->p_memsz > segment->p_filesz \
? segment->p_memsz : segment->p_filesz))
+#define SECTION_SIZE(section, segment) \
+ (((section->flags & (SEC_HAS_CONTENTS | SEC_THREAD_LOCAL)) \
+ != SEC_THREAD_LOCAL || segment->p_type == PT_TLS) \
+ ? section->_raw_size : 0)
+
/* Returns true if the given section is contained within
the given segment. VMA addresses are compared. */
#define IS_CONTAINED_BY_VMA(section, segment) \
(section->vma >= segment->p_vaddr \
- && (section->vma + section->_raw_size \
+ && (section->vma + SECTION_SIZE (section, segment) \
<= (SEGMENT_END (segment, segment->p_vaddr))))
/* Returns true if the given section is contained within
the given segment. LMA addresses are compared. */
#define IS_CONTAINED_BY_LMA(section, segment, base) \
(section->lma >= base \
- && (section->lma + section->_raw_size \
+ && (section->lma + SECTION_SIZE (section, segment) \
<= SEGMENT_END (segment, base)))
/* Special case: corefile "NOTE" section containing regs, prpsinfo etc. */
@@ -4588,7 +4608,9 @@ copy_private_bfd_data (ibfd, obfd)
if that is set for the segment and the VMA otherwise,
2. It is an allocated segment,
3. There is an output section associated with it,
- 4. The section has not already been allocated to a previous segment. */
+ 4. The section has not already been allocated to a previous segment.
+ 5. PT_TLS segment includes only SHF_TLS sections.
+ 6. SHF_TLS sections are only in PT_TLS or PT_LOAD segments. */
#define INCLUDE_SECTION_IN_SEGMENT(section, segment, bed) \
((((segment->p_paddr \
? IS_CONTAINED_BY_LMA (section, segment, segment->p_paddr) \
@@ -4596,6 +4618,11 @@ copy_private_bfd_data (ibfd, obfd)
&& (section->flags & SEC_ALLOC) != 0) \
|| IS_COREFILE_NOTE (segment, section)) \
&& section->output_section != NULL \
+ && (segment->p_type != PT_TLS \
+ || (section->flags & SEC_THREAD_LOCAL)) \
+ && (segment->p_type == PT_LOAD \
+ || segment->p_type == PT_TLS \
+ || (section->flags & SEC_THREAD_LOCAL) == 0) \
&& ! section->segment_mark)
/* Returns true iff seg1 starts after the end of seg2. */
@@ -5073,6 +5100,7 @@ copy_private_bfd_data (ibfd, obfd)
#endif
#undef SEGMENT_END
+#undef SECTION_SIZE
#undef IS_CONTAINED_BY_VMA
#undef IS_CONTAINED_BY_LMA
#undef IS_COREFILE_NOTE
Jakub