From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 110713 invoked by alias); 18 Apr 2016 11:49:14 -0000 Mailing-List: contact binutils-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: binutils-owner@sourceware.org Received: (qmail 110697 invoked by uid 89); 18 Apr 2016 11:49:12 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.3 required=5.0 tests=AWL,BAYES_00,RCVD_IN_DNSWL_NONE,RP_MATCHES_RCVD,SPF_PASS autolearn=ham version=3.3.2 spammy=hongjiuluintelcom, hongjiu.lu@intel.com, detects, 2987 X-HELO: mailapp01.imgtec.com Received: from mailapp01.imgtec.com (HELO mailapp01.imgtec.com) (195.59.15.196) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Mon, 18 Apr 2016 11:49:01 +0000 Received: from HHMAIL01.hh.imgtec.org (unknown [10.100.10.19]) by Websense Email with ESMTPS id E3300ABF2EF88; Mon, 18 Apr 2016 12:48:54 +0100 (IST) Received: from hhmail02.hh.imgtec.org ([fe80::5400:d33e:81a4:f775]) by HHMAIL01.hh.imgtec.org ([fe80::710b:f219:72bc:e0b3%26]) with mapi id 14.03.0266.001; Mon, 18 Apr 2016 12:48:57 +0100 From: Matthew Fortune To: Nick Clifton , Alan Modra , "Hans-Peter Nilsson" CC: "binutils@sourceware.org" Subject: RE: [PATCH] Add new NOCROSSREFSTO linker script command Date: Mon, 18 Apr 2016 11:49:00 -0000 Message-ID: <6D39441BF12EF246A7ABCE6654B023537E3D959B@hhmail02.hh.imgtec.org> References: <6D39441BF12EF246A7ABCE6654B023537E3D4B60@hhmail02.hh.imgtec.org> <20160414223011.GB27620@bubble.grove.modra.org> <6D39441BF12EF246A7ABCE6654B023537E3D6082@hhmail02.hh.imgtec.org> <5714C1D5.2090904@redhat.com> In-Reply-To: <5714C1D5.2090904@redhat.com> Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 X-IsSubscribed: yes X-SW-Source: 2016-04/txt/msg00270.txt.bz2 Nick Clifton writes: > > I have no objection if this seems clearer. If there are no other > > opinions I'll update to add an underscore. >=20 > Please do. Otherwise the patch looks fine to me too. Thanks. Committed as below. Matthew NOCROSSREFS_TO is similar to the existing NOCROSSREFS command but only checks one direction of cross referencing. ld/ChangeLog * ld.texinfo: Document NOCROSSREFS_TO script command. * ldlang.h (struct lang_nocrossrefs): Add onlyfirst field. (lang_add_nocrossref_to): New prototype. * ldcref.c (check_local_sym_xref): Use onlyfirst to only look for symbols defined in the first section. (check_nocrossref): Likewise. * ldgram.y (NOCROSSREFS_TO): New script command. * ldlang.c (lang_add_nocrossref): Set onlyfirst to FALSE. (lang_add_nocrossref_to): New function. * ldlex.l (NOCROSSREFS_TO): New token. * NEWS: Mention NOCROSSREFS_TO. * testsuite/ld-scripts/cross4.t: New file. * testsuite/ld-scripts/cross5.t: Likewise. * testsuite/ld-scripts/cross6.t: Likewise. * testsuite/ld-scripts/cross7.t: Likewise. * testsuite/ld-scripts/crossref.exp: Run 4 new NOCROSSREFS_TO tests. --- ld/ChangeLog | 20 +++++++++++ ld/NEWS | 2 ++ ld/ld.texinfo | 19 +++++++++++ ld/ldcref.c | 24 ++++++++++---- ld/ldgram.y | 6 +++- ld/ldlang.c | 10 ++++++ ld/ldlang.h | 3 ++ ld/ldlex.l | 1 + ld/testsuite/ld-scripts/cross4.t | 10 ++++++ ld/testsuite/ld-scripts/cross5.t | 10 ++++++ ld/testsuite/ld-scripts/cross6.t | 9 +++++ ld/testsuite/ld-scripts/cross7.t | 9 +++++ ld/testsuite/ld-scripts/crossref.exp | 64 ++++++++++++++++++++++++++++++++= ++++ 13 files changed, 180 insertions(+), 7 deletions(-) create mode 100644 ld/testsuite/ld-scripts/cross4.t create mode 100644 ld/testsuite/ld-scripts/cross5.t create mode 100644 ld/testsuite/ld-scripts/cross6.t create mode 100644 ld/testsuite/ld-scripts/cross7.t diff --git a/ld/ChangeLog b/ld/ChangeLog index b340125..0701b12 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -1,3 +1,23 @@ +2016-04-18 Matthew Fortune + + * ld.texinfo: Document NOCROSSREFS_TO script command. + * ldlang.h (struct lang_nocrossrefs): Add onlyfirst field. + (lang_add_nocrossref_to): New prototype. + * ldcref.c (check_local_sym_xref): Use onlyfirst to only look for + symbols defined in the first section. + (check_nocrossref): Likewise. + * ldgram.y (NOCROSSREFS_TO): New script command. + * ldlang.c (lang_add_nocrossref): Set onlyfirst to FALSE. + (lang_add_nocrossref_to): New function. + * ldlex.l (NOCROSSREFS_TO): New token. + * NEWS: Mention NOCROSSREFS_TO. + * testsuite/ld-scripts/cross4.t: New file. + * testsuite/ld-scripts/cross5.t: Likewise. + * testsuite/ld-scripts/cross6.t: Likewise. + * testsuite/ld-scripts/cross7.t: Likewise. + * testsuite/ld-scripts/crossref.exp: Run 4 new NOCROSSREFS_TO + tests. + 2016-04-15 H.J. Lu =20 * Makefile.in: Regenerated with automake 1.11.6. diff --git a/ld/NEWS b/ld/NEWS index b88da5c..b4abd0b 100644 --- a/ld/NEWS +++ b/ld/NEWS @@ -9,6 +9,8 @@ * Support for -z nodynamic-undefined-weak in the x86 ELF linker, which avoids dynamic relocations against undefined weak symbols in executable. =20 +* The NOCROSSREFSTO command was added to the linker script language. + Changes in 2.26: =20 * Add --fix-stm32l4xx-629360 to the ARM linker to enable a link-time diff --git a/ld/ld.texinfo b/ld/ld.texinfo index d3d8dc6..7a2ed3a 100644 --- a/ld/ld.texinfo +++ b/ld/ld.texinfo @@ -3674,6 +3674,25 @@ an error and returns a non-zero exit status. Note t= hat the @code{NOCROSSREFS} command uses output section names, not input section names. =20 +@item NOCROSSREFS_TO(@var{tosection} @var{fromsection} @dots{}) +@kindex NOCROSSREFS_TO(@var{tosection} @var{fromsections}) +@cindex cross references +This command may be used to tell @command{ld} to issue an error about any +references to one section from a list of other sections. + +The @code{NOCROSSREFS} command is useful when ensuring that two or more +output sections are entirely independent but there are situations where +a one-way dependency is needed. For example, in a multi-core application +there may be shared code that can be called from each core but for safety +must never call back. + +The @code{NOCROSSREFS_TO} command takes a list of output section names. +The first section can not be referenced from any of the other sections. +If @command{ld} detects any references to the first section from any of +the other sections, it reports an error and returns a non-zero exit +status. Note that the @code{NOCROSSREFS_TO} command uses output section +names, not input section names. + @ifclear SingleFormat @item OUTPUT_ARCH(@var{bfdarch}) @kindex OUTPUT_ARCH(@var{bfdarch}) diff --git a/ld/ldcref.c b/ld/ldcref.c index b87f384..d96db20 100644 --- a/ld/ldcref.c +++ b/ld/ldcref.c @@ -534,8 +534,14 @@ check_local_sym_xref (lang_input_statement_type *state= ment) symname =3D sym->name; for (ncrs =3D nocrossref_list; ncrs !=3D NULL; ncrs =3D ncrs->next) for (ncr =3D ncrs->list; ncr !=3D NULL; ncr =3D ncr->next) - if (strcmp (ncr->name, outsecname) =3D=3D 0) - check_refs (symname, FALSE, sym->section, abfd, ncrs); + { + if (strcmp (ncr->name, outsecname) =3D=3D 0) + check_refs (symname, FALSE, sym->section, abfd, ncrs); + /* The NOCROSSREFS_TO command only checks symbols defined in + the first section in the list. */ + if (ncrs->onlyfirst) + break; + } } } } @@ -572,10 +578,16 @@ check_nocrossref (struct cref_hash_entry *h, void *ig= nore ATTRIBUTE_UNUSED) =20 for (ncrs =3D nocrossref_list; ncrs !=3D NULL; ncrs =3D ncrs->next) for (ncr =3D ncrs->list; ncr !=3D NULL; ncr =3D ncr->next) - if (strcmp (ncr->name, defsecname) =3D=3D 0) - for (ref =3D h->refs; ref !=3D NULL; ref =3D ref->next) - check_refs (hl->root.string, TRUE, hl->u.def.section, - ref->abfd, ncrs); + { + if (strcmp (ncr->name, defsecname) =3D=3D 0) + for (ref =3D h->refs; ref !=3D NULL; ref =3D ref->next) + check_refs (hl->root.string, TRUE, hl->u.def.section, + ref->abfd, ncrs); + /* The NOCROSSREFS_TO command only checks symbols defined in the first + section in the list. */ + if (ncrs->onlyfirst) + break; + } =20 return TRUE; } diff --git a/ld/ldgram.y b/ld/ldgram.y index a664258..9973b07 100644 --- a/ld/ldgram.y +++ b/ld/ldgram.y @@ -141,7 +141,7 @@ static int error_index; %token DEFINED TARGET_K SEARCH_DIR MAP ENTRY %token NEXT %token SIZEOF ALIGNOF ADDR LOADADDR MAX_K MIN_K -%token STARTUP HLL SYSLIB FLOAT NOFLOAT NOCROSSREFS +%token STARTUP HLL SYSLIB FLOAT NOFLOAT NOCROSSREFS NOCROSSREFS_TO %token ORIGIN FILL %token LENGTH CREATE_OBJECT_SYMBOLS INPUT GROUP OUTPUT CONSTRUCTORS %token ALIGNMOD AT SUBALIGN HIDDEN PROVIDE PROVIDE_HIDDEN AS_NEEDED @@ -353,6 +353,10 @@ ifile_p1: { lang_add_nocrossref ($3); } + | NOCROSSREFS_TO '(' nocrossref_list ')' + { + lang_add_nocrossref_to ($3); + } | EXTERN '(' extern_name_list ')' | INSERT_K AFTER NAME { lang_add_insert ($3, 0); } diff --git a/ld/ldlang.c b/ld/ldlang.c index 1947efc..856e3e2 100644 --- a/ld/ldlang.c +++ b/ld/ldlang.c @@ -7486,11 +7486,21 @@ lang_add_nocrossref (lang_nocrossref_type *l) n =3D (struct lang_nocrossrefs *) xmalloc (sizeof *n); n->next =3D nocrossref_list; n->list =3D l; + n->onlyfirst =3D FALSE; nocrossref_list =3D n; =20 /* Set notice_all so that we get informed about all symbols. */ link_info.notice_all =3D TRUE; } + +/* Record a section that cannot be referenced from a list of sections. */ + +void +lang_add_nocrossref_to (lang_nocrossref_type *l) +{ + lang_add_nocrossref (l); + nocrossref_list->onlyfirst =3D TRUE; +} =20 /* Overlay handling. We handle overlays with some static variables. */ =20 diff --git a/ld/ldlang.h b/ld/ldlang.h index 65d768b..0cb147c 100644 --- a/ld/ldlang.h +++ b/ld/ldlang.h @@ -464,6 +464,7 @@ struct lang_nocrossrefs { struct lang_nocrossrefs *next; lang_nocrossref_type *list; + bfd_boolean onlyfirst; }; =20 /* This structure is used to hold a list of input section names which @@ -654,6 +655,8 @@ extern void lang_new_phdr etree_type *); extern void lang_add_nocrossref (lang_nocrossref_type *); +extern void lang_add_nocrossref_to + (lang_nocrossref_type *); extern void lang_enter_overlay (etree_type *, etree_type *); extern void lang_enter_overlay_section diff --git a/ld/ldlex.l b/ld/ldlex.l index d70fad1..2eb8fc1 100644 --- a/ld/ldlex.l +++ b/ld/ldlex.l @@ -298,6 +298,7 @@ V_IDENTIFIER [*?.$_a-zA-Z\[\]\-\!\^\\]([*?.$_a-zA-Z0-9\= [\]\-\!\^\\]|::)* "BYTE" { RTOKEN( BYTE);} "NOFLOAT" { RTOKEN(NOFLOAT);} "NOCROSSREFS" { RTOKEN(NOCROSSREFS);} +"NOCROSSREFS_TO" { RTOKEN(NOCROSSREFS_TO);} "OVERLAY" { RTOKEN(OVERLAY); } "SORT_BY_NAME" { RTOKEN(SORT_BY_NAME); } "SORT_BY_ALIGNMENT" { RTOKEN(SORT_BY_ALIGNMENT); } diff --git a/ld/testsuite/ld-scripts/cross4.t b/ld/testsuite/ld-scripts/cro= ss4.t new file mode 100644 index 0000000..7f91b81 --- /dev/null +++ b/ld/testsuite/ld-scripts/cross4.t @@ -0,0 +1,10 @@ +NOCROSSREFS_TO(.data .nocrossrefs) + +SECTIONS +{ + .text : { *(.text) } + .nocrossrefs : { *(.nocrossrefs) } + .data : { *(.data) *(.opd) } + .bss : { *(.bss) *(COMMON) } + /DISCARD/ : { *(*) } +} diff --git a/ld/testsuite/ld-scripts/cross5.t b/ld/testsuite/ld-scripts/cro= ss5.t new file mode 100644 index 0000000..43657f1 --- /dev/null +++ b/ld/testsuite/ld-scripts/cross5.t @@ -0,0 +1,10 @@ +NOCROSSREFS_TO(.nocrossrefs .data) + +SECTIONS +{ + .text : { *(.text) } + .nocrossrefs : { *(.nocrossrefs) } + .data : { *(.data) *(.opd) } + .bss : { *(.bss) *(COMMON) } + /DISCARD/ : { *(*) } +} diff --git a/ld/testsuite/ld-scripts/cross6.t b/ld/testsuite/ld-scripts/cro= ss6.t new file mode 100644 index 0000000..4664221 --- /dev/null +++ b/ld/testsuite/ld-scripts/cross6.t @@ -0,0 +1,9 @@ +NOCROSSREFS_TO(.text .data) + +SECTIONS +{ + .text : { *(.text) } + .data : { *(.data) *(.opd) } + .bss : { *(.bss) *(COMMON) } + /DISCARD/ : { *(*) } +} diff --git a/ld/testsuite/ld-scripts/cross7.t b/ld/testsuite/ld-scripts/cro= ss7.t new file mode 100644 index 0000000..dad2103 --- /dev/null +++ b/ld/testsuite/ld-scripts/cross7.t @@ -0,0 +1,9 @@ +NOCROSSREFS_TO(.data .text) + +SECTIONS +{ + .text : { *(.text) } + .data : { *(.data) *(.opd) } + .bss : { *(.bss) *(COMMON) } + /DISCARD/ : { *(*) } +} diff --git a/ld/testsuite/ld-scripts/crossref.exp b/ld/testsuite/ld-scripts= /crossref.exp index 7244b90..4371320 100644 --- a/ld/testsuite/ld-scripts/crossref.exp +++ b/ld/testsuite/ld-scripts/crossref.exp @@ -22,11 +22,19 @@ set test1 "NOCROSSREFS 1" set test2 "NOCROSSREFS 2" set test3 "NOCROSSREFS 3" +set test4 "NOCROSSREFS_TO 1" +set test5 "NOCROSSREFS_TO 2" +set test6 "NOCROSSREFS_TO 3" +set test7 "NOCROSSREFS_TO 4" =20 if { ![is_remote host] && [which $CC] =3D=3D 0 } { untested $test1 untested $test2 untested $test3 + untested $test4 + untested $test5 + untested $test6 + untested $test7 return } =20 @@ -158,5 +166,61 @@ if [string match "" $exec_output] then { fail $test3 } =20 +set exec_output [run_host_cmd "$ld" "$flags -o tmpdir/cross4 -T $srcdir/$s= ubdir/cross4.t tmpdir/cross4.o"] +set exec_output [prune_warnings $exec_output] + +regsub -all "(^|\n)($ld: warning: cannot find entry symbol\[^\n\]*\n?)" $e= xec_output "\\1" exec_output + +if [string match "" $exec_output] then { + pass $test4 +} else { + verbose -log "$exec_output" + fail $test4 +} + +set exec_output [run_host_cmd "$ld" "$flags -o tmpdir/cross5 -T $srcdir/$s= ubdir/cross5.t tmpdir/cross4.o"] +set exec_output [prune_warnings $exec_output] + +regsub -all "(^|\n)($ld: warning: cannot find entry symbol\[^\n\]*\n?)" $e= xec_output "\\1" exec_output + +if [string match "" $exec_output] then { + fail $test5 +} else { + verbose -log "$exec_output" + if [regexp "prohibited cross reference from .* to `.*' in" $exec_outpu= t] { + pass $test5 + } else { + fail $test5 + } +} + +set exec_output [run_host_cmd "$ld" "$flags -o tmpdir/cross6 -T $srcdir/$s= ubdir/cross6.t tmpdir/cross3.o"] +set exec_output [prune_warnings $exec_output] + +regsub -all "(^|\n)($ld: warning: cannot find entry symbol\[^\n\]*\n?)" $e= xec_output "\\1" exec_output + +if [string match "" $exec_output] then { + pass $test6 +} else { + verbose -log "$exec_output" + fail $test6 +} + +set exec_output [run_host_cmd "$ld" "$flags -o tmpdir/cross7 -T $srcdir/$s= ubdir/cross7.t tmpdir/cross3.o"] +set exec_output [prune_warnings $exec_output] + +regsub -all "(^|\n)($ld: warning: cannot find entry symbol\[^\n\]*\n?)" $e= xec_output "\\1" exec_output + +if [string match "" $exec_output] then { + fail $test7 +} else { + verbose -log "$exec_output" + if [regexp "prohibited cross reference from .* to `.*' in" $exec_outpu= t] { + pass $test7 + } else { + fail $test7 + } +} + set CFLAGS "$old_CFLAGS" set CC "$old_CC" --=20 2.2.1