linker bug 10515

H.J. Lu hjl.tools@gmail.com
Thu Oct 8 00:51:00 GMT 2009


On Wed, Oct 7, 2009 at 3:50 PM, H.J. Lu <hjl.tools@gmail.com> wrote:
> On Tue, Oct 6, 2009 at 3:29 AM, Alan Modra <amodra@bigpond.net.au> wrote:
>> On Tue, Oct 06, 2009 at 10:33:53AM +0100, Nathan Sidwell wrote:
>>> Alan Modra wrote:
>>>
>>>> No.  I think you should just check PT_LOAD headers.  That would allow
>>>> various non-load headers to appear first if anyone so desires
>>>> (eg. PT_PHDR, PT_INTERP).  It would also simplify the documentation
>>>> and error message.
>>>
>>> do you mean that only the first PT_LOAD segment can have headers, and no
>>> subsequent PT_LOAD headers?  Please clarify
>>
>> Yes.  You would need overlapping PT_LOAD segments if more than one
>> could have PHDRS.  I suppose that would be possible with overlays but
>> I doubt the existing code supports it.
>>
>
> FYI, Linux ia64 kernel does use it:
>
> http://www.sourceware.org/bugzilla/show_bug.cgi?id=10744
>
> Can we allow FILEHDRS/PHDRS if the previous segment has the same
> headers?
>
> Thanks.
>

Here is a patch.  OK to install?

Thanks.


-- 
H.J.
---

ld/

2009-10-07  Nathan Sidwell  <nathan@codesourcery.com>

	PR ld/10744
	* ldlang.c (lang_new_phdr): Allow PHDRS and FILEHDR in
	PT_LOAD segment if previous segment contains either
	PHDRS or FILEHDR.

	* ld.texinfo (PHDRS): Updated.

ld/testsuite/

2009-10-07  H.J. Lu  <hongjiu.lu@intel.com>
	    Nathan Sidwell  <nathan@codesourcery.com>

	* ld-scripts/phdrs3.d: Updated.

	* ld-scripts/phdrs3.exp: Run phdrs3a.

	* ld-scripts/phdrs3a.d: New.
	* ld-scripts/phdrs3a.t: Likewise.
-------------- next part --------------
ld/

2009-10-07  Nathan Sidwell  <nathan@codesourcery.com>

	PR ld/10744
	* ldlang.c (lang_new_phdr): Allow PHDRS and FILEHDR in
	PT_LOAD segment if previous segment contains either
	PHDRS or FILEHDR.

	* ld.texinfo (PHDRS): Updated.

ld/testsuite/

2009-10-07  H.J. Lu  <hongjiu.lu@intel.com>
	    Nathan Sidwell  <nathan@codesourcery.com>

	* ld-scripts/phdrs3.d: Updated.

	* ld-scripts/phdrs3.exp: Run phdrs3a.

	* ld-scripts/phdrs3a.d: New.
	* ld-scripts/phdrs3a.t: Likewise.

diff --git a/ld/ld.texinfo b/ld/ld.texinfo
index 978ae66..8ca0e14 100644
--- a/ld/ld.texinfo
+++ b/ld/ld.texinfo
@@ -4739,8 +4739,9 @@ You may use the @code{FILEHDR} and @code{PHDRS} keywords after
 the program header type to further describe the contents of the segment.
 The @code{FILEHDR} keyword means that the segment should include the ELF
 file header.  The @code{PHDRS} keyword means that the segment should
-include the ELF program headers themselves.  If applied to a loadable
-segment (@code{PT_LOAD}), it must be the first loadable segment.
+include the ELF program headers themselves.  These may only be applied
+to the first segment, or to a segment that appears immediately after
+another segment containing either @code{PHDRS} or @code{FILEHDR}.
 
 The @var{type} may be one of the following.  The numbers indicate the
 value of the keyword.
