From 89753bbf8102edc2aa4262a4d43f1a71a10e34f3 Mon Sep 17 00:00:00 2001 From: Alan Modra Date: Sat, 20 Feb 2021 15:45:44 +1030 Subject: [PATCH] Warn when a script redefines a symbol Note that we don't even warn if scripts adjust a symbol as in ld-elf/var1 and ld-scripts/pr14962. include/ * bfdlink.h (struct bfd_link_info): Add warn_multiple_definition. ld/ * ldexp.c (exp_fold_tree_1): Warn on script defining a symbol defined in an object file. * ldmain.c (multiple_definition): Heed info->warn_multiple_definition. * testsuite/ld-scripts/defined5.d: Expect a warning. --- include/ChangeLog | 4 ++++ include/bfdlink.h | 8 ++++++-- ld/ChangeLog | 7 +++++++ ld/ldexp.c | 15 +++++++++------ ld/ldmain.c | 4 +++- ld/testsuite/ld-scripts/defined5.d | 5 +++-- 6 files changed, 32 insertions(+), 11 deletions(-) diff --git a/include/ChangeLog b/include/ChangeLog index 71f0beb13b..616b923b53 100644 --- a/include/ChangeLog +++ b/include/ChangeLog @@ -1,3 +1,7 @@ +2021-02-21 Alan Modra + + * bfdlink.h (struct bfd_link_info): Add warn_multiple_definition. + 2021-02-17 Nick Alcock * ctf-api.h (ctf_arc_lookup_symbol_name): New. diff --git a/include/bfdlink.h b/include/bfdlink.h index 079e31227e..95728b6f03 100644 --- a/include/bfdlink.h +++ b/include/bfdlink.h @@ -465,12 +465,16 @@ struct bfd_link_info statics. */ unsigned int task_link: 1; - /* TRUE if ok to have multiple definition. */ + /* TRUE if ok to have multiple definitions, without warning. */ unsigned int allow_multiple_definition: 1; - /* TRUE if ok to have prohibit multiple definition of absolute symbols. */ + /* TRUE if multiple definition of absolute symbols (eg. from -R) should + be reported. */ unsigned int prohibit_multiple_definition_absolute: 1; + /* TRUE if multiple definitions should only warn. */ + unsigned int warn_multiple_definition: 1; + /* TRUE if ok to have version with no definition. */ unsigned int allow_undefined_version: 1; diff --git a/ld/ChangeLog b/ld/ChangeLog index 9d16c30520..2339a4014c 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -1,3 +1,10 @@ +2021-02-21 Alan Modra + + * ldexp.c (exp_fold_tree_1): Warn on script defining a symbol + defined in an object file. + * ldmain.c (multiple_definition): Heed info->warn_multiple_definition. + * testsuite/ld-scripts/defined5.d: Expect a warning. + 2021-02-19 Alan Modra * testsuite/lib/ld-lib.exp: Whitespace. diff --git a/ld/ldexp.c b/ld/ldexp.c index 084bb17c4b..016784505b 100644 --- a/ld/ldexp.c +++ b/ld/ldexp.c @@ -1186,16 +1186,19 @@ exp_fold_tree_1 (etree_type *tree) { if (expld.result.section == NULL) expld.result.section = expld.section; - if (!update_definedness (tree->assign.dst, h) && 0) + if (!update_definedness (tree->assign.dst, h) + && expld.assign_name != NULL) { - /* Symbol was already defined. For now this error - is disabled because it causes failures in the ld - testsuite: ld-elf/var1, ld-scripts/defined5, and - ld-scripts/pr14962. Some of these no doubt - reflect scripts used in the wild. */ + /* Symbol was already defined, and the script isn't + modifying the symbol value for some reason as in + ld-elf/var1 and ld-scripts/pr14962. + For now this is only a warning. */ + unsigned int warn = link_info.warn_multiple_definition; + link_info.warn_multiple_definition = 1; (*link_info.callbacks->multiple_definition) (&link_info, h, link_info.output_bfd, expld.result.section, expld.result.value); + link_info.warn_multiple_definition = warn; } if (expld.phase == lang_fixed_phase_enum) { diff --git a/ld/ldmain.c b/ld/ldmain.c index 863df0293e..5c88ee744f 100644 --- a/ld/ldmain.c +++ b/ld/ldmain.c @@ -1074,7 +1074,9 @@ multiple_definition (struct bfd_link_info *info, nval = oval; obfd = NULL; } - einfo (_("%X%P: %C: multiple definition of `%pT'"), + if (!info->warn_multiple_definition) + einfo ("%X"); + einfo (_("%P: %C: multiple definition of `%pT'"), nbfd, nsec, nval, name); if (obfd != NULL) einfo (_("; %D: first defined here"), obfd, osec, oval); diff --git a/ld/testsuite/ld-scripts/defined5.d b/ld/testsuite/ld-scripts/defined5.d index 2530c0e09e..7aa680b85a 100644 --- a/ld/testsuite/ld-scripts/defined5.d +++ b/ld/testsuite/ld-scripts/defined5.d @@ -1,10 +1,11 @@ #ld: -Tdefined5.t +#warning: .*multiple definition of `defined'.* #nm: -B -#source: defined5.s #xfail: [is_xcoff_format] # xcoff outputs value of "defined" from the object file -# Check that arithmetic on DEFINED works. +# Check that a script can override an object file symbol, if multiple +# definitions are allowed. See pr12356. #... 0+1000 D defined #pass -- 2.34.1