diff options
author | Matthew Fortune <matthew.fortune@imgtec.com> | 2016-04-14 11:49:53 +0100 |
---|---|---|
committer | Matthew Fortune <matthew.fortune@imgtec.com> | 2016-04-18 12:45:46 +0100 |
commit | cdf969539c718acb1f3f031b2c55d5274a538717 (patch) | |
tree | 003ffa5726fcc2217dc4aafcdeb1efa46ff88b04 /ld | |
parent | 5947319ef398728052a22575e1d0de0e94e4220f (diff) | |
download | gdb-cdf969539c718acb1f3f031b2c55d5274a538717.zip gdb-cdf969539c718acb1f3f031b2c55d5274a538717.tar.gz gdb-cdf969539c718acb1f3f031b2c55d5274a538717.tar.bz2 |
Add new NOCROSSREFS_TO linker script command
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.
Diffstat (limited to 'ld')
-rw-r--r-- | ld/ChangeLog | 20 | ||||
-rw-r--r-- | ld/NEWS | 2 | ||||
-rw-r--r-- | ld/ld.texinfo | 19 | ||||
-rw-r--r-- | ld/ldcref.c | 24 | ||||
-rw-r--r-- | ld/ldgram.y | 6 | ||||
-rw-r--r-- | ld/ldlang.c | 10 | ||||
-rw-r--r-- | ld/ldlang.h | 3 | ||||
-rw-r--r-- | ld/ldlex.l | 1 | ||||
-rw-r--r-- | ld/testsuite/ld-scripts/cross4.t | 10 | ||||
-rw-r--r-- | ld/testsuite/ld-scripts/cross5.t | 10 | ||||
-rw-r--r-- | ld/testsuite/ld-scripts/cross6.t | 9 | ||||
-rw-r--r-- | ld/testsuite/ld-scripts/cross7.t | 9 | ||||
-rw-r--r-- | ld/testsuite/ld-scripts/crossref.exp | 64 |
13 files changed, 180 insertions, 7 deletions
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 <matthew.fortune@imgtec.com> + + * 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 <hongjiu.lu@intel.com> * Makefile.in: Regenerated with automake 1.11.6. @@ -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. +* The NOCROSSREFSTO command was added to the linker script language. + Changes in 2.26: * 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 that the @code{NOCROSSREFS} command uses output section names, not input section names. +@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 *statement) symname = sym->name; for (ncrs = nocrossref_list; ncrs != NULL; ncrs = ncrs->next) for (ncr = ncrs->list; ncr != NULL; ncr = ncr->next) - if (strcmp (ncr->name, outsecname) == 0) - check_refs (symname, FALSE, sym->section, abfd, ncrs); + { + if (strcmp (ncr->name, outsecname) == 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 *ignore ATTRIBUTE_UNUSED) for (ncrs = nocrossref_list; ncrs != NULL; ncrs = ncrs->next) for (ncr = ncrs->list; ncr != NULL; ncr = ncr->next) - if (strcmp (ncr->name, defsecname) == 0) - for (ref = h->refs; ref != NULL; ref = ref->next) - check_refs (hl->root.string, TRUE, hl->u.def.section, - ref->abfd, ncrs); + { + if (strcmp (ncr->name, defsecname) == 0) + for (ref = h->refs; ref != NULL; ref = 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; + } 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 <integer> 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 = (struct lang_nocrossrefs *) xmalloc (sizeof *n); n->next = nocrossref_list; n->list = l; + n->onlyfirst = FALSE; nocrossref_list = n; /* Set notice_all so that we get informed about all symbols. */ link_info.notice_all = 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 = TRUE; +} /* Overlay handling. We handle overlays with some static variables. */ 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; }; /* 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 @@ -298,6 +298,7 @@ V_IDENTIFIER [*?.$_a-zA-Z\[\]\-\!\^\\]([*?.$_a-zA-Z0-9\[\]\-\!\^\\]|::)* <BOTH,SCRIPT>"BYTE" { RTOKEN( BYTE);} <BOTH,SCRIPT>"NOFLOAT" { RTOKEN(NOFLOAT);} <EXPRESSION,BOTH,SCRIPT>"NOCROSSREFS" { RTOKEN(NOCROSSREFS);} +<EXPRESSION,BOTH,SCRIPT>"NOCROSSREFS_TO" { RTOKEN(NOCROSSREFS_TO);} <BOTH,SCRIPT>"OVERLAY" { RTOKEN(OVERLAY); } <BOTH,SCRIPT>"SORT_BY_NAME" { RTOKEN(SORT_BY_NAME); } <BOTH,SCRIPT>"SORT_BY_ALIGNMENT" { RTOKEN(SORT_BY_ALIGNMENT); } diff --git a/ld/testsuite/ld-scripts/cross4.t b/ld/testsuite/ld-scripts/cross4.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/cross5.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/cross6.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/cross7.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" if { ![is_remote host] && [which $CC] == 0 } { untested $test1 untested $test2 untested $test3 + untested $test4 + untested $test5 + untested $test6 + untested $test7 return } @@ -158,5 +166,61 @@ if [string match "" $exec_output] then { fail $test3 } +set exec_output [run_host_cmd "$ld" "$flags -o tmpdir/cross4 -T $srcdir/$subdir/cross4.t tmpdir/cross4.o"] +set exec_output [prune_warnings $exec_output] + +regsub -all "(^|\n)($ld: warning: cannot find entry symbol\[^\n\]*\n?)" $exec_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/$subdir/cross5.t tmpdir/cross4.o"] +set exec_output [prune_warnings $exec_output] + +regsub -all "(^|\n)($ld: warning: cannot find entry symbol\[^\n\]*\n?)" $exec_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_output] { + pass $test5 + } else { + fail $test5 + } +} + +set exec_output [run_host_cmd "$ld" "$flags -o tmpdir/cross6 -T $srcdir/$subdir/cross6.t tmpdir/cross3.o"] +set exec_output [prune_warnings $exec_output] + +regsub -all "(^|\n)($ld: warning: cannot find entry symbol\[^\n\]*\n?)" $exec_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/$subdir/cross7.t tmpdir/cross3.o"] +set exec_output [prune_warnings $exec_output] + +regsub -all "(^|\n)($ld: warning: cannot find entry symbol\[^\n\]*\n?)" $exec_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_output] { + pass $test7 + } else { + fail $test7 + } +} + set CFLAGS "$old_CFLAGS" set CC "$old_CC" |