diff --git a/ld/ldlang.c b/ld/ldlang.c
index a46438e..92dccbb 100644
--- a/ld/ldlang.c
+++ b/ld/ldlang.c
@@ -6765,7 +6765,6 @@ lang_new_phdr (const char *name,
 	       etree_type *flags)
 {
   struct lang_phdr *n, **pp;
-  bfd_boolean hdrs;
 
   n = (struct lang_phdr *) stat_alloc (sizeof (struct lang_phdr));
   n->next = NULL;
@@ -6775,14 +6774,12 @@ lang_new_phdr (const char *name,
   n->phdrs = phdrs;
   n->at = at;
   n->flags = flags;
-  
-  hdrs = n->type == 1 && (phdrs || filehdr);
 
   for (pp = &lang_phdr_list; *pp != NULL; pp = &(*pp)->next)
-    if (hdrs && (*pp)->type == 1)
+    if ((filehdr || phdrs) && !((*pp)->filehdr || (*pp)->phdrs))
       {
-	einfo (_("%X%P:%S: PHDRS and FILEHDR are only permitted for the first PT_LOAD segment\n"));
-	hdrs = FALSE;
+	einfo (_("%X%P:%S: PHDRS and FILEHDR are only permitted if all previous segments contain headers, `%s' does not\n"), (*pp)->name);
+	filehdr = phdrs = FALSE;
       }
 
   *pp = n;
diff --git a/ld/testsuite/ld-scripts/phdrs3.d b/ld/testsuite/ld-scripts/phdrs3.d
index 78fe4e4..ecbe84f 100644
--- a/ld/testsuite/ld-scripts/phdrs3.d
+++ b/ld/testsuite/ld-scripts/phdrs3.d
@@ -1,4 +1,4 @@
 # name: PHDRS headers
 # source: phdrs.s
 # ld: -T phdrs3.t
-# error: \A[^ \n:]*:[^:\n]*:5: PHDRS and FILEHDR are only permitted for the first PT_LOAD segment\Z
+# error: \A[^ \n:]*:[^:\n]*:4: PHDRS and FILEHDR are only permitted if all previous segments contain headers, `data' does not\n[^ \n:]*:[^:\n]*:5: PHDRS and FILEHDR are only permitted if all previous segments contain headers, `data' does not\Z
diff --git a/ld/testsuite/ld-scripts/phdrs3.exp b/ld/testsuite/ld-scripts/phdrs3.exp
index 90651af..e7e0414 100644
--- a/ld/testsuite/ld-scripts/phdrs3.exp
+++ b/ld/testsuite/ld-scripts/phdrs3.exp
@@ -34,5 +34,6 @@ if { [istarget spu*-*-*] } {
 }
 
 run_dump_test "phdrs3"
+run_dump_test "phdrs3a"
 
 set LDFLAGS $old_ldflags
diff --git a/ld/testsuite/ld-scripts/phdrs3a.d b/ld/testsuite/ld-scripts/phdrs3a.d
new file mode 100644
index 0000000..cd151a9
--- /dev/null
+++ b/ld/testsuite/ld-scripts/phdrs3a.d
@@ -0,0 +1,9 @@
+#name: PHDRS headers 3a
+#source: phdrs.s
+#ld: -T phdrs3a.t
+#readelf: -l --wide
+
+#...
+[ \t]+LOAD.*
+[ \t]+LOAD.*
+#pass
diff --git a/ld/testsuite/ld-scripts/phdrs3a.t b/ld/testsuite/ld-scripts/phdrs3a.t
new file mode 100644
index 0000000..c07ff34
--- /dev/null
+++ b/ld/testsuite/ld-scripts/phdrs3a.t
@@ -0,0 +1,15 @@
+PHDRS
+{
+  data PT_LOAD FILEHDR PHDRS FLAGS(4);
+  text PT_LOAD FILEHDR PHDRS FLAGS(1);
+}
+
+SECTIONS
+{
+  /* This test will fail on architectures where the startaddress below
+     is less than the constant MAXPAGESIZE.  */
+  . = 0x800000 + SIZEOF_HEADERS;
+  .text : { *(.text) } :text
+  .data : { *(.data) } :data
+  /DISCARD/ : { *(.*) }
+}


More information about the Binutils mailing list