This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
[PATCH] Fix "SIZEOF and .tbss" patch
- From: Jakub Jelinek <jakub at redhat dot com>
- To: Alan Modra <amodra at bigpond dot net dot au>, Nathan Sidwell <nathan at codesourcery dot com>
- Cc: binutils at sources dot redhat dot com
- Date: Fri, 26 Mar 2004 14:47:10 +0100
- Subject: [PATCH] Fix "SIZEOF and .tbss" patch
- References: <4039E6E3.4080507@codesourcery.com> <m3llmiw6s8.fsf@redhat.com> <40474CA7.7040605@codesourcery.com>
- Reply-to: Jakub Jelinek <jakub at redhat dot com>
On Thu, Mar 04, 2004 at 03:35:03PM +0000, Nathan Sidwell wrote:
> Nick,
> >>This patch implements that functionality in a different manner. Rather
> >>than
> >>lie about .tbss's size, I tweak the couple of places that need to know
> >>it can be ignored for layout purposes.
>
> >It appears that there are now some new failures in the linker
> >testsuite with this patch applied:
>
> This patch adds the equivalent bit into elf.c's segment mapping. With
> this patch I find the linkers testsuite has the same failures as without
> the patch (on i686-pc-linux-gnu). ok?
>
> I'll investigate those failures I'm seeing -- it might be related
> to me using a gcc-3.4-pre compiler. I'd understand if you'd like to
> hold off this patch until these other failures are resolved.
This patch is still wrong.
One problem is e.g. mapping following sections:
.text
[ VMA gap here ]
.tbss
.data
.bss
Your change was ignoring .tbss only in one of the 2 places where
last_hdr is set up, but .tbss really cannot be ignored, but rather should
be handled as if it was SEC_LOAD and had zero _raw_size.
Without this, I get e.g. tlsg failures with -z relro patch (which reorders
sections).
Ok to commit?
2004-03-26 Jakub Jelinek <jakub@redhat.com>
* elf.c (map_sections_to_segments): Fix handling of .tbss.
--- bfd/elf.c.jj 2004-03-26 15:22:59.000000000 +0100
+++ bfd/elf.c 2004-03-26 16:48:19.402552105 +0100
@@ -3190,6 +3190,7 @@ map_sections_to_segments (bfd *abfd)
struct elf_segment_map **pm;
struct elf_segment_map *m;
asection *last_hdr;
+ bfd_vma last_size;
unsigned int phdr_index;
bfd_vma maxpagesize;
asection **hdrpp;
@@ -3269,6 +3270,7 @@ map_sections_to_segments (bfd *abfd)
segment when the start of the second section can be placed within
a few bytes of the end of the first section. */
last_hdr = NULL;
+ last_size = 0;
phdr_index = 0;
maxpagesize = get_elf_backend_data (abfd)->maxpagesize;
writable = FALSE;
@@ -3317,18 +3319,19 @@ map_sections_to_segments (bfd *abfd)
segment. */
new_segment = TRUE;
}
- else if (BFD_ALIGN (last_hdr->lma + last_hdr->_raw_size, maxpagesize)
+ else if (BFD_ALIGN (last_hdr->lma + last_size, maxpagesize)
< BFD_ALIGN (hdr->lma, maxpagesize))
{
/* If putting this section in this segment would force us to
skip a page in the segment, then we need a new segment. */
new_segment = TRUE;
}
- else if ((last_hdr->flags & SEC_LOAD) == 0
- && (hdr->flags & SEC_LOAD) != 0)
+ else if ((last_hdr->flags & (SEC_LOAD | SEC_THREAD_LOCAL)) == 0
+ && (hdr->flags & (SEC_LOAD | SEC_THREAD_LOCAL)) != 0)
{
/* We don't want to put a loadable section after a
- nonloadable section in the same segment. */
+ nonloadable section in the same segment.
+ Consider .tbss sections as loadable for this purpose. */
new_segment = TRUE;
}
else if ((abfd->flags & D_PAGED) == 0)
@@ -3340,7 +3343,7 @@ map_sections_to_segments (bfd *abfd)
}
else if (! writable
&& (hdr->flags & SEC_READONLY) == 0
- && (((last_hdr->lma + last_hdr->_raw_size - 1)
+ && (((last_hdr->lma + last_size - 1)
& ~(maxpagesize - 1))
!= (hdr->lma & ~(maxpagesize - 1))))
{
@@ -3363,9 +3366,12 @@ map_sections_to_segments (bfd *abfd)
{
if ((hdr->flags & SEC_READONLY) == 0)
writable = TRUE;
- /* Ignore .tbss section for segment layout purposes. */
+ last_hdr = hdr;
+ /* .tbss sections effectively have zero size. */
if ((hdr->flags & (SEC_THREAD_LOCAL | SEC_LOAD)) != SEC_THREAD_LOCAL)
- last_hdr = hdr;
+ last_size = hdr->_raw_size;
+ else
+ last_size = 0;
continue;
}
@@ -3385,6 +3391,11 @@ map_sections_to_segments (bfd *abfd)
writable = FALSE;
last_hdr = hdr;
+ /* .tbss sections effectively have zero size. */
+ if ((hdr->flags & (SEC_THREAD_LOCAL | SEC_LOAD)) != SEC_THREAD_LOCAL)
+ last_size = hdr->_raw_size;
+ else
+ last_size = 0;
phdr_index = i;
phdr_in_segment = FALSE;
}
Jakub