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] | |
Looking further at what ld does when building Linux I discovered more
anomalies (all sections in the below descriptions are considered to be
page size aligned and a multiple of a page size large):
1) A non-writable section following a writable one would result in the
non-writable section to be merged into the writable segment, thus
losing
the write protection. The inverse case was dealt with properly.
2) A zero-sized bss section following a writable section and preceding
a non-writable one would result in the latter again losing its write
protection.
3) A zero-sized bss section between two writable sections would result
in a needlessly splitting the sections into two segments.
The patch attempts to address all these. Built and tested on
i686-pc-linux-gnu.
Jan
bfd/
2004-08-27 Jan Beulich <jbeulich@novell.com>
* elf.c (map_sections_to_segments): Symmetrically handle
segment
splits between non-writable and writable sections when a
writable
section preceeds a non-writable one. Consider
loadable/non-loadable
state of section only when it has non-zero size.
(elf_sort_sections): Consider loadable state only after
comparing
sizes (after comparing addresses there can, in a set of
sections
with identical addresses, only be one with non-zero size, which
should be ordered last here; among the zero-sized sections,
those
that are loadable should preceed all non-loadable ones).
ld/testsuite/
2004-08-27 Jan Beulich <jbeulich@novell.com>
* ld-elf/seg.*: New.
---
/home/jbeulich/src/binutils/mainline/2004-08-27.13.46/bfd/elf.c 2004-08-19
11:03:15.000000000 +0200
+++ 2004-08-27.13.46-elf-segments/bfd/elf.c 2004-08-27
14:01:06.010545560 +0200
@@ -3347,6 +3347,7 @@ map_sections_to_segments (bfd *abfd)
asection **hdrpp;
bfd_boolean phdr_in_segment = TRUE;
bfd_boolean writable;
+ int loadable; /* 0: indifferent, < 0: no, > 0: yes */
int tls_count = 0;
asection *first_tls = NULL;
asection *dynsec, *eh_frame_hdr;
@@ -3425,6 +3426,7 @@ map_sections_to_segments (bfd *abfd)
phdr_index = 0;
maxpagesize = get_elf_backend_data (abfd)->maxpagesize;
writable = FALSE;
+ loadable = 0;
dynsec = bfd_get_section_by_name (abfd, ".dynamic");
if (dynsec != NULL
&& (dynsec->flags & SEC_LOAD) == 0)
@@ -3477,11 +3479,12 @@ map_sections_to_segments (bfd *abfd)
skip a page in the segment, then we need a new segment.
*/
new_segment = TRUE;
}
- else if ((last_hdr->flags & (SEC_LOAD | SEC_THREAD_LOCAL)) == 0
- && (hdr->flags & (SEC_LOAD | SEC_THREAD_LOCAL)) != 0)
+ else if (loadable < 0
+ && (hdr->flags & (SEC_LOAD | SEC_THREAD_LOCAL)) != 0
+ && hdr->size != 0)
{
- /* We don't want to put a loadable section after a
- nonloadable section in the same segment.
+ /* We don't want to put a non-empty loadable section after
+ a nonloadable section in the same segment.
Consider .tbss sections as loadable for this purpose.
*/
new_segment = TRUE;
}
@@ -3492,8 +3495,7 @@ map_sections_to_segments (bfd *abfd)
file, then there is no other reason for a new segment.
*/
new_segment = FALSE;
}
- else if (! writable
- && (hdr->flags & SEC_READONLY) == 0
+ else if (! writable == ! (hdr->flags & SEC_READONLY)
&& (((last_hdr->lma + last_size - 1)
& ~(maxpagesize - 1))
!= (hdr->lma & ~(maxpagesize - 1))))
@@ -3517,6 +3519,13 @@ map_sections_to_segments (bfd *abfd)
{
if ((hdr->flags & SEC_READONLY) == 0)
writable = TRUE;
+ if (hdr->size != 0)
+ {
+ if ((hdr->flags & (SEC_LOAD | SEC_THREAD_LOCAL)) != 0)
+ loadable = 1;
+ else
+ loadable = -1;
+ }
last_hdr = hdr;
/* .tbss sections effectively have zero size. */
if ((hdr->flags & (SEC_THREAD_LOCAL | SEC_LOAD)) !=
SEC_THREAD_LOCAL)
@@ -3540,6 +3549,12 @@ map_sections_to_segments (bfd *abfd)
writable = TRUE;
else
writable = FALSE;
+ if (hdr->size == 0)
+ loadable = 0;
+ else if ((hdr->flags & (SEC_LOAD | SEC_THREAD_LOCAL)) != 0)
+ loadable = 1;
+ else
+ loadable = -1;
last_hdr = hdr;
/* .tbss sections effectively have zero size. */
@@ -3719,27 +3734,6 @@ elf_sort_sections (const void *arg1, con
else if (sec1->vma > sec2->vma)
return 1;
- /* Put !SEC_LOAD sections after SEC_LOAD ones. */
-
-#define TOEND(x) (((x)->flags & (SEC_LOAD | SEC_THREAD_LOCAL)) == 0)
-
- if (TOEND (sec1))
- {
- if (TOEND (sec2))
- {
- /* If the indicies are the same, do not return 0
- here, but continue to try the next comparison. */
- if (sec1->target_index - sec2->target_index != 0)
- return sec1->target_index - sec2->target_index;
- }
- else
- return 1;
- }
- else if (TOEND (sec2))
- return -1;
-
-#undef TOEND
-
/* Sort by size, to put zero sized sections
before others at the same address. */
@@ -3751,6 +3745,15 @@ elf_sort_sections (const void *arg1, con
if (size1 > size2)
return 1;
+ /* Put !SEC_LOAD sections after SEC_LOAD ones. */
+
+#define TOEND(x) (((x)->flags & (SEC_LOAD | SEC_THREAD_LOCAL)) == 0)
+
+ if (TOEND (sec1) != TOEND (sec2))
+ return TOEND (sec1) - TOEND (sec2);
+
+#undef TOEND
+
return sec1->target_index - sec2->target_index;
}
---
/home/jbeulich/src/binutils/mainline/2004-08-27.13.46/ld/testsuite/ld-elf/seg.d 1970-01-01
01:00:00.000000000 +0100
+++
2004-08-27.13.46-elf-segments/ld/testsuite/ld-elf/seg.d 2004-08-27
13:42:42.000000000 +0200
@@ -0,0 +1,18 @@
+#source: seg.s
+#ld: -T seg.ld
+#objdump: -p
+
+.*:.*elf.*
+
+.*:
+[ ]*LOAD[ ].*
+[ ]*filesz (0x0*1000+) memsz \1 flags r-x
+[ ]*LOAD[ ].*
+[ ]*filesz (0x0*3000+) memsz \1 flags rw-
+[ ]*LOAD[ ].*
+[ ]*filesz (0x0*1000+) memsz \1 flags r-x
+[ ]*LOAD[ ].*
+[ ]*filesz (0x0*1000+) memsz \1 flags rw-
+[ ]*LOAD[ ].*
+[ ]*filesz (0x0*1000+) memsz \1 flags r-x
+#pass
---
/home/jbeulich/src/binutils/mainline/2004-08-27.13.46/ld/testsuite/ld-elf/seg.ld 1970-01-01
01:00:00.000000000 +0100
+++
2004-08-27.13.46-elf-segments/ld/testsuite/ld-elf/seg.ld 2004-08-27
13:22:05.000000000 +0200
@@ -0,0 +1,13 @@
+SECTIONS {
+ . = 0xABC00000;
+ .text : { *(.text) }
+ .rodata : { *(.rodata) }
+ .data : { *(.data) }
+ .bss : { *(.bss) }
+ .write1 : { *(.write1) }
+ .write2 : { *(.write2) }
+ .exec1 : { *(.exec1) }
+ .write3 : { *(.write3) }
+ .bss3 : { *(.bss3) }
+ .exec2 : { *(.exec2) }
+}
---
/home/jbeulich/src/binutils/mainline/2004-08-27.13.46/ld/testsuite/ld-elf/seg.s 1970-01-01
01:00:00.000000000 +0100
+++
2004-08-27.13.46-elf-segments/ld/testsuite/ld-elf/seg.s 2004-08-27
13:40:38.000000000 +0200
@@ -0,0 +1,54 @@
+.equ PAGESIZE, 0x10000
+
+.global _start
+
+.text
+_start:
+.byte 0xCC
+
+.section .rodata, "a", @progbits
+.align 4
+code:
+.rept PAGESIZE - 4
+ .byte 0xCC
+.endr
+
+.data
+data:
+.rept PAGESIZE
+ .byte 0xDD
+.endr
+
+.section .write1, "aw", @progbits
+write1:
+.rept PAGESIZE
+ .byte 0x11
+.endr
+
+.section .write2, "aw", @progbits
+write2:
+.rept PAGESIZE
+ .byte 0x22
+.endr
+
+.section .exec1, "ax", @progbits
+exec1:
+.rept PAGESIZE
+ .byte 0xE1
+.endr
+
+.section .write3, "aw", @progbits
+.align 4
+write3:
+.rept PAGESIZE
+ .byte 0x33
+.endr
+
+.section .bss3, "aw", @nobits
+bss3:
+
+.section .exec2, "ax", @progbits
+exec2:
+.rept PAGESIZE
+ .byte 0xE2
+.endr
Attachment:
binutils-mainline-elf-segments.patch
Description: Binary data
| Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
|---|---|---|
| Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |