public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
* [PATCH] ELF section to segment mapping adjustments
@ 2005-05-10 12:40 Jan Beulich
  2005-05-10 15:21 ` Ian Lance Taylor
  0 siblings, 1 reply; 4+ messages in thread
From: Jan Beulich @ 2005-05-10 12:40 UTC (permalink / raw)
  To: binutils

[-- Attachment #1: Type: text/plain, Size: 9434 bytes --]

(Re-submitting a patch that I never got a reply to, originally at
http://sourceware.org/ml/binutils/2004-08/msg00361.html.)

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
x86_64-unknown-linux-gnu and as cross tools for a large number of targets.

Two additional questions:

Does it really make sense to have a zero-sized section contribute to the
access permissions of the segment it gets assigned to?

Shouldn't the executable permission be handled like the writeable one, i.e.
attempting to not merge sections with different permissions into one
segment?

If the answer to the first one is 'no' and/or that to the second is 'yes',
then perhaps some more adjustments to this code might be desirable.

Jan

bfd/
2004-05-10  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.

ld/testsuite/
2005-05-10  Jan Beulich  <jbeulich@novell.com>

	* ld-elf/seg.*: New.

--- /home/jbeulich/src/binutils/mainline/2005-05-06/bfd/elf.c	2005-05-06 08:24:21.000000000 +0200
+++ 2005-05-06/bfd/elf.c	2005-05-10 09:24:55.000000000 +0200
@@ -3442,13 +3442,14 @@ map_sections_to_segments (bfd *abfd)
   struct elf_segment_map *mfirst;
   struct elf_segment_map **pm;
   struct elf_segment_map *m;
-  asection *last_hdr;
+  asection *last_hdr, *last_nz;
   bfd_vma last_size;
   unsigned int phdr_index;
   bfd_vma maxpagesize;
   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;
@@ -3524,9 +3525,11 @@ map_sections_to_segments (bfd *abfd)
      a few bytes of the end of the first section.  */
   last_hdr = NULL;
   last_size = 0;
+  last_nz = NULL;
   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)
@@ -3579,11 +3582,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;
 	}
@@ -3594,9 +3598,9 @@ 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
-	       && (((last_hdr->lma + last_size - 1)
+      else if (! writable == ! (hdr->flags & SEC_READONLY)
+	       && last_nz != NULL
+	       && (((last_nz->lma + last_nz->size - 1)
 		    & ~(maxpagesize - 1))
 		   != (hdr->lma & ~(maxpagesize - 1))))
 	{
@@ -3615,33 +3619,33 @@ map_sections_to_segments (bfd *abfd)
 	  new_segment = FALSE;
 	}
 
-      if (! new_segment)
+      if (new_segment)
 	{
-	  if ((hdr->flags & SEC_READONLY) == 0)
-	    writable = TRUE;
-	  last_hdr = hdr;
-	  /* .tbss sections effectively have zero size.  */
-	  if ((hdr->flags & (SEC_THREAD_LOCAL | SEC_LOAD)) != SEC_THREAD_LOCAL)
-	    last_size = hdr->size;
-	  else
-	    last_size = 0;
-	  continue;
-	}
+	  /* We need a new program segment.  We must create a new program
+	     header holding all the sections from phdr_index until hdr.  */
 
-      /* We need a new program segment.  We must create a new program
-         header holding all the sections from phdr_index until hdr.  */
-
-      m = make_mapping (abfd, sections, phdr_index, i, phdr_in_segment);
-      if (m == NULL)
-	goto error_return;
+	  m = make_mapping (abfd, sections, phdr_index, i, phdr_in_segment);
+	  if (m == NULL)
+	    goto error_return;
 
-      *pm = m;
-      pm = &m->next;
+	  *pm = m;
+	  pm = &m->next;
+	  phdr_index = i;
+	  phdr_in_segment = FALSE;
+	  writable = FALSE;
+	  loadable = 0;
+	  last_nz = NULL;
+	}
 
       if ((hdr->flags & SEC_READONLY) == 0)
 	writable = TRUE;
-      else
-	writable = FALSE;
+      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.  */
@@ -3649,8 +3653,8 @@ map_sections_to_segments (bfd *abfd)
 	last_size = hdr->size;
       else
 	last_size = 0;
-      phdr_index = i;
-      phdr_in_segment = FALSE;
+      if (last_size != 0)
+	last_nz = hdr;
     }
 
   /* Create a final PT_LOAD program segment.  */
@@ -3815,27 +3819,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.  */
 
@@ -3847,6 +3830,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/2005-05-06/ld/testsuite/ld-elf/seg.d	1970-01-01 01:00:00.000000000 +0100
+++ 2005-05-06-elf-seg/ld/testsuite/ld-elf/seg.d	2005-05-09 12:34:37.000000000 +0200
@@ -0,0 +1,20 @@
+#source: seg.s
+#ld: -T seg.ld
+#objdump: -p
+#xfail: "avr-*-*" "cr16c-*-*" "crx-*-*" "dlx-*-*" "h8300-*-*" "hppa64-*-*"
+#xfail: "i960-*-*" "ip2k-*-*" "m32r-*-*" "m88k-*-*" "mips-*-*" "msp430-*-*"
+
+.*:.*elf.*
+#...
+Program Header:
+[ 	]*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/2005-05-06/ld/testsuite/ld-elf/seg.ld	1970-01-01 01:00:00.000000000 +0100
+++ 2005-05-06-elf-seg/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/2005-05-06/ld/testsuite/ld-elf/seg.s	1970-01-01 01:00:00.000000000 +0100
+++ 2005-05-06-elf-seg/ld/testsuite/ld-elf/seg.s	2005-05-09 10:48:55.000000000 +0200
@@ -0,0 +1,39 @@
+ .equiv	PAGESIZE, 0x100000
+
+.global	_start
+
+ .text
+_start:
+ .byte	0x11
+
+ .section	.rodata, "a", "progbits"
+ .p2align	4
+const:
+ .fill	PAGESIZE - 16, 1, 0x22
+
+ .data
+data:
+ .fill	PAGESIZE, 1, 0x33
+
+ .section	.write1, "aw", "progbits"
+write1:
+ .fill	PAGESIZE, 1, 0x44
+
+ .section	.write2, "aw", "progbits"
+write2:
+ .fill	PAGESIZE, 1, 0x55
+
+ .section	.exec1, "ax", "progbits"
+exec1:
+ .fill	PAGESIZE, 1, 0x66
+
+ .section	.write3, "aw", "progbits"
+write3:
+ .fill	PAGESIZE, 1, 0x77
+
+ .section	.bss3, "aw", "nobits"
+bss3:
+
+ .section	.exec2, "ax", "progbits"
+exec2:
+ .fill	PAGESIZE, 1, 0x88


[-- Attachment #2: binutils-mainline-elf-segments.patch --]
[-- Type: text/plain, Size: 9131 bytes --]

(Re-submitting a patch that I never got a reply to, originally at
http://sourceware.org/ml/binutils/2004-08/msg00361.html.)

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
x86_64-unknown-linux-gnu and as cross tools for a large number of targets.

Two additional questions:

Does it really make sense to have a zero-sized section contribute to the
access permissions of the segment it gets assigned to?

Shouldn't the executable permission be handled like the writeable one, i.e.
attempting to not merge sections with different permissions into one
segment?

If the answer to the first one is 'no' and/or that to the second is 'yes',
then perhaps some more adjustments to this code might be desirable.

Jan

bfd/
2004-05-10  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.

ld/testsuite/
2005-05-10  Jan Beulich  <jbeulich@novell.com>

	* ld-elf/seg.*: New.

--- /home/jbeulich/src/binutils/mainline/2005-05-06/bfd/elf.c	2005-05-06 08:24:21.000000000 +0200
+++ 2005-05-06/bfd/elf.c	2005-05-10 09:24:55.000000000 +0200
@@ -3442,13 +3442,14 @@ map_sections_to_segments (bfd *abfd)
   struct elf_segment_map *mfirst;
   struct elf_segment_map **pm;
   struct elf_segment_map *m;
-  asection *last_hdr;
+  asection *last_hdr, *last_nz;
   bfd_vma last_size;
   unsigned int phdr_index;
   bfd_vma maxpagesize;
   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;
@@ -3524,9 +3525,11 @@ map_sections_to_segments (bfd *abfd)
      a few bytes of the end of the first section.  */
   last_hdr = NULL;
   last_size = 0;
+  last_nz = NULL;
   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)
@@ -3579,11 +3582,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;
 	}
@@ -3594,9 +3598,9 @@ 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
-	       && (((last_hdr->lma + last_size - 1)
+      else if (! writable == ! (hdr->flags & SEC_READONLY)
+	       && last_nz != NULL
+	       && (((last_nz->lma + last_nz->size - 1)
 		    & ~(maxpagesize - 1))
 		   != (hdr->lma & ~(maxpagesize - 1))))
 	{
@@ -3615,33 +3619,33 @@ map_sections_to_segments (bfd *abfd)
 	  new_segment = FALSE;
 	}
 
-      if (! new_segment)
+      if (new_segment)
 	{
-	  if ((hdr->flags & SEC_READONLY) == 0)
-	    writable = TRUE;
-	  last_hdr = hdr;
-	  /* .tbss sections effectively have zero size.  */
-	  if ((hdr->flags & (SEC_THREAD_LOCAL | SEC_LOAD)) != SEC_THREAD_LOCAL)
-	    last_size = hdr->size;
-	  else
-	    last_size = 0;
-	  continue;
-	}
+	  /* We need a new program segment.  We must create a new program
+	     header holding all the sections from phdr_index until hdr.  */
 
-      /* We need a new program segment.  We must create a new program
-         header holding all the sections from phdr_index until hdr.  */
-
-      m = make_mapping (abfd, sections, phdr_index, i, phdr_in_segment);
-      if (m == NULL)
-	goto error_return;
+	  m = make_mapping (abfd, sections, phdr_index, i, phdr_in_segment);
+	  if (m == NULL)
+	    goto error_return;
 
-      *pm = m;
-      pm = &m->next;
+	  *pm = m;
+	  pm = &m->next;
+	  phdr_index = i;
+	  phdr_in_segment = FALSE;
+	  writable = FALSE;
+	  loadable = 0;
+	  last_nz = NULL;
+	}
 
       if ((hdr->flags & SEC_READONLY) == 0)
 	writable = TRUE;
-      else
-	writable = FALSE;
+      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.  */
@@ -3649,8 +3653,8 @@ map_sections_to_segments (bfd *abfd)
 	last_size = hdr->size;
       else
 	last_size = 0;
-      phdr_index = i;
-      phdr_in_segment = FALSE;
+      if (last_size != 0)
+	last_nz = hdr;
     }
 
   /* Create a final PT_LOAD program segment.  */
@@ -3815,27 +3819,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.  */
 
@@ -3847,6 +3830,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/2005-05-06/ld/testsuite/ld-elf/seg.d	1970-01-01 01:00:00.000000000 +0100
+++ 2005-05-06-elf-seg/ld/testsuite/ld-elf/seg.d	2005-05-09 12:34:37.000000000 +0200
@@ -0,0 +1,20 @@
+#source: seg.s
+#ld: -T seg.ld
+#objdump: -p
+#xfail: "avr-*-*" "cr16c-*-*" "crx-*-*" "dlx-*-*" "h8300-*-*" "hppa64-*-*"
+#xfail: "i960-*-*" "ip2k-*-*" "m32r-*-*" "m88k-*-*" "mips-*-*" "msp430-*-*"
+
+.*:.*elf.*
+#...
+Program Header:
+[ 	]*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/2005-05-06/ld/testsuite/ld-elf/seg.ld	1970-01-01 01:00:00.000000000 +0100
+++ 2005-05-06-elf-seg/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/2005-05-06/ld/testsuite/ld-elf/seg.s	1970-01-01 01:00:00.000000000 +0100
+++ 2005-05-06-elf-seg/ld/testsuite/ld-elf/seg.s	2005-05-09 10:48:55.000000000 +0200
@@ -0,0 +1,39 @@
+ .equiv	PAGESIZE, 0x100000
+
+.global	_start
+
+ .text
+_start:
+ .byte	0x11
+
+ .section	.rodata, "a", "progbits"
+ .p2align	4
+const:
+ .fill	PAGESIZE - 16, 1, 0x22
+
+ .data
+data:
+ .fill	PAGESIZE, 1, 0x33
+
+ .section	.write1, "aw", "progbits"
+write1:
+ .fill	PAGESIZE, 1, 0x44
+
+ .section	.write2, "aw", "progbits"
+write2:
+ .fill	PAGESIZE, 1, 0x55
+
+ .section	.exec1, "ax", "progbits"
+exec1:
+ .fill	PAGESIZE, 1, 0x66
+
+ .section	.write3, "aw", "progbits"
+write3:
+ .fill	PAGESIZE, 1, 0x77
+
+ .section	.bss3, "aw", "nobits"
+bss3:
+
+ .section	.exec2, "ax", "progbits"
+exec2:
+ .fill	PAGESIZE, 1, 0x88

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH] ELF section to segment mapping adjustments
  2005-05-10 12:40 [PATCH] ELF section to segment mapping adjustments Jan Beulich
@ 2005-05-10 15:21 ` Ian Lance Taylor
  0 siblings, 0 replies; 4+ messages in thread
From: Ian Lance Taylor @ 2005-05-10 15:21 UTC (permalink / raw)
  To: Jan Beulich; +Cc: binutils

"Jan Beulich" <JBeulich@novell.com> writes:

> Shouldn't the executable permission be handled like the writeable one, i.e.
> attempting to not merge sections with different permissions into one
> segment?

If we break a segment to avoid merging a non-executable section with
an executable section, then we will wind up putting .text and .rodata
into different segments.  We don't want to do that in the normal case.

Ian

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH] ELF section to segment mapping adjustments
       [not found] <s280e191.021@emea1-mh.id2.novell.com>
@ 2005-05-10 16:45 ` Ian Lance Taylor
  0 siblings, 0 replies; 4+ messages in thread
From: Ian Lance Taylor @ 2005-05-10 16:45 UTC (permalink / raw)
  To: Jan Beulich; +Cc: binutils

"Jan Beulich" <JBeulich@novell.com> writes:

> >>> Ian Lance Taylor <ian@airs.com> 10.05.05 17:12:55 >>>
> >"Jan Beulich" <JBeulich@novell.com> writes:
> >
> >> Shouldn't the executable permission be handled like the writeable one, i.e.
> >> attempting to not merge sections with different permissions into one
> >> segment?
> >
> >If we break a segment to avoid merging a non-executable section with
> >an executable section, then we will wind up putting .text and .rodata
> >into different segments.  We don't want to do that in the normal case.
> 
> I understand that's been the traditional behavior, but I don't know
> why exactly this is happening (except for space saving
> reasons). With attempts in various places to close holes where one
> can execute stuff in memory that shouldn't really be executed, it'd
> seem to me that more enforcement in this area would be quite
> reasonable to expect...

Those holes are related to writable memory.  It would be a big mistake
to merge a writable section with an executable section and thus make
the segment writable.  But it does no harm to have read-only data
mixed into an executable segment.  Sure, the person doing the link
could put then execute data which is in the .rodata section.  But they
can already put that same data into the .text section, so there is no
additional vulnerability.

Saving space is less important than security, but it is not of
neglible importance.

Ian

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH] ELF section to segment mapping adjustments
@ 2005-05-10 15:32 Jan Beulich
  0 siblings, 0 replies; 4+ messages in thread
From: Jan Beulich @ 2005-05-10 15:32 UTC (permalink / raw)
  To: ian; +Cc: binutils

>>> Ian Lance Taylor <ian@airs.com> 10.05.05 17:12:55 >>>
>"Jan Beulich" <JBeulich@novell.com> writes:
>
>> Shouldn't the executable permission be handled like the writeable one, i.e.
>> attempting to not merge sections with different permissions into one
>> segment?
>
>If we break a segment to avoid merging a non-executable section with
>an executable section, then we will wind up putting .text and .rodata
>into different segments.  We don't want to do that in the normal case.

I understand that's been the traditional behavior, but I don't know why exactly this is happening (except for space saving reasons). With attempts in various places to close holes where one can execute stuff in memory that shouldn't really be executed, it'd seem to me that more enforcement in this area would be quite reasonable to expect...

Jan

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2005-05-10 16:05 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2005-05-10 12:40 [PATCH] ELF section to segment mapping adjustments Jan Beulich
2005-05-10 15:21 ` Ian Lance Taylor
2005-05-10 15:32 Jan Beulich
     [not found] <s280e191.021@emea1-mh.id2.novell.com>
2005-05-10 16:45 ` Ian Lance Taylor

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).