From 5c1a3f0fa74b2b0cc679d03e4158b4f37ae973f1 Mon Sep 17 00:00:00 2001 From: Nathan Sidwell Date: Wed, 7 Oct 2009 07:25:36 +0000 Subject: ld/ * ldlang.c (lang_new_phdr): Check PHDRS and FILEHDR in loadable segments do not appear after a different loadable segment. * ld.texinfo (PHDRS): Document order of processing segments. Document where PHDRS and FILEHDR may appear. ld/testsuite/ * ld-scripts/phdrs3.d: New. * ld-scripts/phdrs3.t: New. * ld-scripts/phdrs3.exp: New. --- ld/ChangeLog | 7 +++++++ ld/ld.texinfo | 8 +++++--- ld/ldlang.c | 10 +++++++++- ld/testsuite/ld-scripts/phdrs3.d | 4 ++++ ld/testsuite/ld-scripts/phdrs3.exp | 38 ++++++++++++++++++++++++++++++++++++++ ld/testsuite/ld-scripts/phdrs3.t | 16 ++++++++++++++++ 6 files changed, 79 insertions(+), 4 deletions(-) create mode 100644 ld/testsuite/ld-scripts/phdrs3.d create mode 100644 ld/testsuite/ld-scripts/phdrs3.exp create mode 100644 ld/testsuite/ld-scripts/phdrs3.t (limited to 'ld') diff --git a/ld/ChangeLog b/ld/ChangeLog index df61ad0..fe15c36 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -1,3 +1,10 @@ +2009-10-06 Nathan Sidwell + + * ldlang.c (lang_new_phdr): Check PHDRS and FILEHDR in loadable + segments do not appear after a different loadable segment. + * ld.texinfo (PHDRS): Document order of processing segments. + Document where PHDRS and FILEHDR may appear. + 2009-10-03 Alan Modra * emultempl/ppc32elf.em (emit_stub_syms): Init to -1. diff --git a/ld/ld.texinfo b/ld/ld.texinfo index e17d3fc..978ae66 100644 --- a/ld/ld.texinfo +++ b/ld/ld.texinfo @@ -4710,7 +4710,8 @@ The @var{name} is used only for reference in the @code{SECTIONS} command of the linker script. It is not put into the output file. Program header names are stored in a separate name space, and will not conflict with symbol names, file names, or section names. Each program header -must have a distinct name. +must have a distinct name. The headers are processed in order and it +is usual for them to map to sections in ascending load address order. Certain program header types describe segments of memory which the system loader will load from the file. In the linker script, you @@ -4734,11 +4735,12 @@ segment at all. @kindex FILEHDR @kindex PHDRS -You may use the @code{FILEHDR} and @code{PHDRS} keywords appear after +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. +include the ELF program headers themselves. If applied to a loadable +segment (@code{PT_LOAD}), it must be the first loadable segment. 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 8371370..a46438e 100644 --- a/ld/ldlang.c +++ b/ld/ldlang.c @@ -6765,6 +6765,7 @@ 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; @@ -6774,9 +6775,16 @@ 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) + { + einfo (_("%X%P:%S: PHDRS and FILEHDR are only permitted for the first PT_LOAD segment\n")); + hdrs = FALSE; + } + *pp = n; } diff --git a/ld/testsuite/ld-scripts/phdrs3.d b/ld/testsuite/ld-scripts/phdrs3.d new file mode 100644 index 0000000..78fe4e4 --- /dev/null +++ b/ld/testsuite/ld-scripts/phdrs3.d @@ -0,0 +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 diff --git a/ld/testsuite/ld-scripts/phdrs3.exp b/ld/testsuite/ld-scripts/phdrs3.exp new file mode 100644 index 0000000..90651af --- /dev/null +++ b/ld/testsuite/ld-scripts/phdrs3.exp @@ -0,0 +1,38 @@ +# Test PHDRS in a linker script. +# By Nathan Sidwell +# Copyright 2009 Free Software Foundation, Inc. +# +# This file is part of the GNU Binutils. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, +# MA 02110-1301, USA. + +# PHDRS is only meaningful for ELF. +if ![is_elf_format] { + return +} + +load_lib ld-lib.exp + +set testname "PHDRS headers" + +set old_ldflags $LDFLAGS +if { [istarget spu*-*-*] } { + set LDFLAGS "$LDFLAGS --no-overlays" +} + +run_dump_test "phdrs3" + +set LDFLAGS $old_ldflags diff --git a/ld/testsuite/ld-scripts/phdrs3.t b/ld/testsuite/ld-scripts/phdrs3.t new file mode 100644 index 0000000..4bd4e85 --- /dev/null +++ b/ld/testsuite/ld-scripts/phdrs3.t @@ -0,0 +1,16 @@ +PHDRS +{ + data PT_LOAD ; + header PT_PHDR PHDRS ; /* OK */ + text PT_LOAD FILEHDR PHDRS ; +} + +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/ : { *(.*) } +} -- cgit v1.1