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