ld: Add --export-dynamic-symbol and --export-dynamic-symbol-list

Message ID 20200511064600.hjfo5x5xrrhrfmkx@google.com
State New
Headers show
Series
  • ld: Add --export-dynamic-symbol and --export-dynamic-symbol-list
Related show

Commit Message

On 2020-05-08, H.J. Lu wrote:
>On Fri, May 8, 2020 at 8:12 AM Fangrui Song <maskray@google.com> wrote:

>>

>>

>> On 2020-05-08, H.J. Lu wrote:

>> >On Fri, May 8, 2020 at 7:54 AM Fangrui Song <maskray@google.com> wrote:

>> >>

>> >> On 2020-05-08, H.J. Lu wrote:

>> >> >On Wed, May 6, 2020 at 11:42 AM Fangrui Song <maskray@google.com> wrote:

>> >> >>

>> >> >> On 2020-05-05, H.J. Lu wrote:

>> >> >> >On Tue, May 5, 2020 at 9:55 AM Fangrui Song <maskray@google.com> wrote:

>> >> >> >>

>> >> >> >>

>> >> >> >> On 2020-05-05, H.J. Lu wrote:

>> >> >> >> >On Tue, May 5, 2020 at 8:30 AM Fangrui Song <maskray@google.com> wrote:

>> >> >> >> >>

>> >> >> >> >> On 2020-05-05, H.J. Lu wrote:

>> >> >> >> >> >On Mon, May 4, 2020 at 7:10 PM Fangrui Song <maskray@google.com> wrote:

>> >> >> >> >> >>

>> >> >> >> >> >> On 2020-05-04, H.J. Lu wrote:

>> >> >> >> >> >> >On Mon, May 4, 2020 at 10:48 AM Fangrui Song <maskray@google.com> wrote:

>> >> >> >> >> >> >>

>> >> >> >> >> >> >> On 2020-05-03, H.J. Lu wrote:

>> >> >> >> >> >> >> >On Sat, May 2, 2020 at 11:15 PM Fangrui Song via Binutils

>> >> >> >> >> >> >> ><binutils@sourceware.org> wrote:

>> >> >> >> >> >> >> >>

>> >> >> >> >> >> >> >>         PR ld/25910

>> >> >> >> >> >> >> >>         * ldlang.c (export_dynamic_symbol_list): New.

>> >> >> >> >> >> >> >>         (ldlang_add_export_dynamic_symbol): New.

>> >> >> >> >> >> >> >>         (lang_place_export_dynamic_symbols): New.

>> >> >> >> >> >> >> >>         (lang_process): Handle export_dynamic_symbol_list.

>> >> >> >> >> >> >> >>         * ldlang.h (ldlang_add_export_dynamic_symbol): New.

>> >> >> >> >> >> >> >>         * ldlex.h (option_values): Add OPTION_EXPORT_DYNAMIC_SYMBOL.

>> >> >> >> >> >> >> >>         * lexsup.c (ld_options): Add entry for OPTION_EXPORT_DYNAMIC_SYMBOL.

>> >> >> >> >> >> >> >>         (parse_args): Handle it.

>> >> >> >> >> >> >> >>         * ld.texi: Add --export-dynamic-symbol documentation.

>> >> >> >> >> >> >> >>         * testsuite/ld-undefined/export-dynamic-symbol.exp: Run new test.

>> >> >> >> >> >> >> >>         * testsuite/ld-undefined/export-dynamic-symbol-1.d: New.

>> >> >> >> >> >> >> >> ---

>> >> >> >> >> >> >> >>  ld/ld.texi                                    |  8 +++++

>> >> >> >> >> >> >> >>  ld/ldlang.c                                   | 26 ++++++++++++++

>> >> >> >> >> >> >> >>  ld/ldlang.h                                   |  2 ++

>> >> >> >> >> >> >> >>  ld/ldlex.h                                    |  1 +

>> >> >> >> >> >> >> >>  ld/lexsup.c                                   |  7 ++++

>> >> >> >> >> >> >> >>  .../ld-undefined/export-dynamic-symbol-1.d    |  8 +++++

>> >> >> >> >> >> >> >>  .../ld-undefined/export-dynamic-symbol.exp    | 35 +++++++++++++++++++

>> >> >> >> >> >> >> >>  7 files changed, 87 insertions(+)

>> >> >> >> >> >> >> >>  create mode 100644 ld/testsuite/ld-undefined/export-dynamic-symbol-1.d

>> >> >> >> >> >> >> >>  create mode 100644 ld/testsuite/ld-undefined/export-dynamic-symbol.exp

>> >> >> >> >> >> >> >>

>> >> >> >> >> >> >> >> diff --git a/ld/ld.texi b/ld/ld.texi

>> >> >> >> >> >> >> >> index 4dc78e65fa..b3dc95f314 100644

>> >> >> >> >> >> >> >> --- a/ld/ld.texi

>> >> >> >> >> >> >> >> +++ b/ld/ld.texi

>> >> >> >> >> >> >> >> @@ -569,6 +569,14 @@ Note that this option is specific to ELF targeted ports.  PE targets

>> >> >> >> >> >> >> >>  support a similar function to export all symbols from a DLL or EXE; see

>> >> >> >> >> >> >> >>  the description of @samp{--export-all-symbols} below.

>> >> >> >> >> >> >> >>

>> >> >> >> >> >> >> >> +@kindex --export-dynamic-symbol=@var{symbol}

>> >> >> >> >> >> >> >> +@cindex export dynamic symbol

>> >> >> >> >> >> >> >> +@item --export-dynamic-symbol=@var{symbol}

>> >> >> >> >> >> >> >> +Specify a symbol that should be added to the dynamic symbol table.

>> >> >> >> >> >> >> >> +Additionally, force @var{symbol} to be entered in the output file as an

>> >> >> >> >> >> >> >> +undefined symbol.  Doing this may, for example, trigger linking of additional

>> >> >> >> >> >> >> >> +modules from archives.

>> >> >> >> >> >> >> >> +

>> >> >> >> >> >> >> >>  @ifclear SingleFormat

>> >> >> >> >> >> >> >>  @cindex big-endian objects

>> >> >> >> >> >> >> >>  @cindex endianness

>> >> >> >> >> >> >> >> diff --git a/ld/ldlang.c b/ld/ldlang.c

>> >> >> >> >> >> >> >> index b2cdb3603a..e7ecdfeaf0 100644

>> >> >> >> >> >> >> >> --- a/ld/ldlang.c

>> >> >> >> >> >> >> >> +++ b/ld/ldlang.c

>> >> >> >> >> >> >> >> @@ -3910,6 +3910,26 @@ lang_place_undefineds (void)

>> >> >> >> >> >> >> >>      insert_undefined (ptr->name);

>> >> >> >> >> >> >> >>  }

>> >> >> >> >> >> >> >>

>> >> >> >> >> >> >> >> +static struct bfd_sym_chain export_dynamic_symbol_list = { NULL, NULL };

>> >> >> >> >> >> >> >> +

>> >> >> >> >> >> >> >> +void

>> >> >> >> >> >> >> >> +ldlang_add_export_dynamic_symbol (const char *const name)

>> >> >> >> >> >> >> >> +{

>> >> >> >> >> >> >> >> +  struct bfd_sym_chain *sym;

>> >> >> >> >> >> >> >> +  sym = stat_alloc (sizeof (*sym));

>> >> >> >> >> >> >> >> +  sym->name = xstrdup (name);

>> >> >> >> >> >> >> >> +  sym->next = export_dynamic_symbol_list.next;

>> >> >> >> >> >> >> >> +  export_dynamic_symbol_list.next = sym;

>> >> >> >> >> >> >> >> +}

>> >> >> >> >> >> >> >> +

>> >> >> >> >> >> >> >> +static void

>> >> >> >> >> >> >> >> +lang_place_export_dynamic_symbols (void)

>> >> >> >> >> >> >> >> +{

>> >> >> >> >> >> >> >> +  struct bfd_sym_chain *sym;

>> >> >> >> >> >> >> >> +  for (sym = export_dynamic_symbol_list.next; sym != NULL; sym = sym->next)

>> >> >> >> >> >> >> >> +    insert_undefined (sym->name);

>> >> >> >> >> >> >> >> +}

>> >> >> >> >> >> >> >> +

>> >> >> >> >> >> >> >>  /* Structure used to build the list of symbols that the user has required

>> >> >> >> >> >> >> >>     be defined.  */

>> >> >> >> >> >> >> >>

>> >> >> >> >> >> >> >> @@ -7795,6 +7815,10 @@ void

>> >> >> >> >> >> >> >>  lang_process (void)

>> >> >> >> >> >> >> >>  {

>> >> >> >> >> >> >> >>    /* Finalize dynamic list.  */

>> >> >> >> >> >> >> >> +  struct bfd_sym_chain *sym;

>> >> >> >> >> >> >> >> +  for (sym = export_dynamic_symbol_list.next; sym != NULL; sym = sym->next)

>> >> >> >> >> >> >> >> +    lang_append_dynamic_list (

>> >> >> >> >> >> >> >> +        lang_new_vers_pattern (NULL, sym->name, NULL, FALSE));

>> >> >> >> >> >> >> >>    if (link_info.dynamic_list)

>> >> >> >> >> >> >> >>      lang_finalize_version_expr_head (&link_info.dynamic_list->head);

>> >> >> >> >> >> >> >>

>> >> >> >> >> >> >> >> @@ -7808,6 +7832,8 @@ lang_process (void)

>> >> >> >> >> >> >> >>

>> >> >> >> >> >> >> >>    /* Add to the hash table all undefineds on the command line.  */

>> >> >> >> >> >> >> >>    lang_place_undefineds ();

>> >> >> >> >> >> >> >> +  /* Add --export-dynamic-symbol symbols to the hash table.  */

>> >> >> >> >> >> >> >> +  lang_place_export_dynamic_symbols ();

>> >> >> >> >> >> >> >>

>> >> >> >> >> >> >> >>    if (!bfd_section_already_linked_table_init ())

>> >> >> >> >> >> >> >>      einfo (_("%F%P: can not create hash table: %E\n"));

>> >> >> >> >> >> >> >> diff --git a/ld/ldlang.h b/ld/ldlang.h

>> >> >> >> >> >> >> >> index 2aa3930f95..8c004b173c 100644

>> >> >> >> >> >> >> >> --- a/ld/ldlang.h

>> >> >> >> >> >> >> >> +++ b/ld/ldlang.h

>> >> >> >> >> >> >> >> @@ -606,6 +606,8 @@ extern lang_output_section_statement_type *next_matching_output_section_statemen

>> >> >> >> >> >> >> >>    (lang_output_section_statement_type *, int);

>> >> >> >> >> >> >> >>  extern void ldlang_add_undef

>> >> >> >> >> >> >> >>    (const char *const, bfd_boolean);

>> >> >> >> >> >> >> >> +extern void ldlang_add_export_dynamic_symbol

>> >> >> >> >> >> >> >> +  (const char *const);

>> >> >> >> >> >> >> >>  extern void ldlang_add_require_defined

>> >> >> >> >> >> >> >>    (const char *const);

>> >> >> >> >> >> >> >>  extern void lang_add_output_format

>> >> >> >> >> >> >> >> diff --git a/ld/ldlex.h b/ld/ldlex.h

>> >> >> >> >> >> >> >> index 22b928d2d9..70f2da5636 100644

>> >> >> >> >> >> >> >> --- a/ld/ldlex.h

>> >> >> >> >> >> >> >> +++ b/ld/ldlex.h

>> >> >> >> >> >> >> >> @@ -81,6 +81,7 @@ enum option_values

>> >> >> >> >> >> >> >>    OPTION_DYNAMIC_LIST_CPP_NEW,

>> >> >> >> >> >> >> >>    OPTION_DYNAMIC_LIST_CPP_TYPEINFO,

>> >> >> >> >> >> >> >>    OPTION_DYNAMIC_LIST_DATA,

>> >> >> >> >> >> >> >> +  OPTION_EXPORT_DYNAMIC_SYMBOL,

>> >> >> >> >> >> >> >>    OPTION_WARN_COMMON,

>> >> >> >> >> >> >> >>    OPTION_WARN_CONSTRUCTORS,

>> >> >> >> >> >> >> >>    OPTION_WARN_FATAL,

>> >> >> >> >> >> >> >> diff --git a/ld/lexsup.c b/ld/lexsup.c

>> >> >> >> >> >> >> >> index d1955b9afa..0a0c2f2873 100644

>> >> >> >> >> >> >> >> --- a/ld/lexsup.c

>> >> >> >> >> >> >> >> +++ b/ld/lexsup.c

>> >> >> >> >> >> >> >> @@ -504,6 +504,8 @@ static const struct ld_option ld_options[] =

>> >> >> >> >> >> >> >>      '\0', NULL, N_("Use C++ typeinfo dynamic list"), TWO_DASHES },

>> >> >> >> >> >> >> >>    { {"dynamic-list", required_argument, NULL, OPTION_DYNAMIC_LIST},

>> >> >> >> >> >> >> >>      '\0', N_("FILE"), N_("Read dynamic list"), TWO_DASHES },

>> >> >> >> >> >> >> >> +  { {"export-dynamic-symbol", required_argument, NULL, OPTION_EXPORT_DYNAMIC_SYMBOL},

>> >> >> >> >> >> >> >> +    '\0', N_("SYMBOL"), N_("Read dynamic list"), TWO_DASHES },

>> >> >> >> >> >> >> >>    { {"warn-common", no_argument, NULL, OPTION_WARN_COMMON},

>> >> >> >> >> >> >> >>      '\0', NULL, N_("Warn about duplicate common symbols"), TWO_DASHES },

>> >> >> >> >> >> >> >>    { {"warn-constructors", no_argument, NULL, OPTION_WARN_CONSTRUCTORS},

>> >> >> >> >> >> >> >> @@ -1425,6 +1427,11 @@ parse_args (unsigned argc, char **argv)

>> >> >> >> >> >> >> >>           if (opt_symbolic == symbolic)

>> >> >> >> >> >> >> >>             opt_symbolic = symbolic_unset;

>> >> >> >> >> >> >> >>           break;

>> >> >> >> >> >> >> >> +       case OPTION_EXPORT_DYNAMIC_SYMBOL:

>> >> >> >> >> >> >> >> +         ldlang_add_export_dynamic_symbol (optarg);

>> >> >> >> >> >> >> >> +         if (opt_dynamic_list != dynamic_list_data)

>> >> >> >> >> >> >> >> +           opt_dynamic_list = dynamic_list;

>> >> >> >> >> >> >> >> +         break;

>> >> >> >> >> >> >> >>         case OPTION_WARN_COMMON:

>> >> >> >> >> >> >> >>           config.warn_common = TRUE;

>> >> >> >> >> >> >> >>           break;

>> >> >> >> >> >> >> >> diff --git a/ld/testsuite/ld-undefined/export-dynamic-symbol-1.d b/ld/testsuite/ld-undefined/export-dynamic-symbol-1.d

>> >> >> >> >> >> >> >> new file mode 100644

>> >> >> >> >> >> >> >> index 0000000000..768bf0abd6

>> >> >> >> >> >> >> >> --- /dev/null

>> >> >> >> >> >> >> >> +++ b/ld/testsuite/ld-undefined/export-dynamic-symbol-1.d

>> >> >> >> >> >> >> >> @@ -0,0 +1,8 @@

>> >> >> >> >> >> >> >> +#name: --export-dynamic-symbol foo archive

>> >> >> >> >> >> >> >> +#source: require-defined.s

>> >> >> >> >> >> >> >> +#ld: -pie --export-dynamic-symbol foo tmpdir/libentry.a

>> >> >> >> >> >> >> >

>> >> >> >> >> >> >> >I assume that it supports

>> >> >> >> >> >> >> >

>> >> >> >> >> >> >> >$ ld -pie --export-dynamic-symbol foo --export-dynamic-symbol bar ...

>> >> >> >> >> >> >> >

>> >> >> >> >> >> >> >Please add another --export-dynamic-symbol to your test.

>> >> >> >> >> >> >> >

>> >> >> >> >> >> >> >--

>> >> >> >> >> >> >> >H.J.

>> >> >> >> >> >> >>

>> >> >> >> >> >> >> I face a test difficulty. If I add another `#nm:`, runtest complains:

>> >> >> >> >> >> >>

>> >> >> >> >> >> >> % cd Debug/ld

>> >> >> >> >> >> >> % runtest --tool ld --srcdir ../../ld/testsuite/ export-dynamic-symbol.exp

>> >> >> >> >> >> >> ...

>> >> >> >> >> >> >> ERROR: option nm multiply set in ../../ld/testsuite/ld-undefined/export-dynamic-symbol-1.d

>> >> >> >> >> >> >>

>> >> >> >> >> >> >> There may also be a problem of symbol table order determinism. I don't

>> >> >> >> >> >> >> know whether another symbol may be ordered before foo in some ports and

>> >> >> >> >> >> >> after foo in other ports.

>> >> >> >> >> >> >>

>> >> >> >> >> >> >> Honestly, I think for a number of tests, even if they test generic

>> >> >> >> >> >> >> behavior, it might be fine to restrict them to run on certain hosts,

>> >> >> >> >> >> >> e.g. Linux x86. What I know about testing is lacking, though, I don't

>> >> >> >> >> >> >> know what can be tested.

>> >> >> >> >> >> >>

>> >> >> >> >> >> >> Ideally `#nm:` should just be free-form shell scripts but unfortunately

>> >> >> >> >> >> >> it seems to support very limited features (undocumented?)

>> >> >> >> >> >> >

>> >> >> >> >> >> >You can't add another #nm.  But you can pass additional options to nm.

>> >> >> >> >> >> >

>> >> >> >> >> >> >--

>> >> >> >> >> >> >H.J.

>> >> >> >> >> >>

>> >> >> >> >> >> Attached PATCH v2.

>> >> >> >> >> >>

>> >> >> >> >> >> Added export-dynamic-symbol-2.d

>> >> >> >> >> >

>> >> >> >> >> >There is

>> >> >> >> >> >

>> >> >> >> >> >'--dynamic-list=DYNAMIC-LIST-FILE'

>> >> >> >> >> >     Specify the name of a dynamic list file to the linker.  This is

>> >> >> >> >> >     typically used when creating shared libraries to specify a list of

>> >> >> >> >> >     global symbols whose references shouldn't be bound to the

>> >> >> >> >> >     definition within the shared library, or creating dynamically

>> >> >> >> >> >     linked executables to specify a list of symbols which should be

>> >> >> >> >> >     added to the symbol table in the executable.  This option is only

>> >> >> >> >> >     meaningful on ELF platforms which support shared libraries.

>> >> >> >> >> >

>> >> >> >> >> >The new --export-dynamic-symbol option puts it on command-line

>> >> >> >> >> >and implicitly adds -u.  This makes the new option different from

>> >> >> >> >> >--dynamic-list.  I don't think -u should be added implicitly.  If needed,

>> >> >> >> >> >you should add another option to add -u for all symbols on dynamic

>> >> >> >> >> >list.

>> >> >> >> >> >

>> >> >> >> >> >--

>> >> >> >> >> >H.J.

>> >> >> >> >>

>> >> >> >> >> I would also hope gold did not add -u. I don't particularly like it (see

>> >> >> >> >> also https://reviews.llvm.org/D43103)

>> >> >> >> >

>> >> >> >> >Please drop implicit -u.

>> >> >> >>

>> >> >> >> Done. Attached PATCH v3.

>> >> >> >> Improved tests to check a glob pattern and multiple --export-dynamic-symbol.

>> >> >> >>

>> >> >> >> Moved ld-undefined/ to ld-dynamic/ since the feature is decoupled from -u now.

>> >> >> >>

>> >> >> >> >> If you think we can correct this, I think it should be fine.

>> >> >> >> >

>> >> >> >> >Please open a gold bug for this.

>> >> >> >> >

>> >> >> >> >Thanks.

>> >> >> >> >

>> >> >> >> >--

>> >> >> >> >H.J.

>> >> >> >>

>> >> >> >> Filed https://sourceware.org/bugzilla/show_bug.cgi?id=25925 (--export-dynamic-symbol should drop implicit -u)

>> >> >> >>

>> >> >> >>

>> >> >> >> I may have to migrate some internal projects if they rely on the

>> >> >> >> --export-dynamic-symbol semantics, but hopefully there will not be much

>> >> >> >> work. I am glad that --export-dynamic-symbol semantic will be orthogonal!

>> >> >> >

>> >> >> >+ case OPTION_EXPORT_DYNAMIC_SYMBOL:

>> >> >> >+   ldlang_add_export_dynamic_symbol (optarg);

>> >> >> >

>> >> >> >Can you simply call

>> >> >> >

>> >> >> >lang_append_dynamic_list (lang_new_vers_pattern (NULL, optarg, NULL, FALSE));

>> >> >> >

>> >> >> >here?

>> >> >> >

>> >> >> >--

>> >> >> >H.J.

>> >> >>

>> >> >> Attached PATCH v4, which also handles -shared.  The previous patches do not handle -shared.

>> >> >> Added two tests to ld-elf/shared.exp

>> >> >>

>> >> >> The updated semantics:

>> >> >>

>> >> >> + @kindex --export-dynamic-symbol=@var{glob}

>> >> >> + @cindex export dynamic symbol

>> >> >> + @item --export-dynamic-symbol=@var{glob}

>> >> >> + When creating a dynamically linked executable, symbols matching

>> >> >> + @var{glob} will be added to the dynamic symbol table. When creating a

>> >> >> + shared library, references to symbols matching @var{glob} will not be

>> >> >> + bound to the definitions within the shared library. This option is a

>> >> >> + no-op when creating a shared library and @samp{--dynamic-list} is not

>> >> >> + specified. This option is only meaningful on ELF platforms which

>> >> >> + support shared libraries.

>> >> >>

>> >> >> i.e. --export-dynamic-symbol is like addition to --dynamic-list,

>> >> >> except: -shared --export-dynamic-symbol without --dynamic-list will not

>> >> >> act as -Bsymbolic.

>> >> >>

>> >> >> In the option processing loop, we cannot call lang_append_dynamic_list

>> >> >> because when -shared is specified but --dynamic-list is not specified,

>> >> >> --export-dynamic-symbol should be a no-op.

>> >> >

>> >> >--dynamic-list implies -Bsymbolic.  If we add --export-dynamic-symbol,

>> >> >we should also add --export-dynamic-symbol-list, which is similar to

>> >> >--dynamic-list, but without -Bsymbolic.

>> >>

>> >> --export-dynamic-symbol-list a.list  where a.list is a plain text like:

>> >> foo

>> >> bar

>> >> ?

>> >

>> >I prefer to use the same format as --dynamic-list.

>> >

>> >> The feature can be provided by a response file @a.rsp

>> >> --export-dynamic-symbol foo

>> >> --export-dynamic-symbol bar

>>

>> Adding --export-dynamic-symbol-list is fine. We can implement that separately.

>

>Since implement --export-dynamic-symbol-list at the same time may impact how

>--export-dynamic-symbol is implemented, they should be added together.


OK. Added --export-dynamic-symbol-list as well.

Retitled.

Comments

On Sun, May 10, 2020 at 11:46 PM Fangrui Song <maskray@google.com> wrote:
>

> On 2020-05-08, H.J. Lu wrote:

> >On Fri, May 8, 2020 at 8:12 AM Fangrui Song <maskray@google.com> wrote:

> >>

> >>

> >> On 2020-05-08, H.J. Lu wrote:

> >> >On Fri, May 8, 2020 at 7:54 AM Fangrui Song <maskray@google.com> wrote:

> >> >>

> >> >> On 2020-05-08, H.J. Lu wrote:

> >> >> >On Wed, May 6, 2020 at 11:42 AM Fangrui Song <maskray@google.com> wrote:

> >> >> >>

> >> >> >> On 2020-05-05, H.J. Lu wrote:

> >> >> >> >On Tue, May 5, 2020 at 9:55 AM Fangrui Song <maskray@google.com> wrote:

> >> >> >> >>

> >> >> >> >>

> >> >> >> >> On 2020-05-05, H.J. Lu wrote:

> >> >> >> >> >On Tue, May 5, 2020 at 8:30 AM Fangrui Song <maskray@google.com> wrote:

> >> >> >> >> >>

> >> >> >> >> >> On 2020-05-05, H.J. Lu wrote:

> >> >> >> >> >> >On Mon, May 4, 2020 at 7:10 PM Fangrui Song <maskray@google.com> wrote:

> >> >> >> >> >> >>

> >> >> >> >> >> >> On 2020-05-04, H.J. Lu wrote:

> >> >> >> >> >> >> >On Mon, May 4, 2020 at 10:48 AM Fangrui Song <maskray@google.com> wrote:

> >> >> >> >> >> >> >>

> >> >> >> >> >> >> >> On 2020-05-03, H.J. Lu wrote:

> >> >> >> >> >> >> >> >On Sat, May 2, 2020 at 11:15 PM Fangrui Song via Binutils

> >> >> >> >> >> >> >> ><binutils@sourceware.org> wrote:

> >> >> >> >> >> >> >> >>

> >> >> >> >> >> >> >> >>         PR ld/25910

> >> >> >> >> >> >> >> >>         * ldlang.c (export_dynamic_symbol_list): New.

> >> >> >> >> >> >> >> >>         (ldlang_add_export_dynamic_symbol): New.

> >> >> >> >> >> >> >> >>         (lang_place_export_dynamic_symbols): New.

> >> >> >> >> >> >> >> >>         (lang_process): Handle export_dynamic_symbol_list.

> >> >> >> >> >> >> >> >>         * ldlang.h (ldlang_add_export_dynamic_symbol): New.

> >> >> >> >> >> >> >> >>         * ldlex.h (option_values): Add OPTION_EXPORT_DYNAMIC_SYMBOL.

> >> >> >> >> >> >> >> >>         * lexsup.c (ld_options): Add entry for OPTION_EXPORT_DYNAMIC_SYMBOL.

> >> >> >> >> >> >> >> >>         (parse_args): Handle it.

> >> >> >> >> >> >> >> >>         * ld.texi: Add --export-dynamic-symbol documentation.

> >> >> >> >> >> >> >> >>         * testsuite/ld-undefined/export-dynamic-symbol.exp: Run new test.

> >> >> >> >> >> >> >> >>         * testsuite/ld-undefined/export-dynamic-symbol-1.d: New.

> >> >> >> >> >> >> >> >> ---

> >> >> >> >> >> >> >> >>  ld/ld.texi                                    |  8 +++++

> >> >> >> >> >> >> >> >>  ld/ldlang.c                                   | 26 ++++++++++++++

> >> >> >> >> >> >> >> >>  ld/ldlang.h                                   |  2 ++

> >> >> >> >> >> >> >> >>  ld/ldlex.h                                    |  1 +

> >> >> >> >> >> >> >> >>  ld/lexsup.c                                   |  7 ++++

> >> >> >> >> >> >> >> >>  .../ld-undefined/export-dynamic-symbol-1.d    |  8 +++++

> >> >> >> >> >> >> >> >>  .../ld-undefined/export-dynamic-symbol.exp    | 35 +++++++++++++++++++

> >> >> >> >> >> >> >> >>  7 files changed, 87 insertions(+)

> >> >> >> >> >> >> >> >>  create mode 100644 ld/testsuite/ld-undefined/export-dynamic-symbol-1.d

> >> >> >> >> >> >> >> >>  create mode 100644 ld/testsuite/ld-undefined/export-dynamic-symbol.exp

> >> >> >> >> >> >> >> >>

> >> >> >> >> >> >> >> >> diff --git a/ld/ld.texi b/ld/ld.texi

> >> >> >> >> >> >> >> >> index 4dc78e65fa..b3dc95f314 100644

> >> >> >> >> >> >> >> >> --- a/ld/ld.texi

> >> >> >> >> >> >> >> >> +++ b/ld/ld.texi

> >> >> >> >> >> >> >> >> @@ -569,6 +569,14 @@ Note that this option is specific to ELF targeted ports.  PE targets

> >> >> >> >> >> >> >> >>  support a similar function to export all symbols from a DLL or EXE; see

> >> >> >> >> >> >> >> >>  the description of @samp{--export-all-symbols} below.

> >> >> >> >> >> >> >> >>

> >> >> >> >> >> >> >> >> +@kindex --export-dynamic-symbol=@var{symbol}

> >> >> >> >> >> >> >> >> +@cindex export dynamic symbol

> >> >> >> >> >> >> >> >> +@item --export-dynamic-symbol=@var{symbol}

> >> >> >> >> >> >> >> >> +Specify a symbol that should be added to the dynamic symbol table.

> >> >> >> >> >> >> >> >> +Additionally, force @var{symbol} to be entered in the output file as an

> >> >> >> >> >> >> >> >> +undefined symbol.  Doing this may, for example, trigger linking of additional

> >> >> >> >> >> >> >> >> +modules from archives.

> >> >> >> >> >> >> >> >> +

> >> >> >> >> >> >> >> >>  @ifclear SingleFormat

> >> >> >> >> >> >> >> >>  @cindex big-endian objects

> >> >> >> >> >> >> >> >>  @cindex endianness

> >> >> >> >> >> >> >> >> diff --git a/ld/ldlang.c b/ld/ldlang.c

> >> >> >> >> >> >> >> >> index b2cdb3603a..e7ecdfeaf0 100644

> >> >> >> >> >> >> >> >> --- a/ld/ldlang.c

> >> >> >> >> >> >> >> >> +++ b/ld/ldlang.c

> >> >> >> >> >> >> >> >> @@ -3910,6 +3910,26 @@ lang_place_undefineds (void)

> >> >> >> >> >> >> >> >>      insert_undefined (ptr->name);

> >> >> >> >> >> >> >> >>  }

> >> >> >> >> >> >> >> >>

> >> >> >> >> >> >> >> >> +static struct bfd_sym_chain export_dynamic_symbol_list = { NULL, NULL };

> >> >> >> >> >> >> >> >> +

> >> >> >> >> >> >> >> >> +void

> >> >> >> >> >> >> >> >> +ldlang_add_export_dynamic_symbol (const char *const name)

> >> >> >> >> >> >> >> >> +{

> >> >> >> >> >> >> >> >> +  struct bfd_sym_chain *sym;

> >> >> >> >> >> >> >> >> +  sym = stat_alloc (sizeof (*sym));

> >> >> >> >> >> >> >> >> +  sym->name = xstrdup (name);

> >> >> >> >> >> >> >> >> +  sym->next = export_dynamic_symbol_list.next;

> >> >> >> >> >> >> >> >> +  export_dynamic_symbol_list.next = sym;

> >> >> >> >> >> >> >> >> +}

> >> >> >> >> >> >> >> >> +

> >> >> >> >> >> >> >> >> +static void

> >> >> >> >> >> >> >> >> +lang_place_export_dynamic_symbols (void)

> >> >> >> >> >> >> >> >> +{

> >> >> >> >> >> >> >> >> +  struct bfd_sym_chain *sym;

> >> >> >> >> >> >> >> >> +  for (sym = export_dynamic_symbol_list.next; sym != NULL; sym = sym->next)

> >> >> >> >> >> >> >> >> +    insert_undefined (sym->name);

> >> >> >> >> >> >> >> >> +}

> >> >> >> >> >> >> >> >> +

> >> >> >> >> >> >> >> >>  /* Structure used to build the list of symbols that the user has required

> >> >> >> >> >> >> >> >>     be defined.  */

> >> >> >> >> >> >> >> >>

> >> >> >> >> >> >> >> >> @@ -7795,6 +7815,10 @@ void

> >> >> >> >> >> >> >> >>  lang_process (void)

> >> >> >> >> >> >> >> >>  {

> >> >> >> >> >> >> >> >>    /* Finalize dynamic list.  */

> >> >> >> >> >> >> >> >> +  struct bfd_sym_chain *sym;

> >> >> >> >> >> >> >> >> +  for (sym = export_dynamic_symbol_list.next; sym != NULL; sym = sym->next)

> >> >> >> >> >> >> >> >> +    lang_append_dynamic_list (

> >> >> >> >> >> >> >> >> +        lang_new_vers_pattern (NULL, sym->name, NULL, FALSE));

> >> >> >> >> >> >> >> >>    if (link_info.dynamic_list)

> >> >> >> >> >> >> >> >>      lang_finalize_version_expr_head (&link_info.dynamic_list->head);

> >> >> >> >> >> >> >> >>

> >> >> >> >> >> >> >> >> @@ -7808,6 +7832,8 @@ lang_process (void)

> >> >> >> >> >> >> >> >>

> >> >> >> >> >> >> >> >>    /* Add to the hash table all undefineds on the command line.  */

> >> >> >> >> >> >> >> >>    lang_place_undefineds ();

> >> >> >> >> >> >> >> >> +  /* Add --export-dynamic-symbol symbols to the hash table.  */

> >> >> >> >> >> >> >> >> +  lang_place_export_dynamic_symbols ();

> >> >> >> >> >> >> >> >>

> >> >> >> >> >> >> >> >>    if (!bfd_section_already_linked_table_init ())

> >> >> >> >> >> >> >> >>      einfo (_("%F%P: can not create hash table: %E\n"));

> >> >> >> >> >> >> >> >> diff --git a/ld/ldlang.h b/ld/ldlang.h

> >> >> >> >> >> >> >> >> index 2aa3930f95..8c004b173c 100644

> >> >> >> >> >> >> >> >> --- a/ld/ldlang.h

> >> >> >> >> >> >> >> >> +++ b/ld/ldlang.h

> >> >> >> >> >> >> >> >> @@ -606,6 +606,8 @@ extern lang_output_section_statement_type *next_matching_output_section_statemen

> >> >> >> >> >> >> >> >>    (lang_output_section_statement_type *, int);

> >> >> >> >> >> >> >> >>  extern void ldlang_add_undef

> >> >> >> >> >> >> >> >>    (const char *const, bfd_boolean);

> >> >> >> >> >> >> >> >> +extern void ldlang_add_export_dynamic_symbol

> >> >> >> >> >> >> >> >> +  (const char *const);

> >> >> >> >> >> >> >> >>  extern void ldlang_add_require_defined

> >> >> >> >> >> >> >> >>    (const char *const);

> >> >> >> >> >> >> >> >>  extern void lang_add_output_format

> >> >> >> >> >> >> >> >> diff --git a/ld/ldlex.h b/ld/ldlex.h

> >> >> >> >> >> >> >> >> index 22b928d2d9..70f2da5636 100644

> >> >> >> >> >> >> >> >> --- a/ld/ldlex.h

> >> >> >> >> >> >> >> >> +++ b/ld/ldlex.h

> >> >> >> >> >> >> >> >> @@ -81,6 +81,7 @@ enum option_values

> >> >> >> >> >> >> >> >>    OPTION_DYNAMIC_LIST_CPP_NEW,

> >> >> >> >> >> >> >> >>    OPTION_DYNAMIC_LIST_CPP_TYPEINFO,

> >> >> >> >> >> >> >> >>    OPTION_DYNAMIC_LIST_DATA,

> >> >> >> >> >> >> >> >> +  OPTION_EXPORT_DYNAMIC_SYMBOL,

> >> >> >> >> >> >> >> >>    OPTION_WARN_COMMON,

> >> >> >> >> >> >> >> >>    OPTION_WARN_CONSTRUCTORS,

> >> >> >> >> >> >> >> >>    OPTION_WARN_FATAL,

> >> >> >> >> >> >> >> >> diff --git a/ld/lexsup.c b/ld/lexsup.c

> >> >> >> >> >> >> >> >> index d1955b9afa..0a0c2f2873 100644

> >> >> >> >> >> >> >> >> --- a/ld/lexsup.c

> >> >> >> >> >> >> >> >> +++ b/ld/lexsup.c

> >> >> >> >> >> >> >> >> @@ -504,6 +504,8 @@ static const struct ld_option ld_options[] =

> >> >> >> >> >> >> >> >>      '\0', NULL, N_("Use C++ typeinfo dynamic list"), TWO_DASHES },

> >> >> >> >> >> >> >> >>    { {"dynamic-list", required_argument, NULL, OPTION_DYNAMIC_LIST},

> >> >> >> >> >> >> >> >>      '\0', N_("FILE"), N_("Read dynamic list"), TWO_DASHES },

> >> >> >> >> >> >> >> >> +  { {"export-dynamic-symbol", required_argument, NULL, OPTION_EXPORT_DYNAMIC_SYMBOL},

> >> >> >> >> >> >> >> >> +    '\0', N_("SYMBOL"), N_("Read dynamic list"), TWO_DASHES },

> >> >> >> >> >> >> >> >>    { {"warn-common", no_argument, NULL, OPTION_WARN_COMMON},

> >> >> >> >> >> >> >> >>      '\0', NULL, N_("Warn about duplicate common symbols"), TWO_DASHES },

> >> >> >> >> >> >> >> >>    { {"warn-constructors", no_argument, NULL, OPTION_WARN_CONSTRUCTORS},

> >> >> >> >> >> >> >> >> @@ -1425,6 +1427,11 @@ parse_args (unsigned argc, char **argv)

> >> >> >> >> >> >> >> >>           if (opt_symbolic == symbolic)

> >> >> >> >> >> >> >> >>             opt_symbolic = symbolic_unset;

> >> >> >> >> >> >> >> >>           break;

> >> >> >> >> >> >> >> >> +       case OPTION_EXPORT_DYNAMIC_SYMBOL:

> >> >> >> >> >> >> >> >> +         ldlang_add_export_dynamic_symbol (optarg);

> >> >> >> >> >> >> >> >> +         if (opt_dynamic_list != dynamic_list_data)

> >> >> >> >> >> >> >> >> +           opt_dynamic_list = dynamic_list;

> >> >> >> >> >> >> >> >> +         break;

> >> >> >> >> >> >> >> >>         case OPTION_WARN_COMMON:

> >> >> >> >> >> >> >> >>           config.warn_common = TRUE;

> >> >> >> >> >> >> >> >>           break;

> >> >> >> >> >> >> >> >> diff --git a/ld/testsuite/ld-undefined/export-dynamic-symbol-1.d b/ld/testsuite/ld-undefined/export-dynamic-symbol-1.d

> >> >> >> >> >> >> >> >> new file mode 100644

> >> >> >> >> >> >> >> >> index 0000000000..768bf0abd6

> >> >> >> >> >> >> >> >> --- /dev/null

> >> >> >> >> >> >> >> >> +++ b/ld/testsuite/ld-undefined/export-dynamic-symbol-1.d

> >> >> >> >> >> >> >> >> @@ -0,0 +1,8 @@

> >> >> >> >> >> >> >> >> +#name: --export-dynamic-symbol foo archive

> >> >> >> >> >> >> >> >> +#source: require-defined.s

> >> >> >> >> >> >> >> >> +#ld: -pie --export-dynamic-symbol foo tmpdir/libentry.a

> >> >> >> >> >> >> >> >

> >> >> >> >> >> >> >> >I assume that it supports

> >> >> >> >> >> >> >> >

> >> >> >> >> >> >> >> >$ ld -pie --export-dynamic-symbol foo --export-dynamic-symbol bar ...

> >> >> >> >> >> >> >> >

> >> >> >> >> >> >> >> >Please add another --export-dynamic-symbol to your test.

> >> >> >> >> >> >> >> >

> >> >> >> >> >> >> >> >--

> >> >> >> >> >> >> >> >H.J.

> >> >> >> >> >> >> >>

> >> >> >> >> >> >> >> I face a test difficulty. If I add another `#nm:`, runtest complains:

> >> >> >> >> >> >> >>

> >> >> >> >> >> >> >> % cd Debug/ld

> >> >> >> >> >> >> >> % runtest --tool ld --srcdir ../../ld/testsuite/ export-dynamic-symbol.exp

> >> >> >> >> >> >> >> ...

> >> >> >> >> >> >> >> ERROR: option nm multiply set in ../../ld/testsuite/ld-undefined/export-dynamic-symbol-1.d

> >> >> >> >> >> >> >>

> >> >> >> >> >> >> >> There may also be a problem of symbol table order determinism. I don't

> >> >> >> >> >> >> >> know whether another symbol may be ordered before foo in some ports and

> >> >> >> >> >> >> >> after foo in other ports.

> >> >> >> >> >> >> >>

> >> >> >> >> >> >> >> Honestly, I think for a number of tests, even if they test generic

> >> >> >> >> >> >> >> behavior, it might be fine to restrict them to run on certain hosts,

> >> >> >> >> >> >> >> e.g. Linux x86. What I know about testing is lacking, though, I don't

> >> >> >> >> >> >> >> know what can be tested.

> >> >> >> >> >> >> >>

> >> >> >> >> >> >> >> Ideally `#nm:` should just be free-form shell scripts but unfortunately

> >> >> >> >> >> >> >> it seems to support very limited features (undocumented?)

> >> >> >> >> >> >> >

> >> >> >> >> >> >> >You can't add another #nm.  But you can pass additional options to nm.

> >> >> >> >> >> >> >

> >> >> >> >> >> >> >--

> >> >> >> >> >> >> >H.J.

> >> >> >> >> >> >>

> >> >> >> >> >> >> Attached PATCH v2.

> >> >> >> >> >> >>

> >> >> >> >> >> >> Added export-dynamic-symbol-2.d

> >> >> >> >> >> >

> >> >> >> >> >> >There is

> >> >> >> >> >> >

> >> >> >> >> >> >'--dynamic-list=DYNAMIC-LIST-FILE'

> >> >> >> >> >> >     Specify the name of a dynamic list file to the linker.  This is

> >> >> >> >> >> >     typically used when creating shared libraries to specify a list of

> >> >> >> >> >> >     global symbols whose references shouldn't be bound to the

> >> >> >> >> >> >     definition within the shared library, or creating dynamically

> >> >> >> >> >> >     linked executables to specify a list of symbols which should be

> >> >> >> >> >> >     added to the symbol table in the executable.  This option is only

> >> >> >> >> >> >     meaningful on ELF platforms which support shared libraries.

> >> >> >> >> >> >

> >> >> >> >> >> >The new --export-dynamic-symbol option puts it on command-line

> >> >> >> >> >> >and implicitly adds -u.  This makes the new option different from

> >> >> >> >> >> >--dynamic-list.  I don't think -u should be added implicitly.  If needed,

> >> >> >> >> >> >you should add another option to add -u for all symbols on dynamic

> >> >> >> >> >> >list.

> >> >> >> >> >> >

> >> >> >> >> >> >--

> >> >> >> >> >> >H.J.

> >> >> >> >> >>

> >> >> >> >> >> I would also hope gold did not add -u. I don't particularly like it (see

> >> >> >> >> >> also https://reviews.llvm.org/D43103)

> >> >> >> >> >

> >> >> >> >> >Please drop implicit -u.

> >> >> >> >>

> >> >> >> >> Done. Attached PATCH v3.

> >> >> >> >> Improved tests to check a glob pattern and multiple --export-dynamic-symbol.

> >> >> >> >>

> >> >> >> >> Moved ld-undefined/ to ld-dynamic/ since the feature is decoupled from -u now.

> >> >> >> >>

> >> >> >> >> >> If you think we can correct this, I think it should be fine.

> >> >> >> >> >

> >> >> >> >> >Please open a gold bug for this.

> >> >> >> >> >

> >> >> >> >> >Thanks.

> >> >> >> >> >

> >> >> >> >> >--

> >> >> >> >> >H.J.

> >> >> >> >>

> >> >> >> >> Filed https://sourceware.org/bugzilla/show_bug.cgi?id=25925 (--export-dynamic-symbol should drop implicit -u)

> >> >> >> >>

> >> >> >> >>

> >> >> >> >> I may have to migrate some internal projects if they rely on the

> >> >> >> >> --export-dynamic-symbol semantics, but hopefully there will not be much

> >> >> >> >> work. I am glad that --export-dynamic-symbol semantic will be orthogonal!

> >> >> >> >

> >> >> >> >+ case OPTION_EXPORT_DYNAMIC_SYMBOL:

> >> >> >> >+   ldlang_add_export_dynamic_symbol (optarg);

> >> >> >> >

> >> >> >> >Can you simply call

> >> >> >> >

> >> >> >> >lang_append_dynamic_list (lang_new_vers_pattern (NULL, optarg, NULL, FALSE));

> >> >> >> >

> >> >> >> >here?

> >> >> >> >

> >> >> >> >--

> >> >> >> >H.J.

> >> >> >>

> >> >> >> Attached PATCH v4, which also handles -shared.  The previous patches do not handle -shared.

> >> >> >> Added two tests to ld-elf/shared.exp

> >> >> >>

> >> >> >> The updated semantics:

> >> >> >>

> >> >> >> + @kindex --export-dynamic-symbol=@var{glob}

> >> >> >> + @cindex export dynamic symbol

> >> >> >> + @item --export-dynamic-symbol=@var{glob}

> >> >> >> + When creating a dynamically linked executable, symbols matching

> >> >> >> + @var{glob} will be added to the dynamic symbol table. When creating a

> >> >> >> + shared library, references to symbols matching @var{glob} will not be

> >> >> >> + bound to the definitions within the shared library. This option is a

> >> >> >> + no-op when creating a shared library and @samp{--dynamic-list} is not

> >> >> >> + specified. This option is only meaningful on ELF platforms which

> >> >> >> + support shared libraries.

> >> >> >>

> >> >> >> i.e. --export-dynamic-symbol is like addition to --dynamic-list,

> >> >> >> except: -shared --export-dynamic-symbol without --dynamic-list will not

> >> >> >> act as -Bsymbolic.

> >> >> >>

> >> >> >> In the option processing loop, we cannot call lang_append_dynamic_list

> >> >> >> because when -shared is specified but --dynamic-list is not specified,

> >> >> >> --export-dynamic-symbol should be a no-op.

> >> >> >

> >> >> >--dynamic-list implies -Bsymbolic.  If we add --export-dynamic-symbol,

> >> >> >we should also add --export-dynamic-symbol-list, which is similar to

> >> >> >--dynamic-list, but without -Bsymbolic.

> >> >>

> >> >> --export-dynamic-symbol-list a.list  where a.list is a plain text like:

> >> >> foo

> >> >> bar

> >> >> ?

> >> >

> >> >I prefer to use the same format as --dynamic-list.

> >> >

> >> >> The feature can be provided by a response file @a.rsp

> >> >> --export-dynamic-symbol foo

> >> >> --export-dynamic-symbol bar

> >>

> >> Adding --export-dynamic-symbol-list is fine. We can implement that separately.

> >

> >Since implement --export-dynamic-symbol-list at the same time may impact how

> >--export-dynamic-symbol is implemented, they should be added together.

>

> OK. Added --export-dynamic-symbol-list as well.

>

> Retitled.


A couple comments:

1. Please add an entry to ld/NEWS.
2. Please a note to ld.texi for the difference between --dynamic-list and
--export-dynamic-symbol.
3.  What happens when there are both --dynamic-list and and
--export-dynamic-symbol, with and without -Bsymbolic?
4.  Can you reuse lang_append_dynamic_list to implement
--export-dynamic-symbol?

-- 
H.J.
On 2020-05-11, H.J. Lu wrote:
>On Sun, May 10, 2020 at 11:46 PM Fangrui Song <maskray@google.com> wrote:

>>

>> On 2020-05-08, H.J. Lu wrote:

>> >On Fri, May 8, 2020 at 8:12 AM Fangrui Song <maskray@google.com> wrote:

>> >>

>> >>

>> >> On 2020-05-08, H.J. Lu wrote:

>> >> >On Fri, May 8, 2020 at 7:54 AM Fangrui Song <maskray@google.com> wrote:

>> >> >>

>> >> >> On 2020-05-08, H.J. Lu wrote:

>> >> >> >On Wed, May 6, 2020 at 11:42 AM Fangrui Song <maskray@google.com> wrote:

>> >> >> >>

>> >> >> >> On 2020-05-05, H.J. Lu wrote:

>> >> >> >> >On Tue, May 5, 2020 at 9:55 AM Fangrui Song <maskray@google.com> wrote:

>> >> >> >> >>

>> >> >> >> >>

>> >> >> >> >> On 2020-05-05, H.J. Lu wrote:

>> >> >> >> >> >On Tue, May 5, 2020 at 8:30 AM Fangrui Song <maskray@google.com> wrote:

>> >> >> >> >> >>

>> >> >> >> >> >> On 2020-05-05, H.J. Lu wrote:

>> >> >> >> >> >> >On Mon, May 4, 2020 at 7:10 PM Fangrui Song <maskray@google.com> wrote:

>> >> >> >> >> >> >>

>> >> >> >> >> >> >> On 2020-05-04, H.J. Lu wrote:

>> >> >> >> >> >> >> >On Mon, May 4, 2020 at 10:48 AM Fangrui Song <maskray@google.com> wrote:

>> >> >> >> >> >> >> >>

>> >> >> >> >> >> >> >> On 2020-05-03, H.J. Lu wrote:

>> >> >> >> >> >> >> >> >On Sat, May 2, 2020 at 11:15 PM Fangrui Song via Binutils

>> >> >> >> >> >> >> >> ><binutils@sourceware.org> wrote:

>> >> >> >> >> >> >> >> >>

>> >> >> >> >> >> >> >> >>         PR ld/25910

>> >> >> >> >> >> >> >> >>         * ldlang.c (export_dynamic_symbol_list): New.

>> >> >> >> >> >> >> >> >>         (ldlang_add_export_dynamic_symbol): New.

>> >> >> >> >> >> >> >> >>         (lang_place_export_dynamic_symbols): New.

>> >> >> >> >> >> >> >> >>         (lang_process): Handle export_dynamic_symbol_list.

>> >> >> >> >> >> >> >> >>         * ldlang.h (ldlang_add_export_dynamic_symbol): New.

>> >> >> >> >> >> >> >> >>         * ldlex.h (option_values): Add OPTION_EXPORT_DYNAMIC_SYMBOL.

>> >> >> >> >> >> >> >> >>         * lexsup.c (ld_options): Add entry for OPTION_EXPORT_DYNAMIC_SYMBOL.

>> >> >> >> >> >> >> >> >>         (parse_args): Handle it.

>> >> >> >> >> >> >> >> >>         * ld.texi: Add --export-dynamic-symbol documentation.

>> >> >> >> >> >> >> >> >>         * testsuite/ld-undefined/export-dynamic-symbol.exp: Run new test.

>> >> >> >> >> >> >> >> >>         * testsuite/ld-undefined/export-dynamic-symbol-1.d: New.

>> >> >> >> >> >> >> >> >> ---

>> >> >> >> >> >> >> >> >>  ld/ld.texi                                    |  8 +++++

>> >> >> >> >> >> >> >> >>  ld/ldlang.c                                   | 26 ++++++++++++++

>> >> >> >> >> >> >> >> >>  ld/ldlang.h                                   |  2 ++

>> >> >> >> >> >> >> >> >>  ld/ldlex.h                                    |  1 +

>> >> >> >> >> >> >> >> >>  ld/lexsup.c                                   |  7 ++++

>> >> >> >> >> >> >> >> >>  .../ld-undefined/export-dynamic-symbol-1.d    |  8 +++++

>> >> >> >> >> >> >> >> >>  .../ld-undefined/export-dynamic-symbol.exp    | 35 +++++++++++++++++++

>> >> >> >> >> >> >> >> >>  7 files changed, 87 insertions(+)

>> >> >> >> >> >> >> >> >>  create mode 100644 ld/testsuite/ld-undefined/export-dynamic-symbol-1.d

>> >> >> >> >> >> >> >> >>  create mode 100644 ld/testsuite/ld-undefined/export-dynamic-symbol.exp

>> >> >> >> >> >> >> >> >>

>> >> >> >> >> >> >> >> >> diff --git a/ld/ld.texi b/ld/ld.texi

>> >> >> >> >> >> >> >> >> index 4dc78e65fa..b3dc95f314 100644

>> >> >> >> >> >> >> >> >> --- a/ld/ld.texi

>> >> >> >> >> >> >> >> >> +++ b/ld/ld.texi

>> >> >> >> >> >> >> >> >> @@ -569,6 +569,14 @@ Note that this option is specific to ELF targeted ports.  PE targets

>> >> >> >> >> >> >> >> >>  support a similar function to export all symbols from a DLL or EXE; see

>> >> >> >> >> >> >> >> >>  the description of @samp{--export-all-symbols} below.

>> >> >> >> >> >> >> >> >>

>> >> >> >> >> >> >> >> >> +@kindex --export-dynamic-symbol=@var{symbol}

>> >> >> >> >> >> >> >> >> +@cindex export dynamic symbol

>> >> >> >> >> >> >> >> >> +@item --export-dynamic-symbol=@var{symbol}

>> >> >> >> >> >> >> >> >> +Specify a symbol that should be added to the dynamic symbol table.

>> >> >> >> >> >> >> >> >> +Additionally, force @var{symbol} to be entered in the output file as an

>> >> >> >> >> >> >> >> >> +undefined symbol.  Doing this may, for example, trigger linking of additional

>> >> >> >> >> >> >> >> >> +modules from archives.

>> >> >> >> >> >> >> >> >> +

>> >> >> >> >> >> >> >> >>  @ifclear SingleFormat

>> >> >> >> >> >> >> >> >>  @cindex big-endian objects

>> >> >> >> >> >> >> >> >>  @cindex endianness

>> >> >> >> >> >> >> >> >> diff --git a/ld/ldlang.c b/ld/ldlang.c

>> >> >> >> >> >> >> >> >> index b2cdb3603a..e7ecdfeaf0 100644

>> >> >> >> >> >> >> >> >> --- a/ld/ldlang.c

>> >> >> >> >> >> >> >> >> +++ b/ld/ldlang.c

>> >> >> >> >> >> >> >> >> @@ -3910,6 +3910,26 @@ lang_place_undefineds (void)

>> >> >> >> >> >> >> >> >>      insert_undefined (ptr->name);

>> >> >> >> >> >> >> >> >>  }

>> >> >> >> >> >> >> >> >>

>> >> >> >> >> >> >> >> >> +static struct bfd_sym_chain export_dynamic_symbol_list = { NULL, NULL };

>> >> >> >> >> >> >> >> >> +

>> >> >> >> >> >> >> >> >> +void

>> >> >> >> >> >> >> >> >> +ldlang_add_export_dynamic_symbol (const char *const name)

>> >> >> >> >> >> >> >> >> +{

>> >> >> >> >> >> >> >> >> +  struct bfd_sym_chain *sym;

>> >> >> >> >> >> >> >> >> +  sym = stat_alloc (sizeof (*sym));

>> >> >> >> >> >> >> >> >> +  sym->name = xstrdup (name);

>> >> >> >> >> >> >> >> >> +  sym->next = export_dynamic_symbol_list.next;

>> >> >> >> >> >> >> >> >> +  export_dynamic_symbol_list.next = sym;

>> >> >> >> >> >> >> >> >> +}

>> >> >> >> >> >> >> >> >> +

>> >> >> >> >> >> >> >> >> +static void

>> >> >> >> >> >> >> >> >> +lang_place_export_dynamic_symbols (void)

>> >> >> >> >> >> >> >> >> +{

>> >> >> >> >> >> >> >> >> +  struct bfd_sym_chain *sym;

>> >> >> >> >> >> >> >> >> +  for (sym = export_dynamic_symbol_list.next; sym != NULL; sym = sym->next)

>> >> >> >> >> >> >> >> >> +    insert_undefined (sym->name);

>> >> >> >> >> >> >> >> >> +}

>> >> >> >> >> >> >> >> >> +

>> >> >> >> >> >> >> >> >>  /* Structure used to build the list of symbols that the user has required

>> >> >> >> >> >> >> >> >>     be defined.  */

>> >> >> >> >> >> >> >> >>

>> >> >> >> >> >> >> >> >> @@ -7795,6 +7815,10 @@ void

>> >> >> >> >> >> >> >> >>  lang_process (void)

>> >> >> >> >> >> >> >> >>  {

>> >> >> >> >> >> >> >> >>    /* Finalize dynamic list.  */

>> >> >> >> >> >> >> >> >> +  struct bfd_sym_chain *sym;

>> >> >> >> >> >> >> >> >> +  for (sym = export_dynamic_symbol_list.next; sym != NULL; sym = sym->next)

>> >> >> >> >> >> >> >> >> +    lang_append_dynamic_list (

>> >> >> >> >> >> >> >> >> +        lang_new_vers_pattern (NULL, sym->name, NULL, FALSE));

>> >> >> >> >> >> >> >> >>    if (link_info.dynamic_list)

>> >> >> >> >> >> >> >> >>      lang_finalize_version_expr_head (&link_info.dynamic_list->head);

>> >> >> >> >> >> >> >> >>

>> >> >> >> >> >> >> >> >> @@ -7808,6 +7832,8 @@ lang_process (void)

>> >> >> >> >> >> >> >> >>

>> >> >> >> >> >> >> >> >>    /* Add to the hash table all undefineds on the command line.  */

>> >> >> >> >> >> >> >> >>    lang_place_undefineds ();

>> >> >> >> >> >> >> >> >> +  /* Add --export-dynamic-symbol symbols to the hash table.  */

>> >> >> >> >> >> >> >> >> +  lang_place_export_dynamic_symbols ();

>> >> >> >> >> >> >> >> >>

>> >> >> >> >> >> >> >> >>    if (!bfd_section_already_linked_table_init ())

>> >> >> >> >> >> >> >> >>      einfo (_("%F%P: can not create hash table: %E\n"));

>> >> >> >> >> >> >> >> >> diff --git a/ld/ldlang.h b/ld/ldlang.h

>> >> >> >> >> >> >> >> >> index 2aa3930f95..8c004b173c 100644

>> >> >> >> >> >> >> >> >> --- a/ld/ldlang.h

>> >> >> >> >> >> >> >> >> +++ b/ld/ldlang.h

>> >> >> >> >> >> >> >> >> @@ -606,6 +606,8 @@ extern lang_output_section_statement_type *next_matching_output_section_statemen

>> >> >> >> >> >> >> >> >>    (lang_output_section_statement_type *, int);

>> >> >> >> >> >> >> >> >>  extern void ldlang_add_undef

>> >> >> >> >> >> >> >> >>    (const char *const, bfd_boolean);

>> >> >> >> >> >> >> >> >> +extern void ldlang_add_export_dynamic_symbol

>> >> >> >> >> >> >> >> >> +  (const char *const);

>> >> >> >> >> >> >> >> >>  extern void ldlang_add_require_defined

>> >> >> >> >> >> >> >> >>    (const char *const);

>> >> >> >> >> >> >> >> >>  extern void lang_add_output_format

>> >> >> >> >> >> >> >> >> diff --git a/ld/ldlex.h b/ld/ldlex.h

>> >> >> >> >> >> >> >> >> index 22b928d2d9..70f2da5636 100644

>> >> >> >> >> >> >> >> >> --- a/ld/ldlex.h

>> >> >> >> >> >> >> >> >> +++ b/ld/ldlex.h

>> >> >> >> >> >> >> >> >> @@ -81,6 +81,7 @@ enum option_values

>> >> >> >> >> >> >> >> >>    OPTION_DYNAMIC_LIST_CPP_NEW,

>> >> >> >> >> >> >> >> >>    OPTION_DYNAMIC_LIST_CPP_TYPEINFO,

>> >> >> >> >> >> >> >> >>    OPTION_DYNAMIC_LIST_DATA,

>> >> >> >> >> >> >> >> >> +  OPTION_EXPORT_DYNAMIC_SYMBOL,

>> >> >> >> >> >> >> >> >>    OPTION_WARN_COMMON,

>> >> >> >> >> >> >> >> >>    OPTION_WARN_CONSTRUCTORS,

>> >> >> >> >> >> >> >> >>    OPTION_WARN_FATAL,

>> >> >> >> >> >> >> >> >> diff --git a/ld/lexsup.c b/ld/lexsup.c

>> >> >> >> >> >> >> >> >> index d1955b9afa..0a0c2f2873 100644

>> >> >> >> >> >> >> >> >> --- a/ld/lexsup.c

>> >> >> >> >> >> >> >> >> +++ b/ld/lexsup.c

>> >> >> >> >> >> >> >> >> @@ -504,6 +504,8 @@ static const struct ld_option ld_options[] =

>> >> >> >> >> >> >> >> >>      '\0', NULL, N_("Use C++ typeinfo dynamic list"), TWO_DASHES },

>> >> >> >> >> >> >> >> >>    { {"dynamic-list", required_argument, NULL, OPTION_DYNAMIC_LIST},

>> >> >> >> >> >> >> >> >>      '\0', N_("FILE"), N_("Read dynamic list"), TWO_DASHES },

>> >> >> >> >> >> >> >> >> +  { {"export-dynamic-symbol", required_argument, NULL, OPTION_EXPORT_DYNAMIC_SYMBOL},

>> >> >> >> >> >> >> >> >> +    '\0', N_("SYMBOL"), N_("Read dynamic list"), TWO_DASHES },

>> >> >> >> >> >> >> >> >>    { {"warn-common", no_argument, NULL, OPTION_WARN_COMMON},

>> >> >> >> >> >> >> >> >>      '\0', NULL, N_("Warn about duplicate common symbols"), TWO_DASHES },

>> >> >> >> >> >> >> >> >>    { {"warn-constructors", no_argument, NULL, OPTION_WARN_CONSTRUCTORS},

>> >> >> >> >> >> >> >> >> @@ -1425,6 +1427,11 @@ parse_args (unsigned argc, char **argv)

>> >> >> >> >> >> >> >> >>           if (opt_symbolic == symbolic)

>> >> >> >> >> >> >> >> >>             opt_symbolic = symbolic_unset;

>> >> >> >> >> >> >> >> >>           break;

>> >> >> >> >> >> >> >> >> +       case OPTION_EXPORT_DYNAMIC_SYMBOL:

>> >> >> >> >> >> >> >> >> +         ldlang_add_export_dynamic_symbol (optarg);

>> >> >> >> >> >> >> >> >> +         if (opt_dynamic_list != dynamic_list_data)

>> >> >> >> >> >> >> >> >> +           opt_dynamic_list = dynamic_list;

>> >> >> >> >> >> >> >> >> +         break;

>> >> >> >> >> >> >> >> >>         case OPTION_WARN_COMMON:

>> >> >> >> >> >> >> >> >>           config.warn_common = TRUE;

>> >> >> >> >> >> >> >> >>           break;

>> >> >> >> >> >> >> >> >> diff --git a/ld/testsuite/ld-undefined/export-dynamic-symbol-1.d b/ld/testsuite/ld-undefined/export-dynamic-symbol-1.d

>> >> >> >> >> >> >> >> >> new file mode 100644

>> >> >> >> >> >> >> >> >> index 0000000000..768bf0abd6

>> >> >> >> >> >> >> >> >> --- /dev/null

>> >> >> >> >> >> >> >> >> +++ b/ld/testsuite/ld-undefined/export-dynamic-symbol-1.d

>> >> >> >> >> >> >> >> >> @@ -0,0 +1,8 @@

>> >> >> >> >> >> >> >> >> +#name: --export-dynamic-symbol foo archive

>> >> >> >> >> >> >> >> >> +#source: require-defined.s

>> >> >> >> >> >> >> >> >> +#ld: -pie --export-dynamic-symbol foo tmpdir/libentry.a

>> >> >> >> >> >> >> >> >

>> >> >> >> >> >> >> >> >I assume that it supports

>> >> >> >> >> >> >> >> >

>> >> >> >> >> >> >> >> >$ ld -pie --export-dynamic-symbol foo --export-dynamic-symbol bar ...

>> >> >> >> >> >> >> >> >

>> >> >> >> >> >> >> >> >Please add another --export-dynamic-symbol to your test.

>> >> >> >> >> >> >> >> >

>> >> >> >> >> >> >> >> >--

>> >> >> >> >> >> >> >> >H.J.

>> >> >> >> >> >> >> >>

>> >> >> >> >> >> >> >> I face a test difficulty. If I add another `#nm:`, runtest complains:

>> >> >> >> >> >> >> >>

>> >> >> >> >> >> >> >> % cd Debug/ld

>> >> >> >> >> >> >> >> % runtest --tool ld --srcdir ../../ld/testsuite/ export-dynamic-symbol.exp

>> >> >> >> >> >> >> >> ...

>> >> >> >> >> >> >> >> ERROR: option nm multiply set in ../../ld/testsuite/ld-undefined/export-dynamic-symbol-1.d

>> >> >> >> >> >> >> >>

>> >> >> >> >> >> >> >> There may also be a problem of symbol table order determinism. I don't

>> >> >> >> >> >> >> >> know whether another symbol may be ordered before foo in some ports and

>> >> >> >> >> >> >> >> after foo in other ports.

>> >> >> >> >> >> >> >>

>> >> >> >> >> >> >> >> Honestly, I think for a number of tests, even if they test generic

>> >> >> >> >> >> >> >> behavior, it might be fine to restrict them to run on certain hosts,

>> >> >> >> >> >> >> >> e.g. Linux x86. What I know about testing is lacking, though, I don't

>> >> >> >> >> >> >> >> know what can be tested.

>> >> >> >> >> >> >> >>

>> >> >> >> >> >> >> >> Ideally `#nm:` should just be free-form shell scripts but unfortunately

>> >> >> >> >> >> >> >> it seems to support very limited features (undocumented?)

>> >> >> >> >> >> >> >

>> >> >> >> >> >> >> >You can't add another #nm.  But you can pass additional options to nm.

>> >> >> >> >> >> >> >

>> >> >> >> >> >> >> >--

>> >> >> >> >> >> >> >H.J.

>> >> >> >> >> >> >>

>> >> >> >> >> >> >> Attached PATCH v2.

>> >> >> >> >> >> >>

>> >> >> >> >> >> >> Added export-dynamic-symbol-2.d

>> >> >> >> >> >> >

>> >> >> >> >> >> >There is

>> >> >> >> >> >> >

>> >> >> >> >> >> >'--dynamic-list=DYNAMIC-LIST-FILE'

>> >> >> >> >> >> >     Specify the name of a dynamic list file to the linker.  This is

>> >> >> >> >> >> >     typically used when creating shared libraries to specify a list of

>> >> >> >> >> >> >     global symbols whose references shouldn't be bound to the

>> >> >> >> >> >> >     definition within the shared library, or creating dynamically

>> >> >> >> >> >> >     linked executables to specify a list of symbols which should be

>> >> >> >> >> >> >     added to the symbol table in the executable.  This option is only

>> >> >> >> >> >> >     meaningful on ELF platforms which support shared libraries.

>> >> >> >> >> >> >

>> >> >> >> >> >> >The new --export-dynamic-symbol option puts it on command-line

>> >> >> >> >> >> >and implicitly adds -u.  This makes the new option different from

>> >> >> >> >> >> >--dynamic-list.  I don't think -u should be added implicitly.  If needed,

>> >> >> >> >> >> >you should add another option to add -u for all symbols on dynamic

>> >> >> >> >> >> >list.

>> >> >> >> >> >> >

>> >> >> >> >> >> >--

>> >> >> >> >> >> >H.J.

>> >> >> >> >> >>

>> >> >> >> >> >> I would also hope gold did not add -u. I don't particularly like it (see

>> >> >> >> >> >> also https://reviews.llvm.org/D43103)

>> >> >> >> >> >

>> >> >> >> >> >Please drop implicit -u.

>> >> >> >> >>

>> >> >> >> >> Done. Attached PATCH v3.

>> >> >> >> >> Improved tests to check a glob pattern and multiple --export-dynamic-symbol.

>> >> >> >> >>

>> >> >> >> >> Moved ld-undefined/ to ld-dynamic/ since the feature is decoupled from -u now.

>> >> >> >> >>

>> >> >> >> >> >> If you think we can correct this, I think it should be fine.

>> >> >> >> >> >

>> >> >> >> >> >Please open a gold bug for this.

>> >> >> >> >> >

>> >> >> >> >> >Thanks.

>> >> >> >> >> >

>> >> >> >> >> >--

>> >> >> >> >> >H.J.

>> >> >> >> >>

>> >> >> >> >> Filed https://sourceware.org/bugzilla/show_bug.cgi?id=25925 (--export-dynamic-symbol should drop implicit -u)

>> >> >> >> >>

>> >> >> >> >>

>> >> >> >> >> I may have to migrate some internal projects if they rely on the

>> >> >> >> >> --export-dynamic-symbol semantics, but hopefully there will not be much

>> >> >> >> >> work. I am glad that --export-dynamic-symbol semantic will be orthogonal!

>> >> >> >> >

>> >> >> >> >+ case OPTION_EXPORT_DYNAMIC_SYMBOL:

>> >> >> >> >+   ldlang_add_export_dynamic_symbol (optarg);

>> >> >> >> >

>> >> >> >> >Can you simply call

>> >> >> >> >

>> >> >> >> >lang_append_dynamic_list (lang_new_vers_pattern (NULL, optarg, NULL, FALSE));

>> >> >> >> >

>> >> >> >> >here?

>> >> >> >> >

>> >> >> >> >--

>> >> >> >> >H.J.

>> >> >> >>

>> >> >> >> Attached PATCH v4, which also handles -shared.  The previous patches do not handle -shared.

>> >> >> >> Added two tests to ld-elf/shared.exp

>> >> >> >>

>> >> >> >> The updated semantics:

>> >> >> >>

>> >> >> >> + @kindex --export-dynamic-symbol=@var{glob}

>> >> >> >> + @cindex export dynamic symbol

>> >> >> >> + @item --export-dynamic-symbol=@var{glob}

>> >> >> >> + When creating a dynamically linked executable, symbols matching

>> >> >> >> + @var{glob} will be added to the dynamic symbol table. When creating a

>> >> >> >> + shared library, references to symbols matching @var{glob} will not be

>> >> >> >> + bound to the definitions within the shared library. This option is a

>> >> >> >> + no-op when creating a shared library and @samp{--dynamic-list} is not

>> >> >> >> + specified. This option is only meaningful on ELF platforms which

>> >> >> >> + support shared libraries.

>> >> >> >>

>> >> >> >> i.e. --export-dynamic-symbol is like addition to --dynamic-list,

>> >> >> >> except: -shared --export-dynamic-symbol without --dynamic-list will not

>> >> >> >> act as -Bsymbolic.

>> >> >> >>

>> >> >> >> In the option processing loop, we cannot call lang_append_dynamic_list

>> >> >> >> because when -shared is specified but --dynamic-list is not specified,

>> >> >> >> --export-dynamic-symbol should be a no-op.

>> >> >> >

>> >> >> >--dynamic-list implies -Bsymbolic.  If we add --export-dynamic-symbol,

>> >> >> >we should also add --export-dynamic-symbol-list, which is similar to

>> >> >> >--dynamic-list, but without -Bsymbolic.

>> >> >>

>> >> >> --export-dynamic-symbol-list a.list  where a.list is a plain text like:

>> >> >> foo

>> >> >> bar

>> >> >> ?

>> >> >

>> >> >I prefer to use the same format as --dynamic-list.

>> >> >

>> >> >> The feature can be provided by a response file @a.rsp

>> >> >> --export-dynamic-symbol foo

>> >> >> --export-dynamic-symbol bar

>> >>

>> >> Adding --export-dynamic-symbol-list is fine. We can implement that separately.

>> >

>> >Since implement --export-dynamic-symbol-list at the same time may impact how

>> >--export-dynamic-symbol is implemented, they should be added together.

>>

>> OK. Added --export-dynamic-symbol-list as well.

>>

>> Retitled.

>

>A couple comments:


Thanks for the review!

>1. Please add an entry to ld/NEWS.

>2. Please a note to ld.texi for the difference between --dynamic-list and

>--export-dynamic-symbol.


>3.  What happens when there are both --dynamic-list and and

>--export-dynamic-symbol, with and without -Bsymbolic?


--export-symbol-symbol adds additional entries to --dynamic-list.


I'd expect --dynamic-list to override -Bsymbolic (i.e. --dynamic-list is a
refined -Bsymbolic).
gold and
LLD (https://github.com/llvm/llvm-project/blob/master/lld/ELF/Symbols.cpp#L368)
behave this way.
GNU ld seems to make every symbol symbolic.

This can be tested with:

.globl main, foo, bar
main: call foo
foo: call bar
bar: ret

// a.list
{ foo; };

It is also fine if you think -Bsymbolic should override --dynamic-list.
(Please add a test for that so that I know how to test --export-dynamic-list)
We can then file a gold bug.

>4.  Can you reuse lang_append_dynamic_list to implement

>--export-dynamic-symbol?


This is difficult. It seems that another global variable needs to be introduced.
yacc code duplication may not be that bad compared with the alternative.
On Tue, May 12, 2020 at 9:38 PM Fangrui Song <maskray@google.com> wrote:
>

> On 2020-05-11, H.J. Lu wrote:

> >On Sun, May 10, 2020 at 11:46 PM Fangrui Song <maskray@google.com> wrote:

> >>

> >> On 2020-05-08, H.J. Lu wrote:

> >> >On Fri, May 8, 2020 at 8:12 AM Fangrui Song <maskray@google.com> wrote:

> >> >>

> >> >>

> >> >> On 2020-05-08, H.J. Lu wrote:

> >> >> >On Fri, May 8, 2020 at 7:54 AM Fangrui Song <maskray@google.com> wrote:

> >> >> >>

> >> >> >> On 2020-05-08, H.J. Lu wrote:

> >> >> >> >On Wed, May 6, 2020 at 11:42 AM Fangrui Song <maskray@google.com> wrote:

> >> >> >> >>

> >> >> >> >> On 2020-05-05, H.J. Lu wrote:

> >> >> >> >> >On Tue, May 5, 2020 at 9:55 AM Fangrui Song <maskray@google.com> wrote:

> >> >> >> >> >>

> >> >> >> >> >>

> >> >> >> >> >> On 2020-05-05, H.J. Lu wrote:

> >> >> >> >> >> >On Tue, May 5, 2020 at 8:30 AM Fangrui Song <maskray@google.com> wrote:

> >> >> >> >> >> >>

> >> >> >> >> >> >> On 2020-05-05, H.J. Lu wrote:

> >> >> >> >> >> >> >On Mon, May 4, 2020 at 7:10 PM Fangrui Song <maskray@google.com> wrote:

> >> >> >> >> >> >> >>

> >> >> >> >> >> >> >> On 2020-05-04, H.J. Lu wrote:

> >> >> >> >> >> >> >> >On Mon, May 4, 2020 at 10:48 AM Fangrui Song <maskray@google.com> wrote:

> >> >> >> >> >> >> >> >>

> >> >> >> >> >> >> >> >> On 2020-05-03, H.J. Lu wrote:

> >> >> >> >> >> >> >> >> >On Sat, May 2, 2020 at 11:15 PM Fangrui Song via Binutils

> >> >> >> >> >> >> >> >> ><binutils@sourceware.org> wrote:

> >> >> >> >> >> >> >> >> >>

> >> >> >> >> >> >> >> >> >>         PR ld/25910

> >> >> >> >> >> >> >> >> >>         * ldlang.c (export_dynamic_symbol_list): New.

> >> >> >> >> >> >> >> >> >>         (ldlang_add_export_dynamic_symbol): New.

> >> >> >> >> >> >> >> >> >>         (lang_place_export_dynamic_symbols): New.

> >> >> >> >> >> >> >> >> >>         (lang_process): Handle export_dynamic_symbol_list.

> >> >> >> >> >> >> >> >> >>         * ldlang.h (ldlang_add_export_dynamic_symbol): New.

> >> >> >> >> >> >> >> >> >>         * ldlex.h (option_values): Add OPTION_EXPORT_DYNAMIC_SYMBOL.

> >> >> >> >> >> >> >> >> >>         * lexsup.c (ld_options): Add entry for OPTION_EXPORT_DYNAMIC_SYMBOL.

> >> >> >> >> >> >> >> >> >>         (parse_args): Handle it.

> >> >> >> >> >> >> >> >> >>         * ld.texi: Add --export-dynamic-symbol documentation.

> >> >> >> >> >> >> >> >> >>         * testsuite/ld-undefined/export-dynamic-symbol.exp: Run new test.

> >> >> >> >> >> >> >> >> >>         * testsuite/ld-undefined/export-dynamic-symbol-1.d: New.

> >> >> >> >> >> >> >> >> >> ---

> >> >> >> >> >> >> >> >> >>  ld/ld.texi                                    |  8 +++++

> >> >> >> >> >> >> >> >> >>  ld/ldlang.c                                   | 26 ++++++++++++++

> >> >> >> >> >> >> >> >> >>  ld/ldlang.h                                   |  2 ++

> >> >> >> >> >> >> >> >> >>  ld/ldlex.h                                    |  1 +

> >> >> >> >> >> >> >> >> >>  ld/lexsup.c                                   |  7 ++++

> >> >> >> >> >> >> >> >> >>  .../ld-undefined/export-dynamic-symbol-1.d    |  8 +++++

> >> >> >> >> >> >> >> >> >>  .../ld-undefined/export-dynamic-symbol.exp    | 35 +++++++++++++++++++

> >> >> >> >> >> >> >> >> >>  7 files changed, 87 insertions(+)

> >> >> >> >> >> >> >> >> >>  create mode 100644 ld/testsuite/ld-undefined/export-dynamic-symbol-1.d

> >> >> >> >> >> >> >> >> >>  create mode 100644 ld/testsuite/ld-undefined/export-dynamic-symbol.exp

> >> >> >> >> >> >> >> >> >>

> >> >> >> >> >> >> >> >> >> diff --git a/ld/ld.texi b/ld/ld.texi

> >> >> >> >> >> >> >> >> >> index 4dc78e65fa..b3dc95f314 100644

> >> >> >> >> >> >> >> >> >> --- a/ld/ld.texi

> >> >> >> >> >> >> >> >> >> +++ b/ld/ld.texi

> >> >> >> >> >> >> >> >> >> @@ -569,6 +569,14 @@ Note that this option is specific to ELF targeted ports.  PE targets

> >> >> >> >> >> >> >> >> >>  support a similar function to export all symbols from a DLL or EXE; see

> >> >> >> >> >> >> >> >> >>  the description of @samp{--export-all-symbols} below.

> >> >> >> >> >> >> >> >> >>

> >> >> >> >> >> >> >> >> >> +@kindex --export-dynamic-symbol=@var{symbol}

> >> >> >> >> >> >> >> >> >> +@cindex export dynamic symbol

> >> >> >> >> >> >> >> >> >> +@item --export-dynamic-symbol=@var{symbol}

> >> >> >> >> >> >> >> >> >> +Specify a symbol that should be added to the dynamic symbol table.

> >> >> >> >> >> >> >> >> >> +Additionally, force @var{symbol} to be entered in the output file as an

> >> >> >> >> >> >> >> >> >> +undefined symbol.  Doing this may, for example, trigger linking of additional

> >> >> >> >> >> >> >> >> >> +modules from archives.

> >> >> >> >> >> >> >> >> >> +

> >> >> >> >> >> >> >> >> >>  @ifclear SingleFormat

> >> >> >> >> >> >> >> >> >>  @cindex big-endian objects

> >> >> >> >> >> >> >> >> >>  @cindex endianness

> >> >> >> >> >> >> >> >> >> diff --git a/ld/ldlang.c b/ld/ldlang.c

> >> >> >> >> >> >> >> >> >> index b2cdb3603a..e7ecdfeaf0 100644

> >> >> >> >> >> >> >> >> >> --- a/ld/ldlang.c

> >> >> >> >> >> >> >> >> >> +++ b/ld/ldlang.c

> >> >> >> >> >> >> >> >> >> @@ -3910,6 +3910,26 @@ lang_place_undefineds (void)

> >> >> >> >> >> >> >> >> >>      insert_undefined (ptr->name);

> >> >> >> >> >> >> >> >> >>  }

> >> >> >> >> >> >> >> >> >>

> >> >> >> >> >> >> >> >> >> +static struct bfd_sym_chain export_dynamic_symbol_list = { NULL, NULL };

> >> >> >> >> >> >> >> >> >> +

> >> >> >> >> >> >> >> >> >> +void

> >> >> >> >> >> >> >> >> >> +ldlang_add_export_dynamic_symbol (const char *const name)

> >> >> >> >> >> >> >> >> >> +{

> >> >> >> >> >> >> >> >> >> +  struct bfd_sym_chain *sym;

> >> >> >> >> >> >> >> >> >> +  sym = stat_alloc (sizeof (*sym));

> >> >> >> >> >> >> >> >> >> +  sym->name = xstrdup (name);

> >> >> >> >> >> >> >> >> >> +  sym->next = export_dynamic_symbol_list.next;

> >> >> >> >> >> >> >> >> >> +  export_dynamic_symbol_list.next = sym;

> >> >> >> >> >> >> >> >> >> +}

> >> >> >> >> >> >> >> >> >> +

> >> >> >> >> >> >> >> >> >> +static void

> >> >> >> >> >> >> >> >> >> +lang_place_export_dynamic_symbols (void)

> >> >> >> >> >> >> >> >> >> +{

> >> >> >> >> >> >> >> >> >> +  struct bfd_sym_chain *sym;

> >> >> >> >> >> >> >> >> >> +  for (sym = export_dynamic_symbol_list.next; sym != NULL; sym = sym->next)

> >> >> >> >> >> >> >> >> >> +    insert_undefined (sym->name);

> >> >> >> >> >> >> >> >> >> +}

> >> >> >> >> >> >> >> >> >> +

> >> >> >> >> >> >> >> >> >>  /* Structure used to build the list of symbols that the user has required

> >> >> >> >> >> >> >> >> >>     be defined.  */

> >> >> >> >> >> >> >> >> >>

> >> >> >> >> >> >> >> >> >> @@ -7795,6 +7815,10 @@ void

> >> >> >> >> >> >> >> >> >>  lang_process (void)

> >> >> >> >> >> >> >> >> >>  {

> >> >> >> >> >> >> >> >> >>    /* Finalize dynamic list.  */

> >> >> >> >> >> >> >> >> >> +  struct bfd_sym_chain *sym;

> >> >> >> >> >> >> >> >> >> +  for (sym = export_dynamic_symbol_list.next; sym != NULL; sym = sym->next)

> >> >> >> >> >> >> >> >> >> +    lang_append_dynamic_list (

> >> >> >> >> >> >> >> >> >> +        lang_new_vers_pattern (NULL, sym->name, NULL, FALSE));

> >> >> >> >> >> >> >> >> >>    if (link_info.dynamic_list)

> >> >> >> >> >> >> >> >> >>      lang_finalize_version_expr_head (&link_info.dynamic_list->head);

> >> >> >> >> >> >> >> >> >>

> >> >> >> >> >> >> >> >> >> @@ -7808,6 +7832,8 @@ lang_process (void)

> >> >> >> >> >> >> >> >> >>

> >> >> >> >> >> >> >> >> >>    /* Add to the hash table all undefineds on the command line.  */

> >> >> >> >> >> >> >> >> >>    lang_place_undefineds ();

> >> >> >> >> >> >> >> >> >> +  /* Add --export-dynamic-symbol symbols to the hash table.  */

> >> >> >> >> >> >> >> >> >> +  lang_place_export_dynamic_symbols ();

> >> >> >> >> >> >> >> >> >>

> >> >> >> >> >> >> >> >> >>    if (!bfd_section_already_linked_table_init ())

> >> >> >> >> >> >> >> >> >>      einfo (_("%F%P: can not create hash table: %E\n"));

> >> >> >> >> >> >> >> >> >> diff --git a/ld/ldlang.h b/ld/ldlang.h

> >> >> >> >> >> >> >> >> >> index 2aa3930f95..8c004b173c 100644

> >> >> >> >> >> >> >> >> >> --- a/ld/ldlang.h

> >> >> >> >> >> >> >> >> >> +++ b/ld/ldlang.h

> >> >> >> >> >> >> >> >> >> @@ -606,6 +606,8 @@ extern lang_output_section_statement_type *next_matching_output_section_statemen

> >> >> >> >> >> >> >> >> >>    (lang_output_section_statement_type *, int);

> >> >> >> >> >> >> >> >> >>  extern void ldlang_add_undef

> >> >> >> >> >> >> >> >> >>    (const char *const, bfd_boolean);

> >> >> >> >> >> >> >> >> >> +extern void ldlang_add_export_dynamic_symbol

> >> >> >> >> >> >> >> >> >> +  (const char *const);

> >> >> >> >> >> >> >> >> >>  extern void ldlang_add_require_defined

> >> >> >> >> >> >> >> >> >>    (const char *const);

> >> >> >> >> >> >> >> >> >>  extern void lang_add_output_format

> >> >> >> >> >> >> >> >> >> diff --git a/ld/ldlex.h b/ld/ldlex.h

> >> >> >> >> >> >> >> >> >> index 22b928d2d9..70f2da5636 100644

> >> >> >> >> >> >> >> >> >> --- a/ld/ldlex.h

> >> >> >> >> >> >> >> >> >> +++ b/ld/ldlex.h

> >> >> >> >> >> >> >> >> >> @@ -81,6 +81,7 @@ enum option_values

> >> >> >> >> >> >> >> >> >>    OPTION_DYNAMIC_LIST_CPP_NEW,

> >> >> >> >> >> >> >> >> >>    OPTION_DYNAMIC_LIST_CPP_TYPEINFO,

> >> >> >> >> >> >> >> >> >>    OPTION_DYNAMIC_LIST_DATA,

> >> >> >> >> >> >> >> >> >> +  OPTION_EXPORT_DYNAMIC_SYMBOL,

> >> >> >> >> >> >> >> >> >>    OPTION_WARN_COMMON,

> >> >> >> >> >> >> >> >> >>    OPTION_WARN_CONSTRUCTORS,

> >> >> >> >> >> >> >> >> >>    OPTION_WARN_FATAL,

> >> >> >> >> >> >> >> >> >> diff --git a/ld/lexsup.c b/ld/lexsup.c

> >> >> >> >> >> >> >> >> >> index d1955b9afa..0a0c2f2873 100644

> >> >> >> >> >> >> >> >> >> --- a/ld/lexsup.c

> >> >> >> >> >> >> >> >> >> +++ b/ld/lexsup.c

> >> >> >> >> >> >> >> >> >> @@ -504,6 +504,8 @@ static const struct ld_option ld_options[] =

> >> >> >> >> >> >> >> >> >>      '\0', NULL, N_("Use C++ typeinfo dynamic list"), TWO_DASHES },

> >> >> >> >> >> >> >> >> >>    { {"dynamic-list", required_argument, NULL, OPTION_DYNAMIC_LIST},

> >> >> >> >> >> >> >> >> >>      '\0', N_("FILE"), N_("Read dynamic list"), TWO_DASHES },

> >> >> >> >> >> >> >> >> >> +  { {"export-dynamic-symbol", required_argument, NULL, OPTION_EXPORT_DYNAMIC_SYMBOL},

> >> >> >> >> >> >> >> >> >> +    '\0', N_("SYMBOL"), N_("Read dynamic list"), TWO_DASHES },

> >> >> >> >> >> >> >> >> >>    { {"warn-common", no_argument, NULL, OPTION_WARN_COMMON},

> >> >> >> >> >> >> >> >> >>      '\0', NULL, N_("Warn about duplicate common symbols"), TWO_DASHES },

> >> >> >> >> >> >> >> >> >>    { {"warn-constructors", no_argument, NULL, OPTION_WARN_CONSTRUCTORS},

> >> >> >> >> >> >> >> >> >> @@ -1425,6 +1427,11 @@ parse_args (unsigned argc, char **argv)

> >> >> >> >> >> >> >> >> >>           if (opt_symbolic == symbolic)

> >> >> >> >> >> >> >> >> >>             opt_symbolic = symbolic_unset;

> >> >> >> >> >> >> >> >> >>           break;

> >> >> >> >> >> >> >> >> >> +       case OPTION_EXPORT_DYNAMIC_SYMBOL:

> >> >> >> >> >> >> >> >> >> +         ldlang_add_export_dynamic_symbol (optarg);

> >> >> >> >> >> >> >> >> >> +         if (opt_dynamic_list != dynamic_list_data)

> >> >> >> >> >> >> >> >> >> +           opt_dynamic_list = dynamic_list;

> >> >> >> >> >> >> >> >> >> +         break;

> >> >> >> >> >> >> >> >> >>         case OPTION_WARN_COMMON:

> >> >> >> >> >> >> >> >> >>           config.warn_common = TRUE;

> >> >> >> >> >> >> >> >> >>           break;

> >> >> >> >> >> >> >> >> >> diff --git a/ld/testsuite/ld-undefined/export-dynamic-symbol-1.d b/ld/testsuite/ld-undefined/export-dynamic-symbol-1.d

> >> >> >> >> >> >> >> >> >> new file mode 100644

> >> >> >> >> >> >> >> >> >> index 0000000000..768bf0abd6

> >> >> >> >> >> >> >> >> >> --- /dev/null

> >> >> >> >> >> >> >> >> >> +++ b/ld/testsuite/ld-undefined/export-dynamic-symbol-1.d

> >> >> >> >> >> >> >> >> >> @@ -0,0 +1,8 @@

> >> >> >> >> >> >> >> >> >> +#name: --export-dynamic-symbol foo archive

> >> >> >> >> >> >> >> >> >> +#source: require-defined.s

> >> >> >> >> >> >> >> >> >> +#ld: -pie --export-dynamic-symbol foo tmpdir/libentry.a

> >> >> >> >> >> >> >> >> >

> >> >> >> >> >> >> >> >> >I assume that it supports

> >> >> >> >> >> >> >> >> >

> >> >> >> >> >> >> >> >> >$ ld -pie --export-dynamic-symbol foo --export-dynamic-symbol bar ...

> >> >> >> >> >> >> >> >> >

> >> >> >> >> >> >> >> >> >Please add another --export-dynamic-symbol to your test.

> >> >> >> >> >> >> >> >> >

> >> >> >> >> >> >> >> >> >--

> >> >> >> >> >> >> >> >> >H.J.

> >> >> >> >> >> >> >> >>

> >> >> >> >> >> >> >> >> I face a test difficulty. If I add another `#nm:`, runtest complains:

> >> >> >> >> >> >> >> >>

> >> >> >> >> >> >> >> >> % cd Debug/ld

> >> >> >> >> >> >> >> >> % runtest --tool ld --srcdir ../../ld/testsuite/ export-dynamic-symbol.exp

> >> >> >> >> >> >> >> >> ...

> >> >> >> >> >> >> >> >> ERROR: option nm multiply set in ../../ld/testsuite/ld-undefined/export-dynamic-symbol-1.d

> >> >> >> >> >> >> >> >>

> >> >> >> >> >> >> >> >> There may also be a problem of symbol table order determinism. I don't

> >> >> >> >> >> >> >> >> know whether another symbol may be ordered before foo in some ports and

> >> >> >> >> >> >> >> >> after foo in other ports.

> >> >> >> >> >> >> >> >>

> >> >> >> >> >> >> >> >> Honestly, I think for a number of tests, even if they test generic

> >> >> >> >> >> >> >> >> behavior, it might be fine to restrict them to run on certain hosts,

> >> >> >> >> >> >> >> >> e.g. Linux x86. What I know about testing is lacking, though, I don't

> >> >> >> >> >> >> >> >> know what can be tested.

> >> >> >> >> >> >> >> >>

> >> >> >> >> >> >> >> >> Ideally `#nm:` should just be free-form shell scripts but unfortunately

> >> >> >> >> >> >> >> >> it seems to support very limited features (undocumented?)

> >> >> >> >> >> >> >> >

> >> >> >> >> >> >> >> >You can't add another #nm.  But you can pass additional options to nm.

> >> >> >> >> >> >> >> >

> >> >> >> >> >> >> >> >--

> >> >> >> >> >> >> >> >H.J.

> >> >> >> >> >> >> >>

> >> >> >> >> >> >> >> Attached PATCH v2.

> >> >> >> >> >> >> >>

> >> >> >> >> >> >> >> Added export-dynamic-symbol-2.d

> >> >> >> >> >> >> >

> >> >> >> >> >> >> >There is

> >> >> >> >> >> >> >

> >> >> >> >> >> >> >'--dynamic-list=DYNAMIC-LIST-FILE'

> >> >> >> >> >> >> >     Specify the name of a dynamic list file to the linker.  This is

> >> >> >> >> >> >> >     typically used when creating shared libraries to specify a list of

> >> >> >> >> >> >> >     global symbols whose references shouldn't be bound to the

> >> >> >> >> >> >> >     definition within the shared library, or creating dynamically

> >> >> >> >> >> >> >     linked executables to specify a list of symbols which should be

> >> >> >> >> >> >> >     added to the symbol table in the executable.  This option is only

> >> >> >> >> >> >> >     meaningful on ELF platforms which support shared libraries.

> >> >> >> >> >> >> >

> >> >> >> >> >> >> >The new --export-dynamic-symbol option puts it on command-line

> >> >> >> >> >> >> >and implicitly adds -u.  This makes the new option different from

> >> >> >> >> >> >> >--dynamic-list.  I don't think -u should be added implicitly.  If needed,

> >> >> >> >> >> >> >you should add another option to add -u for all symbols on dynamic

> >> >> >> >> >> >> >list.

> >> >> >> >> >> >> >

> >> >> >> >> >> >> >--

> >> >> >> >> >> >> >H.J.

> >> >> >> >> >> >>

> >> >> >> >> >> >> I would also hope gold did not add -u. I don't particularly like it (see

> >> >> >> >> >> >> also https://reviews.llvm.org/D43103)

> >> >> >> >> >> >

> >> >> >> >> >> >Please drop implicit -u.

> >> >> >> >> >>

> >> >> >> >> >> Done. Attached PATCH v3.

> >> >> >> >> >> Improved tests to check a glob pattern and multiple --export-dynamic-symbol.

> >> >> >> >> >>

> >> >> >> >> >> Moved ld-undefined/ to ld-dynamic/ since the feature is decoupled from -u now.

> >> >> >> >> >>

> >> >> >> >> >> >> If you think we can correct this, I think it should be fine.

> >> >> >> >> >> >

> >> >> >> >> >> >Please open a gold bug for this.

> >> >> >> >> >> >

> >> >> >> >> >> >Thanks.

> >> >> >> >> >> >

> >> >> >> >> >> >--

> >> >> >> >> >> >H.J.

> >> >> >> >> >>

> >> >> >> >> >> Filed https://sourceware.org/bugzilla/show_bug.cgi?id=25925 (--export-dynamic-symbol should drop implicit -u)

> >> >> >> >> >>

> >> >> >> >> >>

> >> >> >> >> >> I may have to migrate some internal projects if they rely on the

> >> >> >> >> >> --export-dynamic-symbol semantics, but hopefully there will not be much

> >> >> >> >> >> work. I am glad that --export-dynamic-symbol semantic will be orthogonal!

> >> >> >> >> >

> >> >> >> >> >+ case OPTION_EXPORT_DYNAMIC_SYMBOL:

> >> >> >> >> >+   ldlang_add_export_dynamic_symbol (optarg);

> >> >> >> >> >

> >> >> >> >> >Can you simply call

> >> >> >> >> >

> >> >> >> >> >lang_append_dynamic_list (lang_new_vers_pattern (NULL, optarg, NULL, FALSE));

> >> >> >> >> >

> >> >> >> >> >here?

> >> >> >> >> >

> >> >> >> >> >--

> >> >> >> >> >H.J.

> >> >> >> >>

> >> >> >> >> Attached PATCH v4, which also handles -shared.  The previous patches do not handle -shared.

> >> >> >> >> Added two tests to ld-elf/shared.exp

> >> >> >> >>

> >> >> >> >> The updated semantics:

> >> >> >> >>

> >> >> >> >> + @kindex --export-dynamic-symbol=@var{glob}

> >> >> >> >> + @cindex export dynamic symbol

> >> >> >> >> + @item --export-dynamic-symbol=@var{glob}

> >> >> >> >> + When creating a dynamically linked executable, symbols matching

> >> >> >> >> + @var{glob} will be added to the dynamic symbol table. When creating a

> >> >> >> >> + shared library, references to symbols matching @var{glob} will not be

> >> >> >> >> + bound to the definitions within the shared library. This option is a

> >> >> >> >> + no-op when creating a shared library and @samp{--dynamic-list} is not

> >> >> >> >> + specified. This option is only meaningful on ELF platforms which

> >> >> >> >> + support shared libraries.

> >> >> >> >>

> >> >> >> >> i.e. --export-dynamic-symbol is like addition to --dynamic-list,

> >> >> >> >> except: -shared --export-dynamic-symbol without --dynamic-list will not

> >> >> >> >> act as -Bsymbolic.

> >> >> >> >>

> >> >> >> >> In the option processing loop, we cannot call lang_append_dynamic_list

> >> >> >> >> because when -shared is specified but --dynamic-list is not specified,

> >> >> >> >> --export-dynamic-symbol should be a no-op.

> >> >> >> >

> >> >> >> >--dynamic-list implies -Bsymbolic.  If we add --export-dynamic-symbol,

> >> >> >> >we should also add --export-dynamic-symbol-list, which is similar to

> >> >> >> >--dynamic-list, but without -Bsymbolic.

> >> >> >>

> >> >> >> --export-dynamic-symbol-list a.list  where a.list is a plain text like:

> >> >> >> foo

> >> >> >> bar

> >> >> >> ?

> >> >> >

> >> >> >I prefer to use the same format as --dynamic-list.

> >> >> >

> >> >> >> The feature can be provided by a response file @a.rsp

> >> >> >> --export-dynamic-symbol foo

> >> >> >> --export-dynamic-symbol bar

> >> >>

> >> >> Adding --export-dynamic-symbol-list is fine. We can implement that separately.

> >> >

> >> >Since implement --export-dynamic-symbol-list at the same time may impact how

> >> >--export-dynamic-symbol is implemented, they should be added together.

> >>

> >> OK. Added --export-dynamic-symbol-list as well.

> >>

> >> Retitled.

> >

> >A couple comments:

>

> Thanks for the review!

>

> >1. Please add an entry to ld/NEWS.

> >2. Please a note to ld.texi for the difference between --dynamic-list and

> >--export-dynamic-symbol.

>

> >3.  What happens when there are both --dynamic-list and and

> >--export-dynamic-symbol, with and without -Bsymbolic?

>

> --export-symbol-symbol adds additional entries to --dynamic-list.


I don't think so.  See below.

>

> I'd expect --dynamic-list to override -Bsymbolic (i.e. --dynamic-list is a

> refined -Bsymbolic).

> gold and

> LLD (https://github.com/llvm/llvm-project/blob/master/lld/ELF/Symbols.cpp#L368)

> behave this way.

> GNU ld seems to make every symbol symbolic.


Ld manual says

'--dynamic-list=DYNAMIC-LIST-FILE'
     Specify the name of a dynamic list file to the linker.  This is
     typically used when creating shared libraries to specify a list of
     global symbols whose references shouldn't be bound to the
     definition within the shared library, or creating dynamically
     linked executables to specify a list of symbols which should be
     added to the symbol table in the executable.  This option is only
     meaningful on ELF platforms which support shared libraries.

     The format of the dynamic list is the same as the version node
     without scope and node name.  See *note VERSION:: for more
     information.

When producing a shared library,  --dynamic-list implies -Bsymbolic
with exception for the symbols on the dynamic list.

> This can be tested with:

>

> .globl main, foo, bar

> main: call foo

> foo: call bar

> bar: ret

>

> // a.list

> { foo; };

>

> It is also fine if you think -Bsymbolic should override --dynamic-list.

> (Please add a test for that so that I know how to test --export-dynamic-list)

> We can then file a gold bug.

>

> >4.  Can you reuse lang_append_dynamic_list to implement

> >--export-dynamic-symbol?

>

> This is difficult. It seems that another global variable needs to be introduced.

> yacc code duplication may not be that bad compared with the alternative.


Since --export-dynamic-symbol is a NOP for -shared and identical with
--dynamic-list otherwise, let's only consider the -shared case:

1. Without -Bsymbolic nor --dynamic-list,  --export-dynamic-symbol should
be dropped.
2. With -Bsymbolic or --dynamic-list, --export-dynamic-symbol should also
be dropped since --export-dynamic-symbol doesn't change symbol binding.

I think we should add a bit field to bfd_elf_version_expr to indicate if symbol
binding should be symbolic (-Bsymbolic) and use lang_append_dynamic_list
for both --dynamic-list and --export-dynamic-symbol.  The only
difference is that
symbols from --export-dynamic-symbol aren't symbolic and can be dropped for
-shared.

-- 
H.J.
On 2020-05-13, H.J. Lu wrote:
>On Tue, May 12, 2020 at 9:38 PM Fangrui Song <maskray@google.com> wrote:

>>

>> On 2020-05-11, H.J. Lu wrote:

>> >On Sun, May 10, 2020 at 11:46 PM Fangrui Song <maskray@google.com> wrote:

>> >>

>> >> On 2020-05-08, H.J. Lu wrote:

>> >> >On Fri, May 8, 2020 at 8:12 AM Fangrui Song <maskray@google.com> wrote:

>> >> >>

>> >> >>

>> >> >> On 2020-05-08, H.J. Lu wrote:

>> >> >> >On Fri, May 8, 2020 at 7:54 AM Fangrui Song <maskray@google.com> wrote:

>> >> >> >>

>> >> >> >> On 2020-05-08, H.J. Lu wrote:

>> >> >> >> >On Wed, May 6, 2020 at 11:42 AM Fangrui Song <maskray@google.com> wrote:

>> >> >> >> >>

>> >> >> >> >> On 2020-05-05, H.J. Lu wrote:

>> >> >> >> >> >On Tue, May 5, 2020 at 9:55 AM Fangrui Song <maskray@google.com> wrote:

>> >> >> >> >> >>

>> >> >> >> >> >>

>> >> >> >> >> >> On 2020-05-05, H.J. Lu wrote:

>> >> >> >> >> >> >On Tue, May 5, 2020 at 8:30 AM Fangrui Song <maskray@google.com> wrote:

>> >> >> >> >> >> >>

>> >> >> >> >> >> >> On 2020-05-05, H.J. Lu wrote:

>> >> >> >> >> >> >> >On Mon, May 4, 2020 at 7:10 PM Fangrui Song <maskray@google.com> wrote:

>> >> >> >> >> >> >> >>

>> >> >> >> >> >> >> >> On 2020-05-04, H.J. Lu wrote:

>> >> >> >> >> >> >> >> >On Mon, May 4, 2020 at 10:48 AM Fangrui Song <maskray@google.com> wrote:

>> >> >> >> >> >> >> >> >>

>> >> >> >> >> >> >> >> >> On 2020-05-03, H.J. Lu wrote:

>> >> >> >> >> >> >> >> >> >On Sat, May 2, 2020 at 11:15 PM Fangrui Song via Binutils

>> >> >> >> >> >> >> >> >> ><binutils@sourceware.org> wrote:

>> >> >> >> >> >> >> >> >> >>

>> >> >> >> >> >> >> >> >> >>         PR ld/25910

>> >> >> >> >> >> >> >> >> >>         * ldlang.c (export_dynamic_symbol_list): New.

>> >> >> >> >> >> >> >> >> >>         (ldlang_add_export_dynamic_symbol): New.

>> >> >> >> >> >> >> >> >> >>         (lang_place_export_dynamic_symbols): New.

>> >> >> >> >> >> >> >> >> >>         (lang_process): Handle export_dynamic_symbol_list.

>> >> >> >> >> >> >> >> >> >>         * ldlang.h (ldlang_add_export_dynamic_symbol): New.

>> >> >> >> >> >> >> >> >> >>         * ldlex.h (option_values): Add OPTION_EXPORT_DYNAMIC_SYMBOL.

>> >> >> >> >> >> >> >> >> >>         * lexsup.c (ld_options): Add entry for OPTION_EXPORT_DYNAMIC_SYMBOL.

>> >> >> >> >> >> >> >> >> >>         (parse_args): Handle it.

>> >> >> >> >> >> >> >> >> >>         * ld.texi: Add --export-dynamic-symbol documentation.

>> >> >> >> >> >> >> >> >> >>         * testsuite/ld-undefined/export-dynamic-symbol.exp: Run new test.

>> >> >> >> >> >> >> >> >> >>         * testsuite/ld-undefined/export-dynamic-symbol-1.d: New.

>> >> >> >> >> >> >> >> >> >> ---

>> >> >> >> >> >> >> >> >> >>  ld/ld.texi                                    |  8 +++++

>> >> >> >> >> >> >> >> >> >>  ld/ldlang.c                                   | 26 ++++++++++++++

>> >> >> >> >> >> >> >> >> >>  ld/ldlang.h                                   |  2 ++

>> >> >> >> >> >> >> >> >> >>  ld/ldlex.h                                    |  1 +

>> >> >> >> >> >> >> >> >> >>  ld/lexsup.c                                   |  7 ++++

>> >> >> >> >> >> >> >> >> >>  .../ld-undefined/export-dynamic-symbol-1.d    |  8 +++++

>> >> >> >> >> >> >> >> >> >>  .../ld-undefined/export-dynamic-symbol.exp    | 35 +++++++++++++++++++

>> >> >> >> >> >> >> >> >> >>  7 files changed, 87 insertions(+)

>> >> >> >> >> >> >> >> >> >>  create mode 100644 ld/testsuite/ld-undefined/export-dynamic-symbol-1.d

>> >> >> >> >> >> >> >> >> >>  create mode 100644 ld/testsuite/ld-undefined/export-dynamic-symbol.exp

>> >> >> >> >> >> >> >> >> >>

>> >> >> >> >> >> >> >> >> >> diff --git a/ld/ld.texi b/ld/ld.texi

>> >> >> >> >> >> >> >> >> >> index 4dc78e65fa..b3dc95f314 100644

>> >> >> >> >> >> >> >> >> >> --- a/ld/ld.texi

>> >> >> >> >> >> >> >> >> >> +++ b/ld/ld.texi

>> >> >> >> >> >> >> >> >> >> @@ -569,6 +569,14 @@ Note that this option is specific to ELF targeted ports.  PE targets

>> >> >> >> >> >> >> >> >> >>  support a similar function to export all symbols from a DLL or EXE; see

>> >> >> >> >> >> >> >> >> >>  the description of @samp{--export-all-symbols} below.

>> >> >> >> >> >> >> >> >> >>

>> >> >> >> >> >> >> >> >> >> +@kindex --export-dynamic-symbol=@var{symbol}

>> >> >> >> >> >> >> >> >> >> +@cindex export dynamic symbol

>> >> >> >> >> >> >> >> >> >> +@item --export-dynamic-symbol=@var{symbol}

>> >> >> >> >> >> >> >> >> >> +Specify a symbol that should be added to the dynamic symbol table.

>> >> >> >> >> >> >> >> >> >> +Additionally, force @var{symbol} to be entered in the output file as an

>> >> >> >> >> >> >> >> >> >> +undefined symbol.  Doing this may, for example, trigger linking of additional

>> >> >> >> >> >> >> >> >> >> +modules from archives.

>> >> >> >> >> >> >> >> >> >> +

>> >> >> >> >> >> >> >> >> >>  @ifclear SingleFormat

>> >> >> >> >> >> >> >> >> >>  @cindex big-endian objects

>> >> >> >> >> >> >> >> >> >>  @cindex endianness

>> >> >> >> >> >> >> >> >> >> diff --git a/ld/ldlang.c b/ld/ldlang.c

>> >> >> >> >> >> >> >> >> >> index b2cdb3603a..e7ecdfeaf0 100644

>> >> >> >> >> >> >> >> >> >> --- a/ld/ldlang.c

>> >> >> >> >> >> >> >> >> >> +++ b/ld/ldlang.c

>> >> >> >> >> >> >> >> >> >> @@ -3910,6 +3910,26 @@ lang_place_undefineds (void)

>> >> >> >> >> >> >> >> >> >>      insert_undefined (ptr->name);

>> >> >> >> >> >> >> >> >> >>  }

>> >> >> >> >> >> >> >> >> >>

>> >> >> >> >> >> >> >> >> >> +static struct bfd_sym_chain export_dynamic_symbol_list = { NULL, NULL };

>> >> >> >> >> >> >> >> >> >> +

>> >> >> >> >> >> >> >> >> >> +void

>> >> >> >> >> >> >> >> >> >> +ldlang_add_export_dynamic_symbol (const char *const name)

>> >> >> >> >> >> >> >> >> >> +{

>> >> >> >> >> >> >> >> >> >> +  struct bfd_sym_chain *sym;

>> >> >> >> >> >> >> >> >> >> +  sym = stat_alloc (sizeof (*sym));

>> >> >> >> >> >> >> >> >> >> +  sym->name = xstrdup (name);

>> >> >> >> >> >> >> >> >> >> +  sym->next = export_dynamic_symbol_list.next;

>> >> >> >> >> >> >> >> >> >> +  export_dynamic_symbol_list.next = sym;

>> >> >> >> >> >> >> >> >> >> +}

>> >> >> >> >> >> >> >> >> >> +

>> >> >> >> >> >> >> >> >> >> +static void

>> >> >> >> >> >> >> >> >> >> +lang_place_export_dynamic_symbols (void)

>> >> >> >> >> >> >> >> >> >> +{

>> >> >> >> >> >> >> >> >> >> +  struct bfd_sym_chain *sym;

>> >> >> >> >> >> >> >> >> >> +  for (sym = export_dynamic_symbol_list.next; sym != NULL; sym = sym->next)

>> >> >> >> >> >> >> >> >> >> +    insert_undefined (sym->name);

>> >> >> >> >> >> >> >> >> >> +}

>> >> >> >> >> >> >> >> >> >> +

>> >> >> >> >> >> >> >> >> >>  /* Structure used to build the list of symbols that the user has required

>> >> >> >> >> >> >> >> >> >>     be defined.  */

>> >> >> >> >> >> >> >> >> >>

>> >> >> >> >> >> >> >> >> >> @@ -7795,6 +7815,10 @@ void

>> >> >> >> >> >> >> >> >> >>  lang_process (void)

>> >> >> >> >> >> >> >> >> >>  {

>> >> >> >> >> >> >> >> >> >>    /* Finalize dynamic list.  */

>> >> >> >> >> >> >> >> >> >> +  struct bfd_sym_chain *sym;

>> >> >> >> >> >> >> >> >> >> +  for (sym = export_dynamic_symbol_list.next; sym != NULL; sym = sym->next)

>> >> >> >> >> >> >> >> >> >> +    lang_append_dynamic_list (

>> >> >> >> >> >> >> >> >> >> +        lang_new_vers_pattern (NULL, sym->name, NULL, FALSE));

>> >> >> >> >> >> >> >> >> >>    if (link_info.dynamic_list)

>> >> >> >> >> >> >> >> >> >>      lang_finalize_version_expr_head (&link_info.dynamic_list->head);

>> >> >> >> >> >> >> >> >> >>

>> >> >> >> >> >> >> >> >> >> @@ -7808,6 +7832,8 @@ lang_process (void)

>> >> >> >> >> >> >> >> >> >>

>> >> >> >> >> >> >> >> >> >>    /* Add to the hash table all undefineds on the command line.  */

>> >> >> >> >> >> >> >> >> >>    lang_place_undefineds ();

>> >> >> >> >> >> >> >> >> >> +  /* Add --export-dynamic-symbol symbols to the hash table.  */

>> >> >> >> >> >> >> >> >> >> +  lang_place_export_dynamic_symbols ();

>> >> >> >> >> >> >> >> >> >>

>> >> >> >> >> >> >> >> >> >>    if (!bfd_section_already_linked_table_init ())

>> >> >> >> >> >> >> >> >> >>      einfo (_("%F%P: can not create hash table: %E\n"));

>> >> >> >> >> >> >> >> >> >> diff --git a/ld/ldlang.h b/ld/ldlang.h

>> >> >> >> >> >> >> >> >> >> index 2aa3930f95..8c004b173c 100644

>> >> >> >> >> >> >> >> >> >> --- a/ld/ldlang.h

>> >> >> >> >> >> >> >> >> >> +++ b/ld/ldlang.h

>> >> >> >> >> >> >> >> >> >> @@ -606,6 +606,8 @@ extern lang_output_section_statement_type *next_matching_output_section_statemen

>> >> >> >> >> >> >> >> >> >>    (lang_output_section_statement_type *, int);

>> >> >> >> >> >> >> >> >> >>  extern void ldlang_add_undef

>> >> >> >> >> >> >> >> >> >>    (const char *const, bfd_boolean);

>> >> >> >> >> >> >> >> >> >> +extern void ldlang_add_export_dynamic_symbol

>> >> >> >> >> >> >> >> >> >> +  (const char *const);

>> >> >> >> >> >> >> >> >> >>  extern void ldlang_add_require_defined

>> >> >> >> >> >> >> >> >> >>    (const char *const);

>> >> >> >> >> >> >> >> >> >>  extern void lang_add_output_format

>> >> >> >> >> >> >> >> >> >> diff --git a/ld/ldlex.h b/ld/ldlex.h

>> >> >> >> >> >> >> >> >> >> index 22b928d2d9..70f2da5636 100644

>> >> >> >> >> >> >> >> >> >> --- a/ld/ldlex.h

>> >> >> >> >> >> >> >> >> >> +++ b/ld/ldlex.h

>> >> >> >> >> >> >> >> >> >> @@ -81,6 +81,7 @@ enum option_values

>> >> >> >> >> >> >> >> >> >>    OPTION_DYNAMIC_LIST_CPP_NEW,

>> >> >> >> >> >> >> >> >> >>    OPTION_DYNAMIC_LIST_CPP_TYPEINFO,

>> >> >> >> >> >> >> >> >> >>    OPTION_DYNAMIC_LIST_DATA,

>> >> >> >> >> >> >> >> >> >> +  OPTION_EXPORT_DYNAMIC_SYMBOL,

>> >> >> >> >> >> >> >> >> >>    OPTION_WARN_COMMON,

>> >> >> >> >> >> >> >> >> >>    OPTION_WARN_CONSTRUCTORS,

>> >> >> >> >> >> >> >> >> >>    OPTION_WARN_FATAL,

>> >> >> >> >> >> >> >> >> >> diff --git a/ld/lexsup.c b/ld/lexsup.c

>> >> >> >> >> >> >> >> >> >> index d1955b9afa..0a0c2f2873 100644

>> >> >> >> >> >> >> >> >> >> --- a/ld/lexsup.c

>> >> >> >> >> >> >> >> >> >> +++ b/ld/lexsup.c

>> >> >> >> >> >> >> >> >> >> @@ -504,6 +504,8 @@ static const struct ld_option ld_options[] =

>> >> >> >> >> >> >> >> >> >>      '\0', NULL, N_("Use C++ typeinfo dynamic list"), TWO_DASHES },

>> >> >> >> >> >> >> >> >> >>    { {"dynamic-list", required_argument, NULL, OPTION_DYNAMIC_LIST},

>> >> >> >> >> >> >> >> >> >>      '\0', N_("FILE"), N_("Read dynamic list"), TWO_DASHES },

>> >> >> >> >> >> >> >> >> >> +  { {"export-dynamic-symbol", required_argument, NULL, OPTION_EXPORT_DYNAMIC_SYMBOL},

>> >> >> >> >> >> >> >> >> >> +    '\0', N_("SYMBOL"), N_("Read dynamic list"), TWO_DASHES },

>> >> >> >> >> >> >> >> >> >>    { {"warn-common", no_argument, NULL, OPTION_WARN_COMMON},

>> >> >> >> >> >> >> >> >> >>      '\0', NULL, N_("Warn about duplicate common symbols"), TWO_DASHES },

>> >> >> >> >> >> >> >> >> >>    { {"warn-constructors", no_argument, NULL, OPTION_WARN_CONSTRUCTORS},

>> >> >> >> >> >> >> >> >> >> @@ -1425,6 +1427,11 @@ parse_args (unsigned argc, char **argv)

>> >> >> >> >> >> >> >> >> >>           if (opt_symbolic == symbolic)

>> >> >> >> >> >> >> >> >> >>             opt_symbolic = symbolic_unset;

>> >> >> >> >> >> >> >> >> >>           break;

>> >> >> >> >> >> >> >> >> >> +       case OPTION_EXPORT_DYNAMIC_SYMBOL:

>> >> >> >> >> >> >> >> >> >> +         ldlang_add_export_dynamic_symbol (optarg);

>> >> >> >> >> >> >> >> >> >> +         if (opt_dynamic_list != dynamic_list_data)

>> >> >> >> >> >> >> >> >> >> +           opt_dynamic_list = dynamic_list;

>> >> >> >> >> >> >> >> >> >> +         break;

>> >> >> >> >> >> >> >> >> >>         case OPTION_WARN_COMMON:

>> >> >> >> >> >> >> >> >> >>           config.warn_common = TRUE;

>> >> >> >> >> >> >> >> >> >>           break;

>> >> >> >> >> >> >> >> >> >> diff --git a/ld/testsuite/ld-undefined/export-dynamic-symbol-1.d b/ld/testsuite/ld-undefined/export-dynamic-symbol-1.d

>> >> >> >> >> >> >> >> >> >> new file mode 100644

>> >> >> >> >> >> >> >> >> >> index 0000000000..768bf0abd6

>> >> >> >> >> >> >> >> >> >> --- /dev/null

>> >> >> >> >> >> >> >> >> >> +++ b/ld/testsuite/ld-undefined/export-dynamic-symbol-1.d

>> >> >> >> >> >> >> >> >> >> @@ -0,0 +1,8 @@

>> >> >> >> >> >> >> >> >> >> +#name: --export-dynamic-symbol foo archive

>> >> >> >> >> >> >> >> >> >> +#source: require-defined.s

>> >> >> >> >> >> >> >> >> >> +#ld: -pie --export-dynamic-symbol foo tmpdir/libentry.a

>> >> >> >> >> >> >> >> >> >

>> >> >> >> >> >> >> >> >> >I assume that it supports

>> >> >> >> >> >> >> >> >> >

>> >> >> >> >> >> >> >> >> >$ ld -pie --export-dynamic-symbol foo --export-dynamic-symbol bar ...

>> >> >> >> >> >> >> >> >> >

>> >> >> >> >> >> >> >> >> >Please add another --export-dynamic-symbol to your test.

>> >> >> >> >> >> >> >> >> >

>> >> >> >> >> >> >> >> >> >--

>> >> >> >> >> >> >> >> >> >H.J.

>> >> >> >> >> >> >> >> >>

>> >> >> >> >> >> >> >> >> I face a test difficulty. If I add another `#nm:`, runtest complains:

>> >> >> >> >> >> >> >> >>

>> >> >> >> >> >> >> >> >> % cd Debug/ld

>> >> >> >> >> >> >> >> >> % runtest --tool ld --srcdir ../../ld/testsuite/ export-dynamic-symbol.exp

>> >> >> >> >> >> >> >> >> ...

>> >> >> >> >> >> >> >> >> ERROR: option nm multiply set in ../../ld/testsuite/ld-undefined/export-dynamic-symbol-1.d

>> >> >> >> >> >> >> >> >>

>> >> >> >> >> >> >> >> >> There may also be a problem of symbol table order determinism. I don't

>> >> >> >> >> >> >> >> >> know whether another symbol may be ordered before foo in some ports and

>> >> >> >> >> >> >> >> >> after foo in other ports.

>> >> >> >> >> >> >> >> >>

>> >> >> >> >> >> >> >> >> Honestly, I think for a number of tests, even if they test generic

>> >> >> >> >> >> >> >> >> behavior, it might be fine to restrict them to run on certain hosts,

>> >> >> >> >> >> >> >> >> e.g. Linux x86. What I know about testing is lacking, though, I don't

>> >> >> >> >> >> >> >> >> know what can be tested.

>> >> >> >> >> >> >> >> >>

>> >> >> >> >> >> >> >> >> Ideally `#nm:` should just be free-form shell scripts but unfortunately

>> >> >> >> >> >> >> >> >> it seems to support very limited features (undocumented?)

>> >> >> >> >> >> >> >> >

>> >> >> >> >> >> >> >> >You can't add another #nm.  But you can pass additional options to nm.

>> >> >> >> >> >> >> >> >

>> >> >> >> >> >> >> >> >--

>> >> >> >> >> >> >> >> >H.J.

>> >> >> >> >> >> >> >>

>> >> >> >> >> >> >> >> Attached PATCH v2.

>> >> >> >> >> >> >> >>

>> >> >> >> >> >> >> >> Added export-dynamic-symbol-2.d

>> >> >> >> >> >> >> >

>> >> >> >> >> >> >> >There is

>> >> >> >> >> >> >> >

>> >> >> >> >> >> >> >'--dynamic-list=DYNAMIC-LIST-FILE'

>> >> >> >> >> >> >> >     Specify the name of a dynamic list file to the linker.  This is

>> >> >> >> >> >> >> >     typically used when creating shared libraries to specify a list of

>> >> >> >> >> >> >> >     global symbols whose references shouldn't be bound to the

>> >> >> >> >> >> >> >     definition within the shared library, or creating dynamically

>> >> >> >> >> >> >> >     linked executables to specify a list of symbols which should be

>> >> >> >> >> >> >> >     added to the symbol table in the executable.  This option is only

>> >> >> >> >> >> >> >     meaningful on ELF platforms which support shared libraries.

>> >> >> >> >> >> >> >

>> >> >> >> >> >> >> >The new --export-dynamic-symbol option puts it on command-line

>> >> >> >> >> >> >> >and implicitly adds -u.  This makes the new option different from

>> >> >> >> >> >> >> >--dynamic-list.  I don't think -u should be added implicitly.  If needed,

>> >> >> >> >> >> >> >you should add another option to add -u for all symbols on dynamic

>> >> >> >> >> >> >> >list.

>> >> >> >> >> >> >> >

>> >> >> >> >> >> >> >--

>> >> >> >> >> >> >> >H.J.

>> >> >> >> >> >> >>

>> >> >> >> >> >> >> I would also hope gold did not add -u. I don't particularly like it (see

>> >> >> >> >> >> >> also https://reviews.llvm.org/D43103)

>> >> >> >> >> >> >

>> >> >> >> >> >> >Please drop implicit -u.

>> >> >> >> >> >>

>> >> >> >> >> >> Done. Attached PATCH v3.

>> >> >> >> >> >> Improved tests to check a glob pattern and multiple --export-dynamic-symbol.

>> >> >> >> >> >>

>> >> >> >> >> >> Moved ld-undefined/ to ld-dynamic/ since the feature is decoupled from -u now.

>> >> >> >> >> >>

>> >> >> >> >> >> >> If you think we can correct this, I think it should be fine.

>> >> >> >> >> >> >

>> >> >> >> >> >> >Please open a gold bug for this.

>> >> >> >> >> >> >

>> >> >> >> >> >> >Thanks.

>> >> >> >> >> >> >

>> >> >> >> >> >> >--

>> >> >> >> >> >> >H.J.

>> >> >> >> >> >>

>> >> >> >> >> >> Filed https://sourceware.org/bugzilla/show_bug.cgi?id=25925 (--export-dynamic-symbol should drop implicit -u)

>> >> >> >> >> >>

>> >> >> >> >> >>

>> >> >> >> >> >> I may have to migrate some internal projects if they rely on the

>> >> >> >> >> >> --export-dynamic-symbol semantics, but hopefully there will not be much

>> >> >> >> >> >> work. I am glad that --export-dynamic-symbol semantic will be orthogonal!

>> >> >> >> >> >

>> >> >> >> >> >+ case OPTION_EXPORT_DYNAMIC_SYMBOL:

>> >> >> >> >> >+   ldlang_add_export_dynamic_symbol (optarg);

>> >> >> >> >> >

>> >> >> >> >> >Can you simply call

>> >> >> >> >> >

>> >> >> >> >> >lang_append_dynamic_list (lang_new_vers_pattern (NULL, optarg, NULL, FALSE));

>> >> >> >> >> >

>> >> >> >> >> >here?

>> >> >> >> >> >

>> >> >> >> >> >--

>> >> >> >> >> >H.J.

>> >> >> >> >>

>> >> >> >> >> Attached PATCH v4, which also handles -shared.  The previous patches do not handle -shared.

>> >> >> >> >> Added two tests to ld-elf/shared.exp

>> >> >> >> >>

>> >> >> >> >> The updated semantics:

>> >> >> >> >>

>> >> >> >> >> + @kindex --export-dynamic-symbol=@var{glob}

>> >> >> >> >> + @cindex export dynamic symbol

>> >> >> >> >> + @item --export-dynamic-symbol=@var{glob}

>> >> >> >> >> + When creating a dynamically linked executable, symbols matching

>> >> >> >> >> + @var{glob} will be added to the dynamic symbol table. When creating a

>> >> >> >> >> + shared library, references to symbols matching @var{glob} will not be

>> >> >> >> >> + bound to the definitions within the shared library. This option is a

>> >> >> >> >> + no-op when creating a shared library and @samp{--dynamic-list} is not

>> >> >> >> >> + specified. This option is only meaningful on ELF platforms which

>> >> >> >> >> + support shared libraries.

>> >> >> >> >>

>> >> >> >> >> i.e. --export-dynamic-symbol is like addition to --dynamic-list,

>> >> >> >> >> except: -shared --export-dynamic-symbol without --dynamic-list will not

>> >> >> >> >> act as -Bsymbolic.

>> >> >> >> >>

>> >> >> >> >> In the option processing loop, we cannot call lang_append_dynamic_list

>> >> >> >> >> because when -shared is specified but --dynamic-list is not specified,

>> >> >> >> >> --export-dynamic-symbol should be a no-op.

>> >> >> >> >

>> >> >> >> >--dynamic-list implies -Bsymbolic.  If we add --export-dynamic-symbol,

>> >> >> >> >we should also add --export-dynamic-symbol-list, which is similar to

>> >> >> >> >--dynamic-list, but without -Bsymbolic.

>> >> >> >>

>> >> >> >> --export-dynamic-symbol-list a.list  where a.list is a plain text like:

>> >> >> >> foo

>> >> >> >> bar

>> >> >> >> ?

>> >> >> >

>> >> >> >I prefer to use the same format as --dynamic-list.

>> >> >> >

>> >> >> >> The feature can be provided by a response file @a.rsp

>> >> >> >> --export-dynamic-symbol foo

>> >> >> >> --export-dynamic-symbol bar

>> >> >>

>> >> >> Adding --export-dynamic-symbol-list is fine. We can implement that separately.

>> >> >

>> >> >Since implement --export-dynamic-symbol-list at the same time may impact how

>> >> >--export-dynamic-symbol is implemented, they should be added together.

>> >>

>> >> OK. Added --export-dynamic-symbol-list as well.

>> >>

>> >> Retitled.

>> >

>> >A couple comments:

>>

>> Thanks for the review!

>>

>> >1. Please add an entry to ld/NEWS.

>> >2. Please a note to ld.texi for the difference between --dynamic-list and

>> >--export-dynamic-symbol.

>>

>> >3.  What happens when there are both --dynamic-list and and

>> >--export-dynamic-symbol, with and without -Bsymbolic?

>>

>> --export-symbol-symbol adds additional entries to --dynamic-list.

>

>I don't think so.  See below.

>

>>

>> I'd expect --dynamic-list to override -Bsymbolic (i.e. --dynamic-list is a

>> refined -Bsymbolic).

>> gold and

>> LLD (https://github.com/llvm/llvm-project/blob/master/lld/ELF/Symbols.cpp#L368)

>> behave this way.

>> GNU ld seems to make every symbol symbolic.

>

>Ld manual says

>

>'--dynamic-list=DYNAMIC-LIST-FILE'

>     Specify the name of a dynamic list file to the linker.  This is

>     typically used when creating shared libraries to specify a list of

>     global symbols whose references shouldn't be bound to the

>     definition within the shared library, or creating dynamically

>     linked executables to specify a list of symbols which should be

>     added to the symbol table in the executable.  This option is only

>     meaningful on ELF platforms which support shared libraries.

>

>     The format of the dynamic list is the same as the version node

>     without scope and node name.  See *note VERSION:: for more

>     information.

>

>When producing a shared library,  --dynamic-list implies -Bsymbolic

>with exception for the symbols on the dynamic list.


This is my understanding. By using `implies`, do you mean -Bsymbolic is
ignored (gold and LLD's interpretation)? If so, GNU ld should be fixed.

I don't think any project is using the combination, so changing the
semantics should not be a problem.

>> This can be tested with:

>>

>> .globl main, foo, bar

>> main: call foo

>> foo: call bar

>> bar: ret

>>

>> // a.list

>> { foo; };

>>

>> It is also fine if you think -Bsymbolic should override --dynamic-list.

>> (Please add a test for that so that I know how to test --export-dynamic-list)

>> We can then file a gold bug.

>>

>> >4.  Can you reuse lang_append_dynamic_list to implement

>> >--export-dynamic-symbol?

>>

>> This is difficult. It seems that another global variable needs to be introduced.

>> yacc code duplication may not be that bad compared with the alternative.

>

>Since --export-dynamic-symbol is a NOP for -shared and identical with

>--dynamic-list otherwise, let's only consider the -shared case:


Combined with both points below, --export-dynamic-symbol can be treated
as a NOP when -shared is specified.  This is acceptable because (as far
as I can tell from my observation) --export-dynamic is a NOP with
-shared.

>1. Without -Bsymbolic nor --dynamic-list,  --export-dynamic-symbol should

>be dropped.


Looks good.

>2. With -Bsymbolic or --dynamic-list, --export-dynamic-symbol should also

>be dropped since --export-dynamic-symbol doesn't change symbol binding.


Is the intention that --export-dynamic-symbol should be similar more to
--export-dynamic and less to --dynamic-list? I'm fine with the change.


If a.list contains { foo; };


# all global symbols are exported. foo is symbolic. --export-dynamic is ignored.
ld.bfd -shared --dynamic-list=a.list --export-dynamic

# all global symbols are exported. foo is symbolic. --export-dynamic-bar is ignored.
ld.bfd -shared --dynamic-list=a.list --export-dynamic-symbol=bar

# all global symbols are exported.
ld.bfd -pie --dynamic-list=a.list --export-dynamic

# foo and bar are exported.
ld.bfd -pie --dynamic-list=a.list --export-dynamic-symbol=bar

>I think we should add a bit field to bfd_elf_version_expr to indicate if symbol

>binding should be symbolic (-Bsymbolic) and use lang_append_dynamic_list

>for both --dynamic-list and --export-dynamic-symbol.  The only

>difference is that

>symbols from --export-dynamic-symbol aren't symbolic and can be dropped for

>-shared.


Like my patch does, we need a separate list for --export-dynamic-symbol.
We cannot call lang_append_dynamic_list yet when processing options,
because it is unknown whether -shared will occur.
On Wed, May 13, 2020 at 8:24 AM Fangrui Song <maskray@google.com> wrote:
>

> On 2020-05-13, H.J. Lu wrote:

> >On Tue, May 12, 2020 at 9:38 PM Fangrui Song <maskray@google.com> wrote:

> >>

> >> On 2020-05-11, H.J. Lu wrote:

> >> >On Sun, May 10, 2020 at 11:46 PM Fangrui Song <maskray@google.com> wrote:

> >> >>

> >> >> On 2020-05-08, H.J. Lu wrote:

> >> >> >On Fri, May 8, 2020 at 8:12 AM Fangrui Song <maskray@google.com> wrote:

> >> >> >>

> >> >> >>

> >> >> >> On 2020-05-08, H.J. Lu wrote:

> >> >> >> >On Fri, May 8, 2020 at 7:54 AM Fangrui Song <maskray@google.com> wrote:

> >> >> >> >>

> >> >> >> >> On 2020-05-08, H.J. Lu wrote:

> >> >> >> >> >On Wed, May 6, 2020 at 11:42 AM Fangrui Song <maskray@google.com> wrote:

> >> >> >> >> >>

> >> >> >> >> >> On 2020-05-05, H.J. Lu wrote:

> >> >> >> >> >> >On Tue, May 5, 2020 at 9:55 AM Fangrui Song <maskray@google.com> wrote:

> >> >> >> >> >> >>

> >> >> >> >> >> >>

> >> >> >> >> >> >> On 2020-05-05, H.J. Lu wrote:

> >> >> >> >> >> >> >On Tue, May 5, 2020 at 8:30 AM Fangrui Song <maskray@google.com> wrote:

> >> >> >> >> >> >> >>

> >> >> >> >> >> >> >> On 2020-05-05, H.J. Lu wrote:

> >> >> >> >> >> >> >> >On Mon, May 4, 2020 at 7:10 PM Fangrui Song <maskray@google.com> wrote:

> >> >> >> >> >> >> >> >>

> >> >> >> >> >> >> >> >> On 2020-05-04, H.J. Lu wrote:

> >> >> >> >> >> >> >> >> >On Mon, May 4, 2020 at 10:48 AM Fangrui Song <maskray@google.com> wrote:

> >> >> >> >> >> >> >> >> >>

> >> >> >> >> >> >> >> >> >> On 2020-05-03, H.J. Lu wrote:

> >> >> >> >> >> >> >> >> >> >On Sat, May 2, 2020 at 11:15 PM Fangrui Song via Binutils

> >> >> >> >> >> >> >> >> >> ><binutils@sourceware.org> wrote:

> >> >> >> >> >> >> >> >> >> >>

> >> >> >> >> >> >> >> >> >> >>         PR ld/25910

> >> >> >> >> >> >> >> >> >> >>         * ldlang.c (export_dynamic_symbol_list): New.

> >> >> >> >> >> >> >> >> >> >>         (ldlang_add_export_dynamic_symbol): New.

> >> >> >> >> >> >> >> >> >> >>         (lang_place_export_dynamic_symbols): New.

> >> >> >> >> >> >> >> >> >> >>         (lang_process): Handle export_dynamic_symbol_list.

> >> >> >> >> >> >> >> >> >> >>         * ldlang.h (ldlang_add_export_dynamic_symbol): New.

> >> >> >> >> >> >> >> >> >> >>         * ldlex.h (option_values): Add OPTION_EXPORT_DYNAMIC_SYMBOL.

> >> >> >> >> >> >> >> >> >> >>         * lexsup.c (ld_options): Add entry for OPTION_EXPORT_DYNAMIC_SYMBOL.

> >> >> >> >> >> >> >> >> >> >>         (parse_args): Handle it.

> >> >> >> >> >> >> >> >> >> >>         * ld.texi: Add --export-dynamic-symbol documentation.

> >> >> >> >> >> >> >> >> >> >>         * testsuite/ld-undefined/export-dynamic-symbol.exp: Run new test.

> >> >> >> >> >> >> >> >> >> >>         * testsuite/ld-undefined/export-dynamic-symbol-1.d: New.

> >> >> >> >> >> >> >> >> >> >> ---

> >> >> >> >> >> >> >> >> >> >>  ld/ld.texi                                    |  8 +++++

> >> >> >> >> >> >> >> >> >> >>  ld/ldlang.c                                   | 26 ++++++++++++++

> >> >> >> >> >> >> >> >> >> >>  ld/ldlang.h                                   |  2 ++

> >> >> >> >> >> >> >> >> >> >>  ld/ldlex.h                                    |  1 +

> >> >> >> >> >> >> >> >> >> >>  ld/lexsup.c                                   |  7 ++++

> >> >> >> >> >> >> >> >> >> >>  .../ld-undefined/export-dynamic-symbol-1.d    |  8 +++++

> >> >> >> >> >> >> >> >> >> >>  .../ld-undefined/export-dynamic-symbol.exp    | 35 +++++++++++++++++++

> >> >> >> >> >> >> >> >> >> >>  7 files changed, 87 insertions(+)

> >> >> >> >> >> >> >> >> >> >>  create mode 100644 ld/testsuite/ld-undefined/export-dynamic-symbol-1.d

> >> >> >> >> >> >> >> >> >> >>  create mode 100644 ld/testsuite/ld-undefined/export-dynamic-symbol.exp

> >> >> >> >> >> >> >> >> >> >>

> >> >> >> >> >> >> >> >> >> >> diff --git a/ld/ld.texi b/ld/ld.texi

> >> >> >> >> >> >> >> >> >> >> index 4dc78e65fa..b3dc95f314 100644

> >> >> >> >> >> >> >> >> >> >> --- a/ld/ld.texi

> >> >> >> >> >> >> >> >> >> >> +++ b/ld/ld.texi

> >> >> >> >> >> >> >> >> >> >> @@ -569,6 +569,14 @@ Note that this option is specific to ELF targeted ports.  PE targets

> >> >> >> >> >> >> >> >> >> >>  support a similar function to export all symbols from a DLL or EXE; see

> >> >> >> >> >> >> >> >> >> >>  the description of @samp{--export-all-symbols} below.

> >> >> >> >> >> >> >> >> >> >>

> >> >> >> >> >> >> >> >> >> >> +@kindex --export-dynamic-symbol=@var{symbol}

> >> >> >> >> >> >> >> >> >> >> +@cindex export dynamic symbol

> >> >> >> >> >> >> >> >> >> >> +@item --export-dynamic-symbol=@var{symbol}

> >> >> >> >> >> >> >> >> >> >> +Specify a symbol that should be added to the dynamic symbol table.

> >> >> >> >> >> >> >> >> >> >> +Additionally, force @var{symbol} to be entered in the output file as an

> >> >> >> >> >> >> >> >> >> >> +undefined symbol.  Doing this may, for example, trigger linking of additional

> >> >> >> >> >> >> >> >> >> >> +modules from archives.

> >> >> >> >> >> >> >> >> >> >> +

> >> >> >> >> >> >> >> >> >> >>  @ifclear SingleFormat

> >> >> >> >> >> >> >> >> >> >>  @cindex big-endian objects

> >> >> >> >> >> >> >> >> >> >>  @cindex endianness

> >> >> >> >> >> >> >> >> >> >> diff --git a/ld/ldlang.c b/ld/ldlang.c

> >> >> >> >> >> >> >> >> >> >> index b2cdb3603a..e7ecdfeaf0 100644

> >> >> >> >> >> >> >> >> >> >> --- a/ld/ldlang.c

> >> >> >> >> >> >> >> >> >> >> +++ b/ld/ldlang.c

> >> >> >> >> >> >> >> >> >> >> @@ -3910,6 +3910,26 @@ lang_place_undefineds (void)

> >> >> >> >> >> >> >> >> >> >>      insert_undefined (ptr->name);

> >> >> >> >> >> >> >> >> >> >>  }

> >> >> >> >> >> >> >> >> >> >>

> >> >> >> >> >> >> >> >> >> >> +static struct bfd_sym_chain export_dynamic_symbol_list = { NULL, NULL };

> >> >> >> >> >> >> >> >> >> >> +

> >> >> >> >> >> >> >> >> >> >> +void

> >> >> >> >> >> >> >> >> >> >> +ldlang_add_export_dynamic_symbol (const char *const name)

> >> >> >> >> >> >> >> >> >> >> +{

> >> >> >> >> >> >> >> >> >> >> +  struct bfd_sym_chain *sym;

> >> >> >> >> >> >> >> >> >> >> +  sym = stat_alloc (sizeof (*sym));

> >> >> >> >> >> >> >> >> >> >> +  sym->name = xstrdup (name);

> >> >> >> >> >> >> >> >> >> >> +  sym->next = export_dynamic_symbol_list.next;

> >> >> >> >> >> >> >> >> >> >> +  export_dynamic_symbol_list.next = sym;

> >> >> >> >> >> >> >> >> >> >> +}

> >> >> >> >> >> >> >> >> >> >> +

> >> >> >> >> >> >> >> >> >> >> +static void

> >> >> >> >> >> >> >> >> >> >> +lang_place_export_dynamic_symbols (void)

> >> >> >> >> >> >> >> >> >> >> +{

> >> >> >> >> >> >> >> >> >> >> +  struct bfd_sym_chain *sym;

> >> >> >> >> >> >> >> >> >> >> +  for (sym = export_dynamic_symbol_list.next; sym != NULL; sym = sym->next)

> >> >> >> >> >> >> >> >> >> >> +    insert_undefined (sym->name);

> >> >> >> >> >> >> >> >> >> >> +}

> >> >> >> >> >> >> >> >> >> >> +

> >> >> >> >> >> >> >> >> >> >>  /* Structure used to build the list of symbols that the user has required

> >> >> >> >> >> >> >> >> >> >>     be defined.  */

> >> >> >> >> >> >> >> >> >> >>

> >> >> >> >> >> >> >> >> >> >> @@ -7795,6 +7815,10 @@ void

> >> >> >> >> >> >> >> >> >> >>  lang_process (void)

> >> >> >> >> >> >> >> >> >> >>  {

> >> >> >> >> >> >> >> >> >> >>    /* Finalize dynamic list.  */

> >> >> >> >> >> >> >> >> >> >> +  struct bfd_sym_chain *sym;

> >> >> >> >> >> >> >> >> >> >> +  for (sym = export_dynamic_symbol_list.next; sym != NULL; sym = sym->next)

> >> >> >> >> >> >> >> >> >> >> +    lang_append_dynamic_list (

> >> >> >> >> >> >> >> >> >> >> +        lang_new_vers_pattern (NULL, sym->name, NULL, FALSE));

> >> >> >> >> >> >> >> >> >> >>    if (link_info.dynamic_list)

> >> >> >> >> >> >> >> >> >> >>      lang_finalize_version_expr_head (&link_info.dynamic_list->head);

> >> >> >> >> >> >> >> >> >> >>

> >> >> >> >> >> >> >> >> >> >> @@ -7808,6 +7832,8 @@ lang_process (void)

> >> >> >> >> >> >> >> >> >> >>

> >> >> >> >> >> >> >> >> >> >>    /* Add to the hash table all undefineds on the command line.  */

> >> >> >> >> >> >> >> >> >> >>    lang_place_undefineds ();

> >> >> >> >> >> >> >> >> >> >> +  /* Add --export-dynamic-symbol symbols to the hash table.  */

> >> >> >> >> >> >> >> >> >> >> +  lang_place_export_dynamic_symbols ();

> >> >> >> >> >> >> >> >> >> >>

> >> >> >> >> >> >> >> >> >> >>    if (!bfd_section_already_linked_table_init ())

> >> >> >> >> >> >> >> >> >> >>      einfo (_("%F%P: can not create hash table: %E\n"));

> >> >> >> >> >> >> >> >> >> >> diff --git a/ld/ldlang.h b/ld/ldlang.h

> >> >> >> >> >> >> >> >> >> >> index 2aa3930f95..8c004b173c 100644

> >> >> >> >> >> >> >> >> >> >> --- a/ld/ldlang.h

> >> >> >> >> >> >> >> >> >> >> +++ b/ld/ldlang.h

> >> >> >> >> >> >> >> >> >> >> @@ -606,6 +606,8 @@ extern lang_output_section_statement_type *next_matching_output_section_statemen

> >> >> >> >> >> >> >> >> >> >>    (lang_output_section_statement_type *, int);

> >> >> >> >> >> >> >> >> >> >>  extern void ldlang_add_undef

> >> >> >> >> >> >> >> >> >> >>    (const char *const, bfd_boolean);

> >> >> >> >> >> >> >> >> >> >> +extern void ldlang_add_export_dynamic_symbol

> >> >> >> >> >> >> >> >> >> >> +  (const char *const);

> >> >> >> >> >> >> >> >> >> >>  extern void ldlang_add_require_defined

> >> >> >> >> >> >> >> >> >> >>    (const char *const);

> >> >> >> >> >> >> >> >> >> >>  extern void lang_add_output_format

> >> >> >> >> >> >> >> >> >> >> diff --git a/ld/ldlex.h b/ld/ldlex.h

> >> >> >> >> >> >> >> >> >> >> index 22b928d2d9..70f2da5636 100644

> >> >> >> >> >> >> >> >> >> >> --- a/ld/ldlex.h

> >> >> >> >> >> >> >> >> >> >> +++ b/ld/ldlex.h

> >> >> >> >> >> >> >> >> >> >> @@ -81,6 +81,7 @@ enum option_values

> >> >> >> >> >> >> >> >> >> >>    OPTION_DYNAMIC_LIST_CPP_NEW,

> >> >> >> >> >> >> >> >> >> >>    OPTION_DYNAMIC_LIST_CPP_TYPEINFO,

> >> >> >> >> >> >> >> >> >> >>    OPTION_DYNAMIC_LIST_DATA,

> >> >> >> >> >> >> >> >> >> >> +  OPTION_EXPORT_DYNAMIC_SYMBOL,

> >> >> >> >> >> >> >> >> >> >>    OPTION_WARN_COMMON,

> >> >> >> >> >> >> >> >> >> >>    OPTION_WARN_CONSTRUCTORS,

> >> >> >> >> >> >> >> >> >> >>    OPTION_WARN_FATAL,

> >> >> >> >> >> >> >> >> >> >> diff --git a/ld/lexsup.c b/ld/lexsup.c

> >> >> >> >> >> >> >> >> >> >> index d1955b9afa..0a0c2f2873 100644

> >> >> >> >> >> >> >> >> >> >> --- a/ld/lexsup.c

> >> >> >> >> >> >> >> >> >> >> +++ b/ld/lexsup.c

> >> >> >> >> >> >> >> >> >> >> @@ -504,6 +504,8 @@ static const struct ld_option ld_options[] =

> >> >> >> >> >> >> >> >> >> >>      '\0', NULL, N_("Use C++ typeinfo dynamic list"), TWO_DASHES },

> >> >> >> >> >> >> >> >> >> >>    { {"dynamic-list", required_argument, NULL, OPTION_DYNAMIC_LIST},

> >> >> >> >> >> >> >> >> >> >>      '\0', N_("FILE"), N_("Read dynamic list"), TWO_DASHES },

> >> >> >> >> >> >> >> >> >> >> +  { {"export-dynamic-symbol", required_argument, NULL, OPTION_EXPORT_DYNAMIC_SYMBOL},

> >> >> >> >> >> >> >> >> >> >> +    '\0', N_("SYMBOL"), N_("Read dynamic list"), TWO_DASHES },

> >> >> >> >> >> >> >> >> >> >>    { {"warn-common", no_argument, NULL, OPTION_WARN_COMMON},

> >> >> >> >> >> >> >> >> >> >>      '\0', NULL, N_("Warn about duplicate common symbols"), TWO_DASHES },

> >> >> >> >> >> >> >> >> >> >>    { {"warn-constructors", no_argument, NULL, OPTION_WARN_CONSTRUCTORS},

> >> >> >> >> >> >> >> >> >> >> @@ -1425,6 +1427,11 @@ parse_args (unsigned argc, char **argv)

> >> >> >> >> >> >> >> >> >> >>           if (opt_symbolic == symbolic)

> >> >> >> >> >> >> >> >> >> >>             opt_symbolic = symbolic_unset;

> >> >> >> >> >> >> >> >> >> >>           break;

> >> >> >> >> >> >> >> >> >> >> +       case OPTION_EXPORT_DYNAMIC_SYMBOL:

> >> >> >> >> >> >> >> >> >> >> +         ldlang_add_export_dynamic_symbol (optarg);

> >> >> >> >> >> >> >> >> >> >> +         if (opt_dynamic_list != dynamic_list_data)

> >> >> >> >> >> >> >> >> >> >> +           opt_dynamic_list = dynamic_list;

> >> >> >> >> >> >> >> >> >> >> +         break;

> >> >> >> >> >> >> >> >> >> >>         case OPTION_WARN_COMMON:

> >> >> >> >> >> >> >> >> >> >>           config.warn_common = TRUE;

> >> >> >> >> >> >> >> >> >> >>           break;

> >> >> >> >> >> >> >> >> >> >> diff --git a/ld/testsuite/ld-undefined/export-dynamic-symbol-1.d b/ld/testsuite/ld-undefined/export-dynamic-symbol-1.d

> >> >> >> >> >> >> >> >> >> >> new file mode 100644

> >> >> >> >> >> >> >> >> >> >> index 0000000000..768bf0abd6

> >> >> >> >> >> >> >> >> >> >> --- /dev/null

> >> >> >> >> >> >> >> >> >> >> +++ b/ld/testsuite/ld-undefined/export-dynamic-symbol-1.d

> >> >> >> >> >> >> >> >> >> >> @@ -0,0 +1,8 @@

> >> >> >> >> >> >> >> >> >> >> +#name: --export-dynamic-symbol foo archive

> >> >> >> >> >> >> >> >> >> >> +#source: require-defined.s

> >> >> >> >> >> >> >> >> >> >> +#ld: -pie --export-dynamic-symbol foo tmpdir/libentry.a

> >> >> >> >> >> >> >> >> >> >

> >> >> >> >> >> >> >> >> >> >I assume that it supports

> >> >> >> >> >> >> >> >> >> >

> >> >> >> >> >> >> >> >> >> >$ ld -pie --export-dynamic-symbol foo --export-dynamic-symbol bar ...

> >> >> >> >> >> >> >> >> >> >

> >> >> >> >> >> >> >> >> >> >Please add another --export-dynamic-symbol to your test.

> >> >> >> >> >> >> >> >> >> >

> >> >> >> >> >> >> >> >> >> >--

> >> >> >> >> >> >> >> >> >> >H.J.

> >> >> >> >> >> >> >> >> >>

> >> >> >> >> >> >> >> >> >> I face a test difficulty. If I add another `#nm:`, runtest complains:

> >> >> >> >> >> >> >> >> >>

> >> >> >> >> >> >> >> >> >> % cd Debug/ld

> >> >> >> >> >> >> >> >> >> % runtest --tool ld --srcdir ../../ld/testsuite/ export-dynamic-symbol.exp

> >> >> >> >> >> >> >> >> >> ...

> >> >> >> >> >> >> >> >> >> ERROR: option nm multiply set in ../../ld/testsuite/ld-undefined/export-dynamic-symbol-1.d

> >> >> >> >> >> >> >> >> >>

> >> >> >> >> >> >> >> >> >> There may also be a problem of symbol table order determinism. I don't

> >> >> >> >> >> >> >> >> >> know whether another symbol may be ordered before foo in some ports and

> >> >> >> >> >> >> >> >> >> after foo in other ports.

> >> >> >> >> >> >> >> >> >>

> >> >> >> >> >> >> >> >> >> Honestly, I think for a number of tests, even if they test generic

> >> >> >> >> >> >> >> >> >> behavior, it might be fine to restrict them to run on certain hosts,

> >> >> >> >> >> >> >> >> >> e.g. Linux x86. What I know about testing is lacking, though, I don't

> >> >> >> >> >> >> >> >> >> know what can be tested.

> >> >> >> >> >> >> >> >> >>

> >> >> >> >> >> >> >> >> >> Ideally `#nm:` should just be free-form shell scripts but unfortunately

> >> >> >> >> >> >> >> >> >> it seems to support very limited features (undocumented?)

> >> >> >> >> >> >> >> >> >

> >> >> >> >> >> >> >> >> >You can't add another #nm.  But you can pass additional options to nm.

> >> >> >> >> >> >> >> >> >

> >> >> >> >> >> >> >> >> >--

> >> >> >> >> >> >> >> >> >H.J.

> >> >> >> >> >> >> >> >>

> >> >> >> >> >> >> >> >> Attached PATCH v2.

> >> >> >> >> >> >> >> >>

> >> >> >> >> >> >> >> >> Added export-dynamic-symbol-2.d

> >> >> >> >> >> >> >> >

> >> >> >> >> >> >> >> >There is

> >> >> >> >> >> >> >> >

> >> >> >> >> >> >> >> >'--dynamic-list=DYNAMIC-LIST-FILE'

> >> >> >> >> >> >> >> >     Specify the name of a dynamic list file to the linker.  This is

> >> >> >> >> >> >> >> >     typically used when creating shared libraries to specify a list of

> >> >> >> >> >> >> >> >     global symbols whose references shouldn't be bound to the

> >> >> >> >> >> >> >> >     definition within the shared library, or creating dynamically

> >> >> >> >> >> >> >> >     linked executables to specify a list of symbols which should be

> >> >> >> >> >> >> >> >     added to the symbol table in the executable.  This option is only

> >> >> >> >> >> >> >> >     meaningful on ELF platforms which support shared libraries.

> >> >> >> >> >> >> >> >

> >> >> >> >> >> >> >> >The new --export-dynamic-symbol option puts it on command-line

> >> >> >> >> >> >> >> >and implicitly adds -u.  This makes the new option different from

> >> >> >> >> >> >> >> >--dynamic-list.  I don't think -u should be added implicitly.  If needed,

> >> >> >> >> >> >> >> >you should add another option to add -u for all symbols on dynamic

> >> >> >> >> >> >> >> >list.

> >> >> >> >> >> >> >> >

> >> >> >> >> >> >> >> >--

> >> >> >> >> >> >> >> >H.J.

> >> >> >> >> >> >> >>

> >> >> >> >> >> >> >> I would also hope gold did not add -u. I don't particularly like it (see

> >> >> >> >> >> >> >> also https://reviews.llvm.org/D43103)

> >> >> >> >> >> >> >

> >> >> >> >> >> >> >Please drop implicit -u.

> >> >> >> >> >> >>

> >> >> >> >> >> >> Done. Attached PATCH v3.

> >> >> >> >> >> >> Improved tests to check a glob pattern and multiple --export-dynamic-symbol.

> >> >> >> >> >> >>

> >> >> >> >> >> >> Moved ld-undefined/ to ld-dynamic/ since the feature is decoupled from -u now.

> >> >> >> >> >> >>

> >> >> >> >> >> >> >> If you think we can correct this, I think it should be fine.

> >> >> >> >> >> >> >

> >> >> >> >> >> >> >Please open a gold bug for this.

> >> >> >> >> >> >> >

> >> >> >> >> >> >> >Thanks.

> >> >> >> >> >> >> >

> >> >> >> >> >> >> >--

> >> >> >> >> >> >> >H.J.

> >> >> >> >> >> >>

> >> >> >> >> >> >> Filed https://sourceware.org/bugzilla/show_bug.cgi?id=25925 (--export-dynamic-symbol should drop implicit -u)

> >> >> >> >> >> >>

> >> >> >> >> >> >>

> >> >> >> >> >> >> I may have to migrate some internal projects if they rely on the

> >> >> >> >> >> >> --export-dynamic-symbol semantics, but hopefully there will not be much

> >> >> >> >> >> >> work. I am glad that --export-dynamic-symbol semantic will be orthogonal!

> >> >> >> >> >> >

> >> >> >> >> >> >+ case OPTION_EXPORT_DYNAMIC_SYMBOL:

> >> >> >> >> >> >+   ldlang_add_export_dynamic_symbol (optarg);

> >> >> >> >> >> >

> >> >> >> >> >> >Can you simply call

> >> >> >> >> >> >

> >> >> >> >> >> >lang_append_dynamic_list (lang_new_vers_pattern (NULL, optarg, NULL, FALSE));

> >> >> >> >> >> >

> >> >> >> >> >> >here?

> >> >> >> >> >> >

> >> >> >> >> >> >--

> >> >> >> >> >> >H.J.

> >> >> >> >> >>

> >> >> >> >> >> Attached PATCH v4, which also handles -shared.  The previous patches do not handle -shared.

> >> >> >> >> >> Added two tests to ld-elf/shared.exp

> >> >> >> >> >>

> >> >> >> >> >> The updated semantics:

> >> >> >> >> >>

> >> >> >> >> >> + @kindex --export-dynamic-symbol=@var{glob}

> >> >> >> >> >> + @cindex export dynamic symbol

> >> >> >> >> >> + @item --export-dynamic-symbol=@var{glob}

> >> >> >> >> >> + When creating a dynamically linked executable, symbols matching

> >> >> >> >> >> + @var{glob} will be added to the dynamic symbol table. When creating a

> >> >> >> >> >> + shared library, references to symbols matching @var{glob} will not be

> >> >> >> >> >> + bound to the definitions within the shared library. This option is a

> >> >> >> >> >> + no-op when creating a shared library and @samp{--dynamic-list} is not

> >> >> >> >> >> + specified. This option is only meaningful on ELF platforms which

> >> >> >> >> >> + support shared libraries.

> >> >> >> >> >>

> >> >> >> >> >> i.e. --export-dynamic-symbol is like addition to --dynamic-list,

> >> >> >> >> >> except: -shared --export-dynamic-symbol without --dynamic-list will not

> >> >> >> >> >> act as -Bsymbolic.

> >> >> >> >> >>

> >> >> >> >> >> In the option processing loop, we cannot call lang_append_dynamic_list

> >> >> >> >> >> because when -shared is specified but --dynamic-list is not specified,

> >> >> >> >> >> --export-dynamic-symbol should be a no-op.

> >> >> >> >> >

> >> >> >> >> >--dynamic-list implies -Bsymbolic.  If we add --export-dynamic-symbol,

> >> >> >> >> >we should also add --export-dynamic-symbol-list, which is similar to

> >> >> >> >> >--dynamic-list, but without -Bsymbolic.

> >> >> >> >>

> >> >> >> >> --export-dynamic-symbol-list a.list  where a.list is a plain text like:

> >> >> >> >> foo

> >> >> >> >> bar

> >> >> >> >> ?

> >> >> >> >

> >> >> >> >I prefer to use the same format as --dynamic-list.

> >> >> >> >

> >> >> >> >> The feature can be provided by a response file @a.rsp

> >> >> >> >> --export-dynamic-symbol foo

> >> >> >> >> --export-dynamic-symbol bar

> >> >> >>

> >> >> >> Adding --export-dynamic-symbol-list is fine. We can implement that separately.

> >> >> >

> >> >> >Since implement --export-dynamic-symbol-list at the same time may impact how

> >> >> >--export-dynamic-symbol is implemented, they should be added together.

> >> >>

> >> >> OK. Added --export-dynamic-symbol-list as well.

> >> >>

> >> >> Retitled.

> >> >

> >> >A couple comments:

> >>

> >> Thanks for the review!

> >>

> >> >1. Please add an entry to ld/NEWS.

> >> >2. Please a note to ld.texi for the difference between --dynamic-list and

> >> >--export-dynamic-symbol.

> >>

> >> >3.  What happens when there are both --dynamic-list and and

> >> >--export-dynamic-symbol, with and without -Bsymbolic?

> >>

> >> --export-symbol-symbol adds additional entries to --dynamic-list.

> >

> >I don't think so.  See below.

> >

> >>

> >> I'd expect --dynamic-list to override -Bsymbolic (i.e. --dynamic-list is a

> >> refined -Bsymbolic).

> >> gold and

> >> LLD (https://github.com/llvm/llvm-project/blob/master/lld/ELF/Symbols.cpp#L368)

> >> behave this way.

> >> GNU ld seems to make every symbol symbolic.

> >

> >Ld manual says

> >

> >'--dynamic-list=DYNAMIC-LIST-FILE'

> >     Specify the name of a dynamic list file to the linker.  This is

> >     typically used when creating shared libraries to specify a list of

> >     global symbols whose references shouldn't be bound to the

> >     definition within the shared library, or creating dynamically

> >     linked executables to specify a list of symbols which should be

> >     added to the symbol table in the executable.  This option is only

> >     meaningful on ELF platforms which support shared libraries.

> >

> >     The format of the dynamic list is the same as the version node

> >     without scope and node name.  See *note VERSION:: for more

> >     information.

> >

> >When producing a shared library,  --dynamic-list implies -Bsymbolic

> >with exception for the symbols on the dynamic list.

>

> This is my understanding. By using `implies`, do you mean -Bsymbolic is

> ignored (gold and LLD's interpretation)? If so, GNU ld should be fixed.


--dynamic-list should be the same as -Bsymbolic --dynamic-list.

> I don't think any project is using the combination, so changing the

> semantics should not be a problem.

>

> >> This can be tested with:

> >>

> >> .globl main, foo, bar

> >> main: call foo

> >> foo: call bar

> >> bar: ret

> >>

> >> // a.list

> >> { foo; };

> >>

> >> It is also fine if you think -Bsymbolic should override --dynamic-list.

> >> (Please add a test for that so that I know how to test --export-dynamic-list)

> >> We can then file a gold bug.

> >>

> >> >4.  Can you reuse lang_append_dynamic_list to implement

> >> >--export-dynamic-symbol?

> >>

> >> This is difficult. It seems that another global variable needs to be introduced.

> >> yacc code duplication may not be that bad compared with the alternative.

> >

> >Since --export-dynamic-symbol is a NOP for -shared and identical with

> >--dynamic-list otherwise, let's only consider the -shared case:

>

> Combined with both points below, --export-dynamic-symbol can be treated

> as a NOP when -shared is specified.  This is acceptable because (as far

> as I can tell from my observation) --export-dynamic is a NOP with

> -shared.

>

> >1. Without -Bsymbolic nor --dynamic-list,  --export-dynamic-symbol should

> >be dropped.

>

> Looks good.

>

> >2. With -Bsymbolic or --dynamic-list, --export-dynamic-symbol should also

> >be dropped since --export-dynamic-symbol doesn't change symbol binding.

>

> Is the intention that --export-dynamic-symbol should be similar more to

> --export-dynamic and less to --dynamic-list? I'm fine with the change.

>

>

> If a.list contains { foo; };

>

>

> # all global symbols are exported. foo is symbolic. --export-dynamic is ignored.

> ld.bfd -shared --dynamic-list=a.list --export-dynamic

>

> # all global symbols are exported. foo is symbolic. --export-dynamic-bar is ignored.

> ld.bfd -shared --dynamic-list=a.list --export-dynamic-symbol=bar

>

> # all global symbols are exported.

> ld.bfd -pie --dynamic-list=a.list --export-dynamic

>

> # foo and bar are exported.

> ld.bfd -pie --dynamic-list=a.list --export-dynamic-symbol=bar

>

> >I think we should add a bit field to bfd_elf_version_expr to indicate if symbol

> >binding should be symbolic (-Bsymbolic) and use lang_append_dynamic_list

> >for both --dynamic-list and --export-dynamic-symbol.  The only

> >difference is that

> >symbols from --export-dynamic-symbol aren't symbolic and can be dropped for

> >-shared.

>

> Like my patch does, we need a separate list for --export-dynamic-symbol.

> We cannot call lang_append_dynamic_list yet when processing options,

> because it is unknown whether -shared will occur.


The dynamic list should be processed after all command line options have
been seen.

-- 
H.J.
On Wed, May 13, 2020 at 8:36 AM H.J. Lu <hjl.tools@gmail.com> wrote:
>

> On Wed, May 13, 2020 at 8:24 AM Fangrui Song <maskray@google.com> wrote:

> >

> > On 2020-05-13, H.J. Lu wrote:

> > >On Tue, May 12, 2020 at 9:38 PM Fangrui Song <maskray@google.com> wrote:

> > >>

> > >> On 2020-05-11, H.J. Lu wrote:

> > >> >On Sun, May 10, 2020 at 11:46 PM Fangrui Song <maskray@google.com> wrote:

> > >> >>

> > >> >> On 2020-05-08, H.J. Lu wrote:

> > >> >> >On Fri, May 8, 2020 at 8:12 AM Fangrui Song <maskray@google.com> wrote:

> > >> >> >>

> > >> >> >>

> > >> >> >> On 2020-05-08, H.J. Lu wrote:

> > >> >> >> >On Fri, May 8, 2020 at 7:54 AM Fangrui Song <maskray@google.com> wrote:

> > >> >> >> >>

> > >> >> >> >> On 2020-05-08, H.J. Lu wrote:

> > >> >> >> >> >On Wed, May 6, 2020 at 11:42 AM Fangrui Song <maskray@google.com> wrote:

> > >> >> >> >> >>

> > >> >> >> >> >> On 2020-05-05, H.J. Lu wrote:

> > >> >> >> >> >> >On Tue, May 5, 2020 at 9:55 AM Fangrui Song <maskray@google.com> wrote:

> > >> >> >> >> >> >>

> > >> >> >> >> >> >>

> > >> >> >> >> >> >> On 2020-05-05, H.J. Lu wrote:

> > >> >> >> >> >> >> >On Tue, May 5, 2020 at 8:30 AM Fangrui Song <maskray@google.com> wrote:

> > >> >> >> >> >> >> >>

> > >> >> >> >> >> >> >> On 2020-05-05, H.J. Lu wrote:

> > >> >> >> >> >> >> >> >On Mon, May 4, 2020 at 7:10 PM Fangrui Song <maskray@google.com> wrote:

> > >> >> >> >> >> >> >> >>

> > >> >> >> >> >> >> >> >> On 2020-05-04, H.J. Lu wrote:

> > >> >> >> >> >> >> >> >> >On Mon, May 4, 2020 at 10:48 AM Fangrui Song <maskray@google.com> wrote:

> > >> >> >> >> >> >> >> >> >>

> > >> >> >> >> >> >> >> >> >> On 2020-05-03, H.J. Lu wrote:

> > >> >> >> >> >> >> >> >> >> >On Sat, May 2, 2020 at 11:15 PM Fangrui Song via Binutils

> > >> >> >> >> >> >> >> >> >> ><binutils@sourceware.org> wrote:

> > >> >> >> >> >> >> >> >> >> >>

> > >> >> >> >> >> >> >> >> >> >>         PR ld/25910

> > >> >> >> >> >> >> >> >> >> >>         * ldlang.c (export_dynamic_symbol_list): New.

> > >> >> >> >> >> >> >> >> >> >>         (ldlang_add_export_dynamic_symbol): New.

> > >> >> >> >> >> >> >> >> >> >>         (lang_place_export_dynamic_symbols): New.

> > >> >> >> >> >> >> >> >> >> >>         (lang_process): Handle export_dynamic_symbol_list.

> > >> >> >> >> >> >> >> >> >> >>         * ldlang.h (ldlang_add_export_dynamic_symbol): New.

> > >> >> >> >> >> >> >> >> >> >>         * ldlex.h (option_values): Add OPTION_EXPORT_DYNAMIC_SYMBOL.

> > >> >> >> >> >> >> >> >> >> >>         * lexsup.c (ld_options): Add entry for OPTION_EXPORT_DYNAMIC_SYMBOL.

> > >> >> >> >> >> >> >> >> >> >>         (parse_args): Handle it.

> > >> >> >> >> >> >> >> >> >> >>         * ld.texi: Add --export-dynamic-symbol documentation.

> > >> >> >> >> >> >> >> >> >> >>         * testsuite/ld-undefined/export-dynamic-symbol.exp: Run new test.

> > >> >> >> >> >> >> >> >> >> >>         * testsuite/ld-undefined/export-dynamic-symbol-1.d: New.

> > >> >> >> >> >> >> >> >> >> >> ---

> > >> >> >> >> >> >> >> >> >> >>  ld/ld.texi                                    |  8 +++++

> > >> >> >> >> >> >> >> >> >> >>  ld/ldlang.c                                   | 26 ++++++++++++++

> > >> >> >> >> >> >> >> >> >> >>  ld/ldlang.h                                   |  2 ++

> > >> >> >> >> >> >> >> >> >> >>  ld/ldlex.h                                    |  1 +

> > >> >> >> >> >> >> >> >> >> >>  ld/lexsup.c                                   |  7 ++++

> > >> >> >> >> >> >> >> >> >> >>  .../ld-undefined/export-dynamic-symbol-1.d    |  8 +++++

> > >> >> >> >> >> >> >> >> >> >>  .../ld-undefined/export-dynamic-symbol.exp    | 35 +++++++++++++++++++

> > >> >> >> >> >> >> >> >> >> >>  7 files changed, 87 insertions(+)

> > >> >> >> >> >> >> >> >> >> >>  create mode 100644 ld/testsuite/ld-undefined/export-dynamic-symbol-1.d

> > >> >> >> >> >> >> >> >> >> >>  create mode 100644 ld/testsuite/ld-undefined/export-dynamic-symbol.exp

> > >> >> >> >> >> >> >> >> >> >>

> > >> >> >> >> >> >> >> >> >> >> diff --git a/ld/ld.texi b/ld/ld.texi

> > >> >> >> >> >> >> >> >> >> >> index 4dc78e65fa..b3dc95f314 100644

> > >> >> >> >> >> >> >> >> >> >> --- a/ld/ld.texi

> > >> >> >> >> >> >> >> >> >> >> +++ b/ld/ld.texi

> > >> >> >> >> >> >> >> >> >> >> @@ -569,6 +569,14 @@ Note that this option is specific to ELF targeted ports.  PE targets

> > >> >> >> >> >> >> >> >> >> >>  support a similar function to export all symbols from a DLL or EXE; see

> > >> >> >> >> >> >> >> >> >> >>  the description of @samp{--export-all-symbols} below.

> > >> >> >> >> >> >> >> >> >> >>

> > >> >> >> >> >> >> >> >> >> >> +@kindex --export-dynamic-symbol=@var{symbol}

> > >> >> >> >> >> >> >> >> >> >> +@cindex export dynamic symbol

> > >> >> >> >> >> >> >> >> >> >> +@item --export-dynamic-symbol=@var{symbol}

> > >> >> >> >> >> >> >> >> >> >> +Specify a symbol that should be added to the dynamic symbol table.

> > >> >> >> >> >> >> >> >> >> >> +Additionally, force @var{symbol} to be entered in the output file as an

> > >> >> >> >> >> >> >> >> >> >> +undefined symbol.  Doing this may, for example, trigger linking of additional

> > >> >> >> >> >> >> >> >> >> >> +modules from archives.

> > >> >> >> >> >> >> >> >> >> >> +

> > >> >> >> >> >> >> >> >> >> >>  @ifclear SingleFormat

> > >> >> >> >> >> >> >> >> >> >>  @cindex big-endian objects

> > >> >> >> >> >> >> >> >> >> >>  @cindex endianness

> > >> >> >> >> >> >> >> >> >> >> diff --git a/ld/ldlang.c b/ld/ldlang.c

> > >> >> >> >> >> >> >> >> >> >> index b2cdb3603a..e7ecdfeaf0 100644

> > >> >> >> >> >> >> >> >> >> >> --- a/ld/ldlang.c

> > >> >> >> >> >> >> >> >> >> >> +++ b/ld/ldlang.c

> > >> >> >> >> >> >> >> >> >> >> @@ -3910,6 +3910,26 @@ lang_place_undefineds (void)

> > >> >> >> >> >> >> >> >> >> >>      insert_undefined (ptr->name);

> > >> >> >> >> >> >> >> >> >> >>  }

> > >> >> >> >> >> >> >> >> >> >>

> > >> >> >> >> >> >> >> >> >> >> +static struct bfd_sym_chain export_dynamic_symbol_list = { NULL, NULL };

> > >> >> >> >> >> >> >> >> >> >> +

> > >> >> >> >> >> >> >> >> >> >> +void

> > >> >> >> >> >> >> >> >> >> >> +ldlang_add_export_dynamic_symbol (const char *const name)

> > >> >> >> >> >> >> >> >> >> >> +{

> > >> >> >> >> >> >> >> >> >> >> +  struct bfd_sym_chain *sym;

> > >> >> >> >> >> >> >> >> >> >> +  sym = stat_alloc (sizeof (*sym));

> > >> >> >> >> >> >> >> >> >> >> +  sym->name = xstrdup (name);

> > >> >> >> >> >> >> >> >> >> >> +  sym->next = export_dynamic_symbol_list.next;

> > >> >> >> >> >> >> >> >> >> >> +  export_dynamic_symbol_list.next = sym;

> > >> >> >> >> >> >> >> >> >> >> +}

> > >> >> >> >> >> >> >> >> >> >> +

> > >> >> >> >> >> >> >> >> >> >> +static void

> > >> >> >> >> >> >> >> >> >> >> +lang_place_export_dynamic_symbols (void)

> > >> >> >> >> >> >> >> >> >> >> +{

> > >> >> >> >> >> >> >> >> >> >> +  struct bfd_sym_chain *sym;

> > >> >> >> >> >> >> >> >> >> >> +  for (sym = export_dynamic_symbol_list.next; sym != NULL; sym = sym->next)

> > >> >> >> >> >> >> >> >> >> >> +    insert_undefined (sym->name);

> > >> >> >> >> >> >> >> >> >> >> +}

> > >> >> >> >> >> >> >> >> >> >> +

> > >> >> >> >> >> >> >> >> >> >>  /* Structure used to build the list of symbols that the user has required

> > >> >> >> >> >> >> >> >> >> >>     be defined.  */

> > >> >> >> >> >> >> >> >> >> >>

> > >> >> >> >> >> >> >> >> >> >> @@ -7795,6 +7815,10 @@ void

> > >> >> >> >> >> >> >> >> >> >>  lang_process (void)

> > >> >> >> >> >> >> >> >> >> >>  {

> > >> >> >> >> >> >> >> >> >> >>    /* Finalize dynamic list.  */

> > >> >> >> >> >> >> >> >> >> >> +  struct bfd_sym_chain *sym;

> > >> >> >> >> >> >> >> >> >> >> +  for (sym = export_dynamic_symbol_list.next; sym != NULL; sym = sym->next)

> > >> >> >> >> >> >> >> >> >> >> +    lang_append_dynamic_list (

> > >> >> >> >> >> >> >> >> >> >> +        lang_new_vers_pattern (NULL, sym->name, NULL, FALSE));

> > >> >> >> >> >> >> >> >> >> >>    if (link_info.dynamic_list)

> > >> >> >> >> >> >> >> >> >> >>      lang_finalize_version_expr_head (&link_info.dynamic_list->head);

> > >> >> >> >> >> >> >> >> >> >>

> > >> >> >> >> >> >> >> >> >> >> @@ -7808,6 +7832,8 @@ lang_process (void)

> > >> >> >> >> >> >> >> >> >> >>

> > >> >> >> >> >> >> >> >> >> >>    /* Add to the hash table all undefineds on the command line.  */

> > >> >> >> >> >> >> >> >> >> >>    lang_place_undefineds ();

> > >> >> >> >> >> >> >> >> >> >> +  /* Add --export-dynamic-symbol symbols to the hash table.  */

> > >> >> >> >> >> >> >> >> >> >> +  lang_place_export_dynamic_symbols ();

> > >> >> >> >> >> >> >> >> >> >>

> > >> >> >> >> >> >> >> >> >> >>    if (!bfd_section_already_linked_table_init ())

> > >> >> >> >> >> >> >> >> >> >>      einfo (_("%F%P: can not create hash table: %E\n"));

> > >> >> >> >> >> >> >> >> >> >> diff --git a/ld/ldlang.h b/ld/ldlang.h

> > >> >> >> >> >> >> >> >> >> >> index 2aa3930f95..8c004b173c 100644

> > >> >> >> >> >> >> >> >> >> >> --- a/ld/ldlang.h

> > >> >> >> >> >> >> >> >> >> >> +++ b/ld/ldlang.h

> > >> >> >> >> >> >> >> >> >> >> @@ -606,6 +606,8 @@ extern lang_output_section_statement_type *next_matching_output_section_statemen

> > >> >> >> >> >> >> >> >> >> >>    (lang_output_section_statement_type *, int);

> > >> >> >> >> >> >> >> >> >> >>  extern void ldlang_add_undef

> > >> >> >> >> >> >> >> >> >> >>    (const char *const, bfd_boolean);

> > >> >> >> >> >> >> >> >> >> >> +extern void ldlang_add_export_dynamic_symbol

> > >> >> >> >> >> >> >> >> >> >> +  (const char *const);

> > >> >> >> >> >> >> >> >> >> >>  extern void ldlang_add_require_defined

> > >> >> >> >> >> >> >> >> >> >>    (const char *const);

> > >> >> >> >> >> >> >> >> >> >>  extern void lang_add_output_format

> > >> >> >> >> >> >> >> >> >> >> diff --git a/ld/ldlex.h b/ld/ldlex.h

> > >> >> >> >> >> >> >> >> >> >> index 22b928d2d9..70f2da5636 100644

> > >> >> >> >> >> >> >> >> >> >> --- a/ld/ldlex.h

> > >> >> >> >> >> >> >> >> >> >> +++ b/ld/ldlex.h

> > >> >> >> >> >> >> >> >> >> >> @@ -81,6 +81,7 @@ enum option_values

> > >> >> >> >> >> >> >> >> >> >>    OPTION_DYNAMIC_LIST_CPP_NEW,

> > >> >> >> >> >> >> >> >> >> >>    OPTION_DYNAMIC_LIST_CPP_TYPEINFO,

> > >> >> >> >> >> >> >> >> >> >>    OPTION_DYNAMIC_LIST_DATA,

> > >> >> >> >> >> >> >> >> >> >> +  OPTION_EXPORT_DYNAMIC_SYMBOL,

> > >> >> >> >> >> >> >> >> >> >>    OPTION_WARN_COMMON,

> > >> >> >> >> >> >> >> >> >> >>    OPTION_WARN_CONSTRUCTORS,

> > >> >> >> >> >> >> >> >> >> >>    OPTION_WARN_FATAL,

> > >> >> >> >> >> >> >> >> >> >> diff --git a/ld/lexsup.c b/ld/lexsup.c

> > >> >> >> >> >> >> >> >> >> >> index d1955b9afa..0a0c2f2873 100644

> > >> >> >> >> >> >> >> >> >> >> --- a/ld/lexsup.c

> > >> >> >> >> >> >> >> >> >> >> +++ b/ld/lexsup.c

> > >> >> >> >> >> >> >> >> >> >> @@ -504,6 +504,8 @@ static const struct ld_option ld_options[] =

> > >> >> >> >> >> >> >> >> >> >>      '\0', NULL, N_("Use C++ typeinfo dynamic list"), TWO_DASHES },

> > >> >> >> >> >> >> >> >> >> >>    { {"dynamic-list", required_argument, NULL, OPTION_DYNAMIC_LIST},

> > >> >> >> >> >> >> >> >> >> >>      '\0', N_("FILE"), N_("Read dynamic list"), TWO_DASHES },

> > >> >> >> >> >> >> >> >> >> >> +  { {"export-dynamic-symbol", required_argument, NULL, OPTION_EXPORT_DYNAMIC_SYMBOL},

> > >> >> >> >> >> >> >> >> >> >> +    '\0', N_("SYMBOL"), N_("Read dynamic list"), TWO_DASHES },

> > >> >> >> >> >> >> >> >> >> >>    { {"warn-common", no_argument, NULL, OPTION_WARN_COMMON},

> > >> >> >> >> >> >> >> >> >> >>      '\0', NULL, N_("Warn about duplicate common symbols"), TWO_DASHES },

> > >> >> >> >> >> >> >> >> >> >>    { {"warn-constructors", no_argument, NULL, OPTION_WARN_CONSTRUCTORS},

> > >> >> >> >> >> >> >> >> >> >> @@ -1425,6 +1427,11 @@ parse_args (unsigned argc, char **argv)

> > >> >> >> >> >> >> >> >> >> >>           if (opt_symbolic == symbolic)

> > >> >> >> >> >> >> >> >> >> >>             opt_symbolic = symbolic_unset;

> > >> >> >> >> >> >> >> >> >> >>           break;

> > >> >> >> >> >> >> >> >> >> >> +       case OPTION_EXPORT_DYNAMIC_SYMBOL:

> > >> >> >> >> >> >> >> >> >> >> +         ldlang_add_export_dynamic_symbol (optarg);

> > >> >> >> >> >> >> >> >> >> >> +         if (opt_dynamic_list != dynamic_list_data)

> > >> >> >> >> >> >> >> >> >> >> +           opt_dynamic_list = dynamic_list;

> > >> >> >> >> >> >> >> >> >> >> +         break;

> > >> >> >> >> >> >> >> >> >> >>         case OPTION_WARN_COMMON:

> > >> >> >> >> >> >> >> >> >> >>           config.warn_common = TRUE;

> > >> >> >> >> >> >> >> >> >> >>           break;

> > >> >> >> >> >> >> >> >> >> >> diff --git a/ld/testsuite/ld-undefined/export-dynamic-symbol-1.d b/ld/testsuite/ld-undefined/export-dynamic-symbol-1.d

> > >> >> >> >> >> >> >> >> >> >> new file mode 100644

> > >> >> >> >> >> >> >> >> >> >> index 0000000000..768bf0abd6

> > >> >> >> >> >> >> >> >> >> >> --- /dev/null

> > >> >> >> >> >> >> >> >> >> >> +++ b/ld/testsuite/ld-undefined/export-dynamic-symbol-1.d

> > >> >> >> >> >> >> >> >> >> >> @@ -0,0 +1,8 @@

> > >> >> >> >> >> >> >> >> >> >> +#name: --export-dynamic-symbol foo archive

> > >> >> >> >> >> >> >> >> >> >> +#source: require-defined.s

> > >> >> >> >> >> >> >> >> >> >> +#ld: -pie --export-dynamic-symbol foo tmpdir/libentry.a

> > >> >> >> >> >> >> >> >> >> >

> > >> >> >> >> >> >> >> >> >> >I assume that it supports

> > >> >> >> >> >> >> >> >> >> >

> > >> >> >> >> >> >> >> >> >> >$ ld -pie --export-dynamic-symbol foo --export-dynamic-symbol bar ...

> > >> >> >> >> >> >> >> >> >> >

> > >> >> >> >> >> >> >> >> >> >Please add another --export-dynamic-symbol to your test.

> > >> >> >> >> >> >> >> >> >> >

> > >> >> >> >> >> >> >> >> >> >--

> > >> >> >> >> >> >> >> >> >> >H.J.

> > >> >> >> >> >> >> >> >> >>

> > >> >> >> >> >> >> >> >> >> I face a test difficulty. If I add another `#nm:`, runtest complains:

> > >> >> >> >> >> >> >> >> >>

> > >> >> >> >> >> >> >> >> >> % cd Debug/ld

> > >> >> >> >> >> >> >> >> >> % runtest --tool ld --srcdir ../../ld/testsuite/ export-dynamic-symbol.exp

> > >> >> >> >> >> >> >> >> >> ...

> > >> >> >> >> >> >> >> >> >> ERROR: option nm multiply set in ../../ld/testsuite/ld-undefined/export-dynamic-symbol-1.d

> > >> >> >> >> >> >> >> >> >>

> > >> >> >> >> >> >> >> >> >> There may also be a problem of symbol table order determinism. I don't

> > >> >> >> >> >> >> >> >> >> know whether another symbol may be ordered before foo in some ports and

> > >> >> >> >> >> >> >> >> >> after foo in other ports.

> > >> >> >> >> >> >> >> >> >>

> > >> >> >> >> >> >> >> >> >> Honestly, I think for a number of tests, even if they test generic

> > >> >> >> >> >> >> >> >> >> behavior, it might be fine to restrict them to run on certain hosts,

> > >> >> >> >> >> >> >> >> >> e.g. Linux x86. What I know about testing is lacking, though, I don't

> > >> >> >> >> >> >> >> >> >> know what can be tested.

> > >> >> >> >> >> >> >> >> >>

> > >> >> >> >> >> >> >> >> >> Ideally `#nm:` should just be free-form shell scripts but unfortunately

> > >> >> >> >> >> >> >> >> >> it seems to support very limited features (undocumented?)

> > >> >> >> >> >> >> >> >> >

> > >> >> >> >> >> >> >> >> >You can't add another #nm.  But you can pass additional options to nm.

> > >> >> >> >> >> >> >> >> >

> > >> >> >> >> >> >> >> >> >--

> > >> >> >> >> >> >> >> >> >H.J.

> > >> >> >> >> >> >> >> >>

> > >> >> >> >> >> >> >> >> Attached PATCH v2.

> > >> >> >> >> >> >> >> >>

> > >> >> >> >> >> >> >> >> Added export-dynamic-symbol-2.d

> > >> >> >> >> >> >> >> >

> > >> >> >> >> >> >> >> >There is

> > >> >> >> >> >> >> >> >

> > >> >> >> >> >> >> >> >'--dynamic-list=DYNAMIC-LIST-FILE'

> > >> >> >> >> >> >> >> >     Specify the name of a dynamic list file to the linker.  This is

> > >> >> >> >> >> >> >> >     typically used when creating shared libraries to specify a list of

> > >> >> >> >> >> >> >> >     global symbols whose references shouldn't be bound to the

> > >> >> >> >> >> >> >> >     definition within the shared library, or creating dynamically

> > >> >> >> >> >> >> >> >     linked executables to specify a list of symbols which should be

> > >> >> >> >> >> >> >> >     added to the symbol table in the executable.  This option is only

> > >> >> >> >> >> >> >> >     meaningful on ELF platforms which support shared libraries.

> > >> >> >> >> >> >> >> >

> > >> >> >> >> >> >> >> >The new --export-dynamic-symbol option puts it on command-line

> > >> >> >> >> >> >> >> >and implicitly adds -u.  This makes the new option different from

> > >> >> >> >> >> >> >> >--dynamic-list.  I don't think -u should be added implicitly.  If needed,

> > >> >> >> >> >> >> >> >you should add another option to add -u for all symbols on dynamic

> > >> >> >> >> >> >> >> >list.

> > >> >> >> >> >> >> >> >

> > >> >> >> >> >> >> >> >--

> > >> >> >> >> >> >> >> >H.J.

> > >> >> >> >> >> >> >>

> > >> >> >> >> >> >> >> I would also hope gold did not add -u. I don't particularly like it (see

> > >> >> >> >> >> >> >> also https://reviews.llvm.org/D43103)

> > >> >> >> >> >> >> >

> > >> >> >> >> >> >> >Please drop implicit -u.

> > >> >> >> >> >> >>

> > >> >> >> >> >> >> Done. Attached PATCH v3.

> > >> >> >> >> >> >> Improved tests to check a glob pattern and multiple --export-dynamic-symbol.

> > >> >> >> >> >> >>

> > >> >> >> >> >> >> Moved ld-undefined/ to ld-dynamic/ since the feature is decoupled from -u now.

> > >> >> >> >> >> >>

> > >> >> >> >> >> >> >> If you think we can correct this, I think it should be fine.

> > >> >> >> >> >> >> >

> > >> >> >> >> >> >> >Please open a gold bug for this.

> > >> >> >> >> >> >> >

> > >> >> >> >> >> >> >Thanks.

> > >> >> >> >> >> >> >

> > >> >> >> >> >> >> >--

> > >> >> >> >> >> >> >H.J.

> > >> >> >> >> >> >>

> > >> >> >> >> >> >> Filed https://sourceware.org/bugzilla/show_bug.cgi?id=25925 (--export-dynamic-symbol should drop implicit -u)

> > >> >> >> >> >> >>

> > >> >> >> >> >> >>

> > >> >> >> >> >> >> I may have to migrate some internal projects if they rely on the

> > >> >> >> >> >> >> --export-dynamic-symbol semantics, but hopefully there will not be much

> > >> >> >> >> >> >> work. I am glad that --export-dynamic-symbol semantic will be orthogonal!

> > >> >> >> >> >> >

> > >> >> >> >> >> >+ case OPTION_EXPORT_DYNAMIC_SYMBOL:

> > >> >> >> >> >> >+   ldlang_add_export_dynamic_symbol (optarg);

> > >> >> >> >> >> >

> > >> >> >> >> >> >Can you simply call

> > >> >> >> >> >> >

> > >> >> >> >> >> >lang_append_dynamic_list (lang_new_vers_pattern (NULL, optarg, NULL, FALSE));

> > >> >> >> >> >> >

> > >> >> >> >> >> >here?

> > >> >> >> >> >> >

> > >> >> >> >> >> >--

> > >> >> >> >> >> >H.J.

> > >> >> >> >> >>

> > >> >> >> >> >> Attached PATCH v4, which also handles -shared.  The previous patches do not handle -shared.

> > >> >> >> >> >> Added two tests to ld-elf/shared.exp

> > >> >> >> >> >>

> > >> >> >> >> >> The updated semantics:

> > >> >> >> >> >>

> > >> >> >> >> >> + @kindex --export-dynamic-symbol=@var{glob}

> > >> >> >> >> >> + @cindex export dynamic symbol

> > >> >> >> >> >> + @item --export-dynamic-symbol=@var{glob}

> > >> >> >> >> >> + When creating a dynamically linked executable, symbols matching

> > >> >> >> >> >> + @var{glob} will be added to the dynamic symbol table. When creating a

> > >> >> >> >> >> + shared library, references to symbols matching @var{glob} will not be

> > >> >> >> >> >> + bound to the definitions within the shared library. This option is a

> > >> >> >> >> >> + no-op when creating a shared library and @samp{--dynamic-list} is not

> > >> >> >> >> >> + specified. This option is only meaningful on ELF platforms which

> > >> >> >> >> >> + support shared libraries.

> > >> >> >> >> >>

> > >> >> >> >> >> i.e. --export-dynamic-symbol is like addition to --dynamic-list,

> > >> >> >> >> >> except: -shared --export-dynamic-symbol without --dynamic-list will not

> > >> >> >> >> >> act as -Bsymbolic.

> > >> >> >> >> >>

> > >> >> >> >> >> In the option processing loop, we cannot call lang_append_dynamic_list

> > >> >> >> >> >> because when -shared is specified but --dynamic-list is not specified,

> > >> >> >> >> >> --export-dynamic-symbol should be a no-op.

> > >> >> >> >> >

> > >> >> >> >> >--dynamic-list implies -Bsymbolic.  If we add --export-dynamic-symbol,

> > >> >> >> >> >we should also add --export-dynamic-symbol-list, which is similar to

> > >> >> >> >> >--dynamic-list, but without -Bsymbolic.

> > >> >> >> >>

> > >> >> >> >> --export-dynamic-symbol-list a.list  where a.list is a plain text like:

> > >> >> >> >> foo

> > >> >> >> >> bar

> > >> >> >> >> ?

> > >> >> >> >

> > >> >> >> >I prefer to use the same format as --dynamic-list.

> > >> >> >> >

> > >> >> >> >> The feature can be provided by a response file @a.rsp

> > >> >> >> >> --export-dynamic-symbol foo

> > >> >> >> >> --export-dynamic-symbol bar

> > >> >> >>

> > >> >> >> Adding --export-dynamic-symbol-list is fine. We can implement that separately.

> > >> >> >

> > >> >> >Since implement --export-dynamic-symbol-list at the same time may impact how

> > >> >> >--export-dynamic-symbol is implemented, they should be added together.

> > >> >>

> > >> >> OK. Added --export-dynamic-symbol-list as well.

> > >> >>

> > >> >> Retitled.

> > >> >

> > >> >A couple comments:

> > >>

> > >> Thanks for the review!

> > >>

> > >> >1. Please add an entry to ld/NEWS.

> > >> >2. Please a note to ld.texi for the difference between --dynamic-list and

> > >> >--export-dynamic-symbol.

> > >>

> > >> >3.  What happens when there are both --dynamic-list and and

> > >> >--export-dynamic-symbol, with and without -Bsymbolic?

> > >>

> > >> --export-symbol-symbol adds additional entries to --dynamic-list.

> > >

> > >I don't think so.  See below.

> > >

> > >>

> > >> I'd expect --dynamic-list to override -Bsymbolic (i.e. --dynamic-list is a

> > >> refined -Bsymbolic).

> > >> gold and

> > >> LLD (https://github.com/llvm/llvm-project/blob/master/lld/ELF/Symbols.cpp#L368)

> > >> behave this way.

> > >> GNU ld seems to make every symbol symbolic.

> > >

> > >Ld manual says

> > >

> > >'--dynamic-list=DYNAMIC-LIST-FILE'

> > >     Specify the name of a dynamic list file to the linker.  This is

> > >     typically used when creating shared libraries to specify a list of

> > >     global symbols whose references shouldn't be bound to the

> > >     definition within the shared library, or creating dynamically

> > >     linked executables to specify a list of symbols which should be

> > >     added to the symbol table in the executable.  This option is only

> > >     meaningful on ELF platforms which support shared libraries.

> > >

> > >     The format of the dynamic list is the same as the version node

> > >     without scope and node name.  See *note VERSION:: for more

> > >     information.

> > >

> > >When producing a shared library,  --dynamic-list implies -Bsymbolic

> > >with exception for the symbols on the dynamic list.

> >

> > This is my understanding. By using `implies`, do you mean -Bsymbolic is

> > ignored (gold and LLD's interpretation)? If so, GNU ld should be fixed.

>

> --dynamic-list should be the same as -Bsymbolic --dynamic-list.

>

> > I don't think any project is using the combination, so changing the

> > semantics should not be a problem.

> >

> > >> This can be tested with:

> > >>

> > >> .globl main, foo, bar

> > >> main: call foo

> > >> foo: call bar

> > >> bar: ret

> > >>

> > >> // a.list

> > >> { foo; };

> > >>

> > >> It is also fine if you think -Bsymbolic should override --dynamic-list.

> > >> (Please add a test for that so that I know how to test --export-dynamic-list)

> > >> We can then file a gold bug.

> > >>

> > >> >4.  Can you reuse lang_append_dynamic_list to implement

> > >> >--export-dynamic-symbol?

> > >>

> > >> This is difficult. It seems that another global variable needs to be introduced.

> > >> yacc code duplication may not be that bad compared with the alternative.

> > >

> > >Since --export-dynamic-symbol is a NOP for -shared and identical with

> > >--dynamic-list otherwise, let's only consider the -shared case:

> >

> > Combined with both points below, --export-dynamic-symbol can be treated

> > as a NOP when -shared is specified.  This is acceptable because (as far

> > as I can tell from my observation) --export-dynamic is a NOP with

> > -shared.

> >

> > >1. Without -Bsymbolic nor --dynamic-list,  --export-dynamic-symbol should

> > >be dropped.

> >

> > Looks good.

> >

> > >2. With -Bsymbolic or --dynamic-list, --export-dynamic-symbol should also

> > >be dropped since --export-dynamic-symbol doesn't change symbol binding.

> >

> > Is the intention that --export-dynamic-symbol should be similar more to

> > --export-dynamic and less to --dynamic-list? I'm fine with the change.

> >

> >

> > If a.list contains { foo; };

> >

> >

> > # all global symbols are exported. foo is symbolic. --export-dynamic is ignored.

> > ld.bfd -shared --dynamic-list=a.list --export-dynamic

> >

> > # all global symbols are exported. foo is symbolic. --export-dynamic-bar is ignored.

> > ld.bfd -shared --dynamic-list=a.list --export-dynamic-symbol=bar

> >

> > # all global symbols are exported.

> > ld.bfd -pie --dynamic-list=a.list --export-dynamic

> >

> > # foo and bar are exported.

> > ld.bfd -pie --dynamic-list=a.list --export-dynamic-symbol=bar

> >

> > >I think we should add a bit field to bfd_elf_version_expr to indicate if symbol

> > >binding should be symbolic (-Bsymbolic) and use lang_append_dynamic_list

> > >for both --dynamic-list and --export-dynamic-symbol.  The only

> > >difference is that

> > >symbols from --export-dynamic-symbol aren't symbolic and can be dropped for

> > >-shared.

> >

> > Like my patch does, we need a separate list for --export-dynamic-symbol.

> > We cannot call lang_append_dynamic_list yet when processing options,

> > because it is unknown whether -shared will occur.

>

> The dynamic list should be processed after all command line options have

> been seen.

>


This is the patch on the top of yours.  But I got

FAIL: Run with libdl2d.so
FAIL: Run with libdl2e.so
FAIL: Run with libdl2f.so
FAIL: Run with libdl2g.so

Please find out why.

-- 
H.J.
From 5288be097ddbf551d0047d9e491d3fff0f5c3e95 Mon Sep 17 00:00:00 2001
From: "H.J. Lu" <hjl.tools@gmail.com>
Date: Wed, 13 May 2020 15:39:12 -0700
Subject: [PATCH] Remove export_dynamic_symbol_list

---
 include/bfdlink.h |  3 +++
 ld/ldgram.y       |  3 ++-
 ld/ldlang.c       | 18 +++++-------------
 ld/ldlang.h       |  2 --
 ld/lexsup.c       | 26 +++++++++++---------------
 5 files changed, 21 insertions(+), 31 deletions(-)

diff --git a/include/bfdlink.h b/include/bfdlink.h
index ec97679e6f..98e7aa5696 100644
--- a/include/bfdlink.h
+++ b/include/bfdlink.h
@@ -920,6 +920,9 @@ struct bfd_elf_version_expr
   unsigned int symver : 1;
   /* Defined by version script.  */
   unsigned int script : 1;
+  /* Set if its references should be bound to the definition within the
+     shared library.  */
+  unsigned int symbolic : 1;
   /* Pattern type.  */
 #define BFD_ELF_VERSION_C_TYPE		1
 #define BFD_ELF_VERSION_CXX_TYPE	2
diff --git a/ld/ldgram.y b/ld/ldgram.y
index 34ff1db63d..ec71bd3212 100644
--- a/ld/ldgram.y
+++ b/ld/ldgram.y
@@ -1342,7 +1342,8 @@ export_dynamic_symbol_list_node:
 export_dynamic_symbol_list_tag:
 		vers_defns ';'
 		{
-		  lang_append_export_dynamic_symbol_list ($1);
+		  $1->symbolic = FALSE;
+		  lang_append_dynamic_list ($1);
 		}
 	;
 
diff --git a/ld/ldlang.c b/ld/ldlang.c
index 1f72630b8f..11aac4f565 100644
--- a/ld/ldlang.c
+++ b/ld/ldlang.c
@@ -119,7 +119,6 @@ lang_statement_list_type file_chain = { NULL, NULL };
 lang_statement_list_type input_file_chain;
 static const char *current_input_file;
 struct bfd_sym_chain entry_symbol = { NULL, NULL };
-struct bfd_elf_version_expr export_dynamic_symbol_list = { NULL };
 const char *entry_section = ".text";
 struct lang_input_statement_flags input_flags;
 bfd_boolean entry_from_cmdline;
@@ -8966,6 +8965,7 @@ lang_new_vers_pattern (struct bfd_elf_version_expr *orig,
   ret->symver = 0;
   ret->script = 0;
   ret->literal = TRUE;
+  ret->symbolic = TRUE;
   ret->pattern = literal_p ? new_name : realsymbol (new_name);
   if (ret->pattern == NULL)
     {
@@ -9039,6 +9039,8 @@ lang_finalize_version_expr_head (struct bfd_elf_version_expr_head *head)
 
   for (e = head->list; e; e = e->next)
     {
+      if (bfd_link_dll (&link_info) && !e->symbolic)
+	continue;
       if (e->literal)
 	count++;
       head->mask |= e->mask;
@@ -9053,6 +9055,8 @@ lang_finalize_version_expr_head (struct bfd_elf_version_expr_head *head)
       for (e = head->list; e; e = next)
 	{
 	  next = e->next;
+	  if (bfd_link_dll (&link_info) && !e->symbolic)
+	    continue;
 	  if (!e->literal)
 	    {
 	      *remaining_loc = e;
@@ -9390,18 +9394,6 @@ lang_append_dynamic_list_cpp_new (void)
   lang_append_dynamic_list (dynamic);
 }
 
-void
-lang_append_export_dynamic_symbol_list (struct bfd_elf_version_expr *dynamic)
-{
-  struct bfd_elf_version_expr *next;
-  for (; dynamic; dynamic = next)
-    {
-      next = dynamic->next;
-      dynamic->next = export_dynamic_symbol_list.next;
-      export_dynamic_symbol_list.next = dynamic;
-    }
-}
-
 /* Scan a space and/or comma separated string of features.  */
 
 void
diff --git a/ld/ldlang.h b/ld/ldlang.h
index 53bc475679..2aa3930f95 100644
--- a/ld/ldlang.h
+++ b/ld/ldlang.h
@@ -506,7 +506,6 @@ extern lang_statement_list_type *stat_ptr;
 extern bfd_boolean delete_output_file_on_failure;
 
 extern struct bfd_sym_chain entry_symbol;
-extern struct bfd_elf_version_expr export_dynamic_symbol_list;
 extern const char *entry_section;
 extern bfd_boolean entry_from_cmdline;
 extern lang_statement_list_type file_chain;
@@ -675,7 +674,6 @@ extern void lang_register_vers_node
 extern void lang_append_dynamic_list (struct bfd_elf_version_expr *);
 extern void lang_append_dynamic_list_cpp_typeinfo (void);
 extern void lang_append_dynamic_list_cpp_new (void);
-extern void lang_append_export_dynamic_symbol_list (struct bfd_elf_version_expr *);
 extern void lang_add_unique
   (const char *);
 extern const char *lang_get_output_target
diff --git a/ld/lexsup.c b/ld/lexsup.c
index c8d033709a..b975aa23a6 100644
--- a/ld/lexsup.c
+++ b/ld/lexsup.c
@@ -1431,12 +1431,15 @@ parse_args (unsigned argc, char **argv)
 	  break;
 	case OPTION_EXPORT_DYNAMIC_SYMBOL:
 	  {
-            struct bfd_elf_version_expr *expr
-                = lang_new_vers_pattern (NULL, xstrdup (optarg), NULL, FALSE);
-            expr->next = export_dynamic_symbol_list.next;
-            export_dynamic_symbol_list.next = expr;
-          }
-	  break;
+	    struct bfd_elf_version_expr *expr
+	      = lang_new_vers_pattern (NULL, xstrdup (optarg), NULL,
+				       FALSE);
+	    expr->symbolic = FALSE;
+	    lang_append_dynamic_list (expr);
+	    if (opt_dynamic_list != dynamic_list_data)
+	      opt_dynamic_list = dynamic_list;
+	  }
+	break;
 	case OPTION_EXPORT_DYNAMIC_SYMBOL_LIST:
 	  {
 	    FILE *hold_script_handle = saved_script_handle;
@@ -1444,6 +1447,8 @@ parse_args (unsigned argc, char **argv)
 	    saved_script_handle = hold_script_handle;
 	    parser_input = input_export_dynamic_symbol_list;
 	    yyparse ();
+	  if (opt_dynamic_list != dynamic_list_data)
+	    opt_dynamic_list = dynamic_list;
 	  }
 	  break;
 	case OPTION_WARN_COMMON:
@@ -1680,15 +1685,6 @@ parse_args (unsigned argc, char **argv)
 	break;
       }
 
-  if (opt_dynamic_list != dynamic_list_unset || !bfd_link_dll (&link_info))
-    {
-      if (export_dynamic_symbol_list.next)
-        lang_append_dynamic_list (export_dynamic_symbol_list.next);
-      if (export_dynamic_symbol_list.next
-          && opt_dynamic_list != dynamic_list_data)
-        opt_dynamic_list = dynamic_list;
-    }
-
   switch (opt_dynamic_list)
     {
     case dynamic_list_unset:
On Wed, May 13, 2020 at 3:41 PM H.J. Lu <hjl.tools@gmail.com> wrote:
>

> On Wed, May 13, 2020 at 8:36 AM H.J. Lu <hjl.tools@gmail.com> wrote:

> >

> > On Wed, May 13, 2020 at 8:24 AM Fangrui Song <maskray@google.com> wrote:

> > >

> > > On 2020-05-13, H.J. Lu wrote:

> > > >On Tue, May 12, 2020 at 9:38 PM Fangrui Song <maskray@google.com> wrote:

> > > >>

> > > >> On 2020-05-11, H.J. Lu wrote:

> > > >> >On Sun, May 10, 2020 at 11:46 PM Fangrui Song <maskray@google.com> wrote:

> > > >> >>

> > > >> >> On 2020-05-08, H.J. Lu wrote:

> > > >> >> >On Fri, May 8, 2020 at 8:12 AM Fangrui Song <maskray@google.com> wrote:

> > > >> >> >>

> > > >> >> >>

> > > >> >> >> On 2020-05-08, H.J. Lu wrote:

> > > >> >> >> >On Fri, May 8, 2020 at 7:54 AM Fangrui Song <maskray@google.com> wrote:

> > > >> >> >> >>

> > > >> >> >> >> On 2020-05-08, H.J. Lu wrote:

> > > >> >> >> >> >On Wed, May 6, 2020 at 11:42 AM Fangrui Song <maskray@google.com> wrote:

> > > >> >> >> >> >>

> > > >> >> >> >> >> On 2020-05-05, H.J. Lu wrote:

> > > >> >> >> >> >> >On Tue, May 5, 2020 at 9:55 AM Fangrui Song <maskray@google.com> wrote:

> > > >> >> >> >> >> >>

> > > >> >> >> >> >> >>

> > > >> >> >> >> >> >> On 2020-05-05, H.J. Lu wrote:

> > > >> >> >> >> >> >> >On Tue, May 5, 2020 at 8:30 AM Fangrui Song <maskray@google.com> wrote:

> > > >> >> >> >> >> >> >>

> > > >> >> >> >> >> >> >> On 2020-05-05, H.J. Lu wrote:

> > > >> >> >> >> >> >> >> >On Mon, May 4, 2020 at 7:10 PM Fangrui Song <maskray@google.com> wrote:

> > > >> >> >> >> >> >> >> >>

> > > >> >> >> >> >> >> >> >> On 2020-05-04, H.J. Lu wrote:

> > > >> >> >> >> >> >> >> >> >On Mon, May 4, 2020 at 10:48 AM Fangrui Song <maskray@google.com> wrote:

> > > >> >> >> >> >> >> >> >> >>

> > > >> >> >> >> >> >> >> >> >> On 2020-05-03, H.J. Lu wrote:

> > > >> >> >> >> >> >> >> >> >> >On Sat, May 2, 2020 at 11:15 PM Fangrui Song via Binutils

> > > >> >> >> >> >> >> >> >> >> ><binutils@sourceware.org> wrote:

> > > >> >> >> >> >> >> >> >> >> >>

> > > >> >> >> >> >> >> >> >> >> >>         PR ld/25910

> > > >> >> >> >> >> >> >> >> >> >>         * ldlang.c (export_dynamic_symbol_list): New.

> > > >> >> >> >> >> >> >> >> >> >>         (ldlang_add_export_dynamic_symbol): New.

> > > >> >> >> >> >> >> >> >> >> >>         (lang_place_export_dynamic_symbols): New.

> > > >> >> >> >> >> >> >> >> >> >>         (lang_process): Handle export_dynamic_symbol_list.

> > > >> >> >> >> >> >> >> >> >> >>         * ldlang.h (ldlang_add_export_dynamic_symbol): New.

> > > >> >> >> >> >> >> >> >> >> >>         * ldlex.h (option_values): Add OPTION_EXPORT_DYNAMIC_SYMBOL.

> > > >> >> >> >> >> >> >> >> >> >>         * lexsup.c (ld_options): Add entry for OPTION_EXPORT_DYNAMIC_SYMBOL.

> > > >> >> >> >> >> >> >> >> >> >>         (parse_args): Handle it.

> > > >> >> >> >> >> >> >> >> >> >>         * ld.texi: Add --export-dynamic-symbol documentation.

> > > >> >> >> >> >> >> >> >> >> >>         * testsuite/ld-undefined/export-dynamic-symbol.exp: Run new test.

> > > >> >> >> >> >> >> >> >> >> >>         * testsuite/ld-undefined/export-dynamic-symbol-1.d: New.

> > > >> >> >> >> >> >> >> >> >> >> ---

> > > >> >> >> >> >> >> >> >> >> >>  ld/ld.texi                                    |  8 +++++

> > > >> >> >> >> >> >> >> >> >> >>  ld/ldlang.c                                   | 26 ++++++++++++++

> > > >> >> >> >> >> >> >> >> >> >>  ld/ldlang.h                                   |  2 ++

> > > >> >> >> >> >> >> >> >> >> >>  ld/ldlex.h                                    |  1 +

> > > >> >> >> >> >> >> >> >> >> >>  ld/lexsup.c                                   |  7 ++++

> > > >> >> >> >> >> >> >> >> >> >>  .../ld-undefined/export-dynamic-symbol-1.d    |  8 +++++

> > > >> >> >> >> >> >> >> >> >> >>  .../ld-undefined/export-dynamic-symbol.exp    | 35 +++++++++++++++++++

> > > >> >> >> >> >> >> >> >> >> >>  7 files changed, 87 insertions(+)

> > > >> >> >> >> >> >> >> >> >> >>  create mode 100644 ld/testsuite/ld-undefined/export-dynamic-symbol-1.d

> > > >> >> >> >> >> >> >> >> >> >>  create mode 100644 ld/testsuite/ld-undefined/export-dynamic-symbol.exp

> > > >> >> >> >> >> >> >> >> >> >>

> > > >> >> >> >> >> >> >> >> >> >> diff --git a/ld/ld.texi b/ld/ld.texi

> > > >> >> >> >> >> >> >> >> >> >> index 4dc78e65fa..b3dc95f314 100644

> > > >> >> >> >> >> >> >> >> >> >> --- a/ld/ld.texi

> > > >> >> >> >> >> >> >> >> >> >> +++ b/ld/ld.texi

> > > >> >> >> >> >> >> >> >> >> >> @@ -569,6 +569,14 @@ Note that this option is specific to ELF targeted ports.  PE targets

> > > >> >> >> >> >> >> >> >> >> >>  support a similar function to export all symbols from a DLL or EXE; see

> > > >> >> >> >> >> >> >> >> >> >>  the description of @samp{--export-all-symbols} below.

> > > >> >> >> >> >> >> >> >> >> >>

> > > >> >> >> >> >> >> >> >> >> >> +@kindex --export-dynamic-symbol=@var{symbol}

> > > >> >> >> >> >> >> >> >> >> >> +@cindex export dynamic symbol

> > > >> >> >> >> >> >> >> >> >> >> +@item --export-dynamic-symbol=@var{symbol}

> > > >> >> >> >> >> >> >> >> >> >> +Specify a symbol that should be added to the dynamic symbol table.

> > > >> >> >> >> >> >> >> >> >> >> +Additionally, force @var{symbol} to be entered in the output file as an

> > > >> >> >> >> >> >> >> >> >> >> +undefined symbol.  Doing this may, for example, trigger linking of additional

> > > >> >> >> >> >> >> >> >> >> >> +modules from archives.

> > > >> >> >> >> >> >> >> >> >> >> +

> > > >> >> >> >> >> >> >> >> >> >>  @ifclear SingleFormat

> > > >> >> >> >> >> >> >> >> >> >>  @cindex big-endian objects

> > > >> >> >> >> >> >> >> >> >> >>  @cindex endianness

> > > >> >> >> >> >> >> >> >> >> >> diff --git a/ld/ldlang.c b/ld/ldlang.c

> > > >> >> >> >> >> >> >> >> >> >> index b2cdb3603a..e7ecdfeaf0 100644

> > > >> >> >> >> >> >> >> >> >> >> --- a/ld/ldlang.c

> > > >> >> >> >> >> >> >> >> >> >> +++ b/ld/ldlang.c

> > > >> >> >> >> >> >> >> >> >> >> @@ -3910,6 +3910,26 @@ lang_place_undefineds (void)

> > > >> >> >> >> >> >> >> >> >> >>      insert_undefined (ptr->name);

> > > >> >> >> >> >> >> >> >> >> >>  }

> > > >> >> >> >> >> >> >> >> >> >>

> > > >> >> >> >> >> >> >> >> >> >> +static struct bfd_sym_chain export_dynamic_symbol_list = { NULL, NULL };

> > > >> >> >> >> >> >> >> >> >> >> +

> > > >> >> >> >> >> >> >> >> >> >> +void

> > > >> >> >> >> >> >> >> >> >> >> +ldlang_add_export_dynamic_symbol (const char *const name)

> > > >> >> >> >> >> >> >> >> >> >> +{

> > > >> >> >> >> >> >> >> >> >> >> +  struct bfd_sym_chain *sym;

> > > >> >> >> >> >> >> >> >> >> >> +  sym = stat_alloc (sizeof (*sym));

> > > >> >> >> >> >> >> >> >> >> >> +  sym->name = xstrdup (name);

> > > >> >> >> >> >> >> >> >> >> >> +  sym->next = export_dynamic_symbol_list.next;

> > > >> >> >> >> >> >> >> >> >> >> +  export_dynamic_symbol_list.next = sym;

> > > >> >> >> >> >> >> >> >> >> >> +}

> > > >> >> >> >> >> >> >> >> >> >> +

> > > >> >> >> >> >> >> >> >> >> >> +static void

> > > >> >> >> >> >> >> >> >> >> >> +lang_place_export_dynamic_symbols (void)

> > > >> >> >> >> >> >> >> >> >> >> +{

> > > >> >> >> >> >> >> >> >> >> >> +  struct bfd_sym_chain *sym;

> > > >> >> >> >> >> >> >> >> >> >> +  for (sym = export_dynamic_symbol_list.next; sym != NULL; sym = sym->next)

> > > >> >> >> >> >> >> >> >> >> >> +    insert_undefined (sym->name);

> > > >> >> >> >> >> >> >> >> >> >> +}

> > > >> >> >> >> >> >> >> >> >> >> +

> > > >> >> >> >> >> >> >> >> >> >>  /* Structure used to build the list of symbols that the user has required

> > > >> >> >> >> >> >> >> >> >> >>     be defined.  */

> > > >> >> >> >> >> >> >> >> >> >>

> > > >> >> >> >> >> >> >> >> >> >> @@ -7795,6 +7815,10 @@ void

> > > >> >> >> >> >> >> >> >> >> >>  lang_process (void)

> > > >> >> >> >> >> >> >> >> >> >>  {

> > > >> >> >> >> >> >> >> >> >> >>    /* Finalize dynamic list.  */

> > > >> >> >> >> >> >> >> >> >> >> +  struct bfd_sym_chain *sym;

> > > >> >> >> >> >> >> >> >> >> >> +  for (sym = export_dynamic_symbol_list.next; sym != NULL; sym = sym->next)

> > > >> >> >> >> >> >> >> >> >> >> +    lang_append_dynamic_list (

> > > >> >> >> >> >> >> >> >> >> >> +        lang_new_vers_pattern (NULL, sym->name, NULL, FALSE));

> > > >> >> >> >> >> >> >> >> >> >>    if (link_info.dynamic_list)

> > > >> >> >> >> >> >> >> >> >> >>      lang_finalize_version_expr_head (&link_info.dynamic_list->head);

> > > >> >> >> >> >> >> >> >> >> >>

> > > >> >> >> >> >> >> >> >> >> >> @@ -7808,6 +7832,8 @@ lang_process (void)

> > > >> >> >> >> >> >> >> >> >> >>

> > > >> >> >> >> >> >> >> >> >> >>    /* Add to the hash table all undefineds on the command line.  */

> > > >> >> >> >> >> >> >> >> >> >>    lang_place_undefineds ();

> > > >> >> >> >> >> >> >> >> >> >> +  /* Add --export-dynamic-symbol symbols to the hash table.  */

> > > >> >> >> >> >> >> >> >> >> >> +  lang_place_export_dynamic_symbols ();

> > > >> >> >> >> >> >> >> >> >> >>

> > > >> >> >> >> >> >> >> >> >> >>    if (!bfd_section_already_linked_table_init ())

> > > >> >> >> >> >> >> >> >> >> >>      einfo (_("%F%P: can not create hash table: %E\n"));

> > > >> >> >> >> >> >> >> >> >> >> diff --git a/ld/ldlang.h b/ld/ldlang.h

> > > >> >> >> >> >> >> >> >> >> >> index 2aa3930f95..8c004b173c 100644

> > > >> >> >> >> >> >> >> >> >> >> --- a/ld/ldlang.h

> > > >> >> >> >> >> >> >> >> >> >> +++ b/ld/ldlang.h

> > > >> >> >> >> >> >> >> >> >> >> @@ -606,6 +606,8 @@ extern lang_output_section_statement_type *next_matching_output_section_statemen

> > > >> >> >> >> >> >> >> >> >> >>    (lang_output_section_statement_type *, int);

> > > >> >> >> >> >> >> >> >> >> >>  extern void ldlang_add_undef

> > > >> >> >> >> >> >> >> >> >> >>    (const char *const, bfd_boolean);

> > > >> >> >> >> >> >> >> >> >> >> +extern void ldlang_add_export_dynamic_symbol

> > > >> >> >> >> >> >> >> >> >> >> +  (const char *const);

> > > >> >> >> >> >> >> >> >> >> >>  extern void ldlang_add_require_defined

> > > >> >> >> >> >> >> >> >> >> >>    (const char *const);

> > > >> >> >> >> >> >> >> >> >> >>  extern void lang_add_output_format

> > > >> >> >> >> >> >> >> >> >> >> diff --git a/ld/ldlex.h b/ld/ldlex.h

> > > >> >> >> >> >> >> >> >> >> >> index 22b928d2d9..70f2da5636 100644

> > > >> >> >> >> >> >> >> >> >> >> --- a/ld/ldlex.h

> > > >> >> >> >> >> >> >> >> >> >> +++ b/ld/ldlex.h

> > > >> >> >> >> >> >> >> >> >> >> @@ -81,6 +81,7 @@ enum option_values

> > > >> >> >> >> >> >> >> >> >> >>    OPTION_DYNAMIC_LIST_CPP_NEW,

> > > >> >> >> >> >> >> >> >> >> >>    OPTION_DYNAMIC_LIST_CPP_TYPEINFO,

> > > >> >> >> >> >> >> >> >> >> >>    OPTION_DYNAMIC_LIST_DATA,

> > > >> >> >> >> >> >> >> >> >> >> +  OPTION_EXPORT_DYNAMIC_SYMBOL,

> > > >> >> >> >> >> >> >> >> >> >>    OPTION_WARN_COMMON,

> > > >> >> >> >> >> >> >> >> >> >>    OPTION_WARN_CONSTRUCTORS,

> > > >> >> >> >> >> >> >> >> >> >>    OPTION_WARN_FATAL,

> > > >> >> >> >> >> >> >> >> >> >> diff --git a/ld/lexsup.c b/ld/lexsup.c

> > > >> >> >> >> >> >> >> >> >> >> index d1955b9afa..0a0c2f2873 100644

> > > >> >> >> >> >> >> >> >> >> >> --- a/ld/lexsup.c

> > > >> >> >> >> >> >> >> >> >> >> +++ b/ld/lexsup.c

> > > >> >> >> >> >> >> >> >> >> >> @@ -504,6 +504,8 @@ static const struct ld_option ld_options[] =

> > > >> >> >> >> >> >> >> >> >> >>      '\0', NULL, N_("Use C++ typeinfo dynamic list"), TWO_DASHES },

> > > >> >> >> >> >> >> >> >> >> >>    { {"dynamic-list", required_argument, NULL, OPTION_DYNAMIC_LIST},

> > > >> >> >> >> >> >> >> >> >> >>      '\0', N_("FILE"), N_("Read dynamic list"), TWO_DASHES },

> > > >> >> >> >> >> >> >> >> >> >> +  { {"export-dynamic-symbol", required_argument, NULL, OPTION_EXPORT_DYNAMIC_SYMBOL},

> > > >> >> >> >> >> >> >> >> >> >> +    '\0', N_("SYMBOL"), N_("Read dynamic list"), TWO_DASHES },

> > > >> >> >> >> >> >> >> >> >> >>    { {"warn-common", no_argument, NULL, OPTION_WARN_COMMON},

> > > >> >> >> >> >> >> >> >> >> >>      '\0', NULL, N_("Warn about duplicate common symbols"), TWO_DASHES },

> > > >> >> >> >> >> >> >> >> >> >>    { {"warn-constructors", no_argument, NULL, OPTION_WARN_CONSTRUCTORS},

> > > >> >> >> >> >> >> >> >> >> >> @@ -1425,6 +1427,11 @@ parse_args (unsigned argc, char **argv)

> > > >> >> >> >> >> >> >> >> >> >>           if (opt_symbolic == symbolic)

> > > >> >> >> >> >> >> >> >> >> >>             opt_symbolic = symbolic_unset;

> > > >> >> >> >> >> >> >> >> >> >>           break;

> > > >> >> >> >> >> >> >> >> >> >> +       case OPTION_EXPORT_DYNAMIC_SYMBOL:

> > > >> >> >> >> >> >> >> >> >> >> +         ldlang_add_export_dynamic_symbol (optarg);

> > > >> >> >> >> >> >> >> >> >> >> +         if (opt_dynamic_list != dynamic_list_data)

> > > >> >> >> >> >> >> >> >> >> >> +           opt_dynamic_list = dynamic_list;

> > > >> >> >> >> >> >> >> >> >> >> +         break;

> > > >> >> >> >> >> >> >> >> >> >>         case OPTION_WARN_COMMON:

> > > >> >> >> >> >> >> >> >> >> >>           config.warn_common = TRUE;

> > > >> >> >> >> >> >> >> >> >> >>           break;

> > > >> >> >> >> >> >> >> >> >> >> diff --git a/ld/testsuite/ld-undefined/export-dynamic-symbol-1.d b/ld/testsuite/ld-undefined/export-dynamic-symbol-1.d

> > > >> >> >> >> >> >> >> >> >> >> new file mode 100644

> > > >> >> >> >> >> >> >> >> >> >> index 0000000000..768bf0abd6

> > > >> >> >> >> >> >> >> >> >> >> --- /dev/null

> > > >> >> >> >> >> >> >> >> >> >> +++ b/ld/testsuite/ld-undefined/export-dynamic-symbol-1.d

> > > >> >> >> >> >> >> >> >> >> >> @@ -0,0 +1,8 @@

> > > >> >> >> >> >> >> >> >> >> >> +#name: --export-dynamic-symbol foo archive

> > > >> >> >> >> >> >> >> >> >> >> +#source: require-defined.s

> > > >> >> >> >> >> >> >> >> >> >> +#ld: -pie --export-dynamic-symbol foo tmpdir/libentry.a

> > > >> >> >> >> >> >> >> >> >> >

> > > >> >> >> >> >> >> >> >> >> >I assume that it supports

> > > >> >> >> >> >> >> >> >> >> >

> > > >> >> >> >> >> >> >> >> >> >$ ld -pie --export-dynamic-symbol foo --export-dynamic-symbol bar ...

> > > >> >> >> >> >> >> >> >> >> >

> > > >> >> >> >> >> >> >> >> >> >Please add another --export-dynamic-symbol to your test.

> > > >> >> >> >> >> >> >> >> >> >

> > > >> >> >> >> >> >> >> >> >> >--

> > > >> >> >> >> >> >> >> >> >> >H.J.

> > > >> >> >> >> >> >> >> >> >>

> > > >> >> >> >> >> >> >> >> >> I face a test difficulty. If I add another `#nm:`, runtest complains:

> > > >> >> >> >> >> >> >> >> >>

> > > >> >> >> >> >> >> >> >> >> % cd Debug/ld

> > > >> >> >> >> >> >> >> >> >> % runtest --tool ld --srcdir ../../ld/testsuite/ export-dynamic-symbol.exp

> > > >> >> >> >> >> >> >> >> >> ...

> > > >> >> >> >> >> >> >> >> >> ERROR: option nm multiply set in ../../ld/testsuite/ld-undefined/export-dynamic-symbol-1.d

> > > >> >> >> >> >> >> >> >> >>

> > > >> >> >> >> >> >> >> >> >> There may also be a problem of symbol table order determinism. I don't

> > > >> >> >> >> >> >> >> >> >> know whether another symbol may be ordered before foo in some ports and

> > > >> >> >> >> >> >> >> >> >> after foo in other ports.

> > > >> >> >> >> >> >> >> >> >>

> > > >> >> >> >> >> >> >> >> >> Honestly, I think for a number of tests, even if they test generic

> > > >> >> >> >> >> >> >> >> >> behavior, it might be fine to restrict them to run on certain hosts,

> > > >> >> >> >> >> >> >> >> >> e.g. Linux x86. What I know about testing is lacking, though, I don't

> > > >> >> >> >> >> >> >> >> >> know what can be tested.

> > > >> >> >> >> >> >> >> >> >>

> > > >> >> >> >> >> >> >> >> >> Ideally `#nm:` should just be free-form shell scripts but unfortunately

> > > >> >> >> >> >> >> >> >> >> it seems to support very limited features (undocumented?)

> > > >> >> >> >> >> >> >> >> >

> > > >> >> >> >> >> >> >> >> >You can't add another #nm.  But you can pass additional options to nm.

> > > >> >> >> >> >> >> >> >> >

> > > >> >> >> >> >> >> >> >> >--

> > > >> >> >> >> >> >> >> >> >H.J.

> > > >> >> >> >> >> >> >> >>

> > > >> >> >> >> >> >> >> >> Attached PATCH v2.

> > > >> >> >> >> >> >> >> >>

> > > >> >> >> >> >> >> >> >> Added export-dynamic-symbol-2.d

> > > >> >> >> >> >> >> >> >

> > > >> >> >> >> >> >> >> >There is

> > > >> >> >> >> >> >> >> >

> > > >> >> >> >> >> >> >> >'--dynamic-list=DYNAMIC-LIST-FILE'

> > > >> >> >> >> >> >> >> >     Specify the name of a dynamic list file to the linker.  This is

> > > >> >> >> >> >> >> >> >     typically used when creating shared libraries to specify a list of

> > > >> >> >> >> >> >> >> >     global symbols whose references shouldn't be bound to the

> > > >> >> >> >> >> >> >> >     definition within the shared library, or creating dynamically

> > > >> >> >> >> >> >> >> >     linked executables to specify a list of symbols which should be

> > > >> >> >> >> >> >> >> >     added to the symbol table in the executable.  This option is only

> > > >> >> >> >> >> >> >> >     meaningful on ELF platforms which support shared libraries.

> > > >> >> >> >> >> >> >> >

> > > >> >> >> >> >> >> >> >The new --export-dynamic-symbol option puts it on command-line

> > > >> >> >> >> >> >> >> >and implicitly adds -u.  This makes the new option different from

> > > >> >> >> >> >> >> >> >--dynamic-list.  I don't think -u should be added implicitly.  If needed,

> > > >> >> >> >> >> >> >> >you should add another option to add -u for all symbols on dynamic

> > > >> >> >> >> >> >> >> >list.

> > > >> >> >> >> >> >> >> >

> > > >> >> >> >> >> >> >> >--

> > > >> >> >> >> >> >> >> >H.J.

> > > >> >> >> >> >> >> >>

> > > >> >> >> >> >> >> >> I would also hope gold did not add -u. I don't particularly like it (see

> > > >> >> >> >> >> >> >> also https://reviews.llvm.org/D43103)

> > > >> >> >> >> >> >> >

> > > >> >> >> >> >> >> >Please drop implicit -u.

> > > >> >> >> >> >> >>

> > > >> >> >> >> >> >> Done. Attached PATCH v3.

> > > >> >> >> >> >> >> Improved tests to check a glob pattern and multiple --export-dynamic-symbol.

> > > >> >> >> >> >> >>

> > > >> >> >> >> >> >> Moved ld-undefined/ to ld-dynamic/ since the feature is decoupled from -u now.

> > > >> >> >> >> >> >>

> > > >> >> >> >> >> >> >> If you think we can correct this, I think it should be fine.

> > > >> >> >> >> >> >> >

> > > >> >> >> >> >> >> >Please open a gold bug for this.

> > > >> >> >> >> >> >> >

> > > >> >> >> >> >> >> >Thanks.

> > > >> >> >> >> >> >> >

> > > >> >> >> >> >> >> >--

> > > >> >> >> >> >> >> >H.J.

> > > >> >> >> >> >> >>

> > > >> >> >> >> >> >> Filed https://sourceware.org/bugzilla/show_bug.cgi?id=25925 (--export-dynamic-symbol should drop implicit -u)

> > > >> >> >> >> >> >>

> > > >> >> >> >> >> >>

> > > >> >> >> >> >> >> I may have to migrate some internal projects if they rely on the

> > > >> >> >> >> >> >> --export-dynamic-symbol semantics, but hopefully there will not be much

> > > >> >> >> >> >> >> work. I am glad that --export-dynamic-symbol semantic will be orthogonal!

> > > >> >> >> >> >> >

> > > >> >> >> >> >> >+ case OPTION_EXPORT_DYNAMIC_SYMBOL:

> > > >> >> >> >> >> >+   ldlang_add_export_dynamic_symbol (optarg);

> > > >> >> >> >> >> >

> > > >> >> >> >> >> >Can you simply call

> > > >> >> >> >> >> >

> > > >> >> >> >> >> >lang_append_dynamic_list (lang_new_vers_pattern (NULL, optarg, NULL, FALSE));

> > > >> >> >> >> >> >

> > > >> >> >> >> >> >here?

> > > >> >> >> >> >> >

> > > >> >> >> >> >> >--

> > > >> >> >> >> >> >H.J.

> > > >> >> >> >> >>

> > > >> >> >> >> >> Attached PATCH v4, which also handles -shared.  The previous patches do not handle -shared.

> > > >> >> >> >> >> Added two tests to ld-elf/shared.exp

> > > >> >> >> >> >>

> > > >> >> >> >> >> The updated semantics:

> > > >> >> >> >> >>

> > > >> >> >> >> >> + @kindex --export-dynamic-symbol=@var{glob}

> > > >> >> >> >> >> + @cindex export dynamic symbol

> > > >> >> >> >> >> + @item --export-dynamic-symbol=@var{glob}

> > > >> >> >> >> >> + When creating a dynamically linked executable, symbols matching

> > > >> >> >> >> >> + @var{glob} will be added to the dynamic symbol table. When creating a

> > > >> >> >> >> >> + shared library, references to symbols matching @var{glob} will not be

> > > >> >> >> >> >> + bound to the definitions within the shared library. This option is a

> > > >> >> >> >> >> + no-op when creating a shared library and @samp{--dynamic-list} is not

> > > >> >> >> >> >> + specified. This option is only meaningful on ELF platforms which

> > > >> >> >> >> >> + support shared libraries.

> > > >> >> >> >> >>

> > > >> >> >> >> >> i.e. --export-dynamic-symbol is like addition to --dynamic-list,

> > > >> >> >> >> >> except: -shared --export-dynamic-symbol without --dynamic-list will not

> > > >> >> >> >> >> act as -Bsymbolic.

> > > >> >> >> >> >>

> > > >> >> >> >> >> In the option processing loop, we cannot call lang_append_dynamic_list

> > > >> >> >> >> >> because when -shared is specified but --dynamic-list is not specified,

> > > >> >> >> >> >> --export-dynamic-symbol should be a no-op.

> > > >> >> >> >> >

> > > >> >> >> >> >--dynamic-list implies -Bsymbolic.  If we add --export-dynamic-symbol,

> > > >> >> >> >> >we should also add --export-dynamic-symbol-list, which is similar to

> > > >> >> >> >> >--dynamic-list, but without -Bsymbolic.

> > > >> >> >> >>

> > > >> >> >> >> --export-dynamic-symbol-list a.list  where a.list is a plain text like:

> > > >> >> >> >> foo

> > > >> >> >> >> bar

> > > >> >> >> >> ?

> > > >> >> >> >

> > > >> >> >> >I prefer to use the same format as --dynamic-list.

> > > >> >> >> >

> > > >> >> >> >> The feature can be provided by a response file @a.rsp

> > > >> >> >> >> --export-dynamic-symbol foo

> > > >> >> >> >> --export-dynamic-symbol bar

> > > >> >> >>

> > > >> >> >> Adding --export-dynamic-symbol-list is fine. We can implement that separately.

> > > >> >> >

> > > >> >> >Since implement --export-dynamic-symbol-list at the same time may impact how

> > > >> >> >--export-dynamic-symbol is implemented, they should be added together.

> > > >> >>

> > > >> >> OK. Added --export-dynamic-symbol-list as well.

> > > >> >>

> > > >> >> Retitled.

> > > >> >

> > > >> >A couple comments:

> > > >>

> > > >> Thanks for the review!

> > > >>

> > > >> >1. Please add an entry to ld/NEWS.

> > > >> >2. Please a note to ld.texi for the difference between --dynamic-list and

> > > >> >--export-dynamic-symbol.

> > > >>

> > > >> >3.  What happens when there are both --dynamic-list and and

> > > >> >--export-dynamic-symbol, with and without -Bsymbolic?

> > > >>

> > > >> --export-symbol-symbol adds additional entries to --dynamic-list.

> > > >

> > > >I don't think so.  See below.

> > > >

> > > >>

> > > >> I'd expect --dynamic-list to override -Bsymbolic (i.e. --dynamic-list is a

> > > >> refined -Bsymbolic).

> > > >> gold and

> > > >> LLD (https://github.com/llvm/llvm-project/blob/master/lld/ELF/Symbols.cpp#L368)

> > > >> behave this way.

> > > >> GNU ld seems to make every symbol symbolic.

> > > >

> > > >Ld manual says

> > > >

> > > >'--dynamic-list=DYNAMIC-LIST-FILE'

> > > >     Specify the name of a dynamic list file to the linker.  This is

> > > >     typically used when creating shared libraries to specify a list of

> > > >     global symbols whose references shouldn't be bound to the

> > > >     definition within the shared library, or creating dynamically

> > > >     linked executables to specify a list of symbols which should be

> > > >     added to the symbol table in the executable.  This option is only

> > > >     meaningful on ELF platforms which support shared libraries.

> > > >

> > > >     The format of the dynamic list is the same as the version node

> > > >     without scope and node name.  See *note VERSION:: for more

> > > >     information.

> > > >

> > > >When producing a shared library,  --dynamic-list implies -Bsymbolic

> > > >with exception for the symbols on the dynamic list.

> > >

> > > This is my understanding. By using `implies`, do you mean -Bsymbolic is

> > > ignored (gold and LLD's interpretation)? If so, GNU ld should be fixed.

> >

> > --dynamic-list should be the same as -Bsymbolic --dynamic-list.

> >

> > > I don't think any project is using the combination, so changing the

> > > semantics should not be a problem.

> > >

> > > >> This can be tested with:

> > > >>

> > > >> .globl main, foo, bar

> > > >> main: call foo

> > > >> foo: call bar

> > > >> bar: ret

> > > >>

> > > >> // a.list

> > > >> { foo; };

> > > >>

> > > >> It is also fine if you think -Bsymbolic should override --dynamic-list.

> > > >> (Please add a test for that so that I know how to test --export-dynamic-list)

> > > >> We can then file a gold bug.

> > > >>

> > > >> >4.  Can you reuse lang_append_dynamic_list to implement

> > > >> >--export-dynamic-symbol?

> > > >>

> > > >> This is difficult. It seems that another global variable needs to be introduced.

> > > >> yacc code duplication may not be that bad compared with the alternative.

> > > >

> > > >Since --export-dynamic-symbol is a NOP for -shared and identical with

> > > >--dynamic-list otherwise, let's only consider the -shared case:

> > >

> > > Combined with both points below, --export-dynamic-symbol can be treated

> > > as a NOP when -shared is specified.  This is acceptable because (as far

> > > as I can tell from my observation) --export-dynamic is a NOP with

> > > -shared.

> > >

> > > >1. Without -Bsymbolic nor --dynamic-list,  --export-dynamic-symbol should

> > > >be dropped.

> > >

> > > Looks good.

> > >

> > > >2. With -Bsymbolic or --dynamic-list, --export-dynamic-symbol should also

> > > >be dropped since --export-dynamic-symbol doesn't change symbol binding.

> > >

> > > Is the intention that --export-dynamic-symbol should be similar more to

> > > --export-dynamic and less to --dynamic-list? I'm fine with the change.

> > >

> > >

> > > If a.list contains { foo; };

> > >

> > >

> > > # all global symbols are exported. foo is symbolic. --export-dynamic is ignored.

> > > ld.bfd -shared --dynamic-list=a.list --export-dynamic

> > >

> > > # all global symbols are exported. foo is symbolic. --export-dynamic-bar is ignored.

> > > ld.bfd -shared --dynamic-list=a.list --export-dynamic-symbol=bar

> > >

> > > # all global symbols are exported.

> > > ld.bfd -pie --dynamic-list=a.list --export-dynamic

> > >

> > > # foo and bar are exported.

> > > ld.bfd -pie --dynamic-list=a.list --export-dynamic-symbol=bar

> > >

> > > >I think we should add a bit field to bfd_elf_version_expr to indicate if symbol

> > > >binding should be symbolic (-Bsymbolic) and use lang_append_dynamic_list

> > > >for both --dynamic-list and --export-dynamic-symbol.  The only

> > > >difference is that

> > > >symbols from --export-dynamic-symbol aren't symbolic and can be dropped for

> > > >-shared.

> > >

> > > Like my patch does, we need a separate list for --export-dynamic-symbol.

> > > We cannot call lang_append_dynamic_list yet when processing options,

> > > because it is unknown whether -shared will occur.

> >

> > The dynamic list should be processed after all command line options have

> > been seen.

> >

>

> This is the patch on the top of yours.  But I got

>

> FAIL: Run with libdl2d.so

> FAIL: Run with libdl2e.so

> FAIL: Run with libdl2f.so

> FAIL: Run with libdl2g.so

>

> Please find out why.

>


This only gets

FAIL: Run with libdl2e.so
FAIL: Run with libdl2g.so

I think these tests are wrong since --export-dynamic-symbol shouldn't change
symbol binding in the shared library.

-- 
H.J.
From 1df6224f16c7527cc9b8066c8a35fd8e96d91f92 Mon Sep 17 00:00:00 2001
From: "H.J. Lu" <hjl.tools@gmail.com>
Date: Wed, 13 May 2020 15:39:12 -0700
Subject: [PATCH] Remove export_dynamic_symbol_list

---
 include/bfdlink.h |  3 +++
 ld/ldgram.y       |  3 ++-
 ld/ldlang.c       | 28 ++++++++++++++--------------
 ld/ldlang.h       |  2 --
 ld/lexsup.c       | 31 ++++++++++++++++---------------
 5 files changed, 35 insertions(+), 32 deletions(-)

diff --git a/include/bfdlink.h b/include/bfdlink.h
index ec97679e6f..98e7aa5696 100644
--- a/include/bfdlink.h
+++ b/include/bfdlink.h
@@ -920,6 +920,9 @@ struct bfd_elf_version_expr
   unsigned int symver : 1;
   /* Defined by version script.  */
   unsigned int script : 1;
+  /* Set if its references should be bound to the definition within the
+     shared library.  */
+  unsigned int symbolic : 1;
   /* Pattern type.  */
 #define BFD_ELF_VERSION_C_TYPE		1
 #define BFD_ELF_VERSION_CXX_TYPE	2
diff --git a/ld/ldgram.y b/ld/ldgram.y
index 34ff1db63d..ec71bd3212 100644
--- a/ld/ldgram.y
+++ b/ld/ldgram.y
@@ -1342,7 +1342,8 @@ export_dynamic_symbol_list_node:
 export_dynamic_symbol_list_tag:
 		vers_defns ';'
 		{
-		  lang_append_export_dynamic_symbol_list ($1);
+		  $1->symbolic = FALSE;
+		  lang_append_dynamic_list ($1);
 		}
 	;
 
diff --git a/ld/ldlang.c b/ld/ldlang.c
index 1f72630b8f..535c549118 100644
--- a/ld/ldlang.c
+++ b/ld/ldlang.c
@@ -119,7 +119,6 @@ lang_statement_list_type file_chain = { NULL, NULL };
 lang_statement_list_type input_file_chain;
 static const char *current_input_file;
 struct bfd_sym_chain entry_symbol = { NULL, NULL };
-struct bfd_elf_version_expr export_dynamic_symbol_list = { NULL };
 const char *entry_section = ".text";
 struct lang_input_statement_flags input_flags;
 bfd_boolean entry_from_cmdline;
@@ -8966,6 +8965,7 @@ lang_new_vers_pattern (struct bfd_elf_version_expr *orig,
   ret->symver = 0;
   ret->script = 0;
   ret->literal = TRUE;
+  ret->symbolic = TRUE;
   ret->pattern = literal_p ? new_name : realsymbol (new_name);
   if (ret->pattern == NULL)
     {
@@ -9036,12 +9036,24 @@ lang_finalize_version_expr_head (struct bfd_elf_version_expr_head *head)
   size_t count = 0;
   struct bfd_elf_version_expr *e, *next;
   struct bfd_elf_version_expr **list_loc, **remaining_loc;
+  struct bfd_elf_version_expr **ep;
 
-  for (e = head->list; e; e = e->next)
+  ep = &head->list;
+  for (e = head->list; e; e = next)
     {
+      next = e->next;
+      /* When buidling shared library, remove the symbol from
+         --export-dynamic-symbol and --export-dynamic-symbol-list.  */
+      if (bfd_link_dll (&link_info) && !e->symbolic)
+	{
+	  *ep = e->next;
+	  free (e);
+	  continue;
+	}
       if (e->literal)
 	count++;
       head->mask |= e->mask;
+      ep = &e->next;
     }
 
   if (count)
@@ -9390,18 +9402,6 @@ lang_append_dynamic_list_cpp_new (void)
   lang_append_dynamic_list (dynamic);
 }
 
-void
-lang_append_export_dynamic_symbol_list (struct bfd_elf_version_expr *dynamic)
-{
-  struct bfd_elf_version_expr *next;
-  for (; dynamic; dynamic = next)
-    {
-      next = dynamic->next;
-      dynamic->next = export_dynamic_symbol_list.next;
-      export_dynamic_symbol_list.next = dynamic;
-    }
-}
-
 /* Scan a space and/or comma separated string of features.  */
 
 void
diff --git a/ld/ldlang.h b/ld/ldlang.h
index 53bc475679..2aa3930f95 100644
--- a/ld/ldlang.h
+++ b/ld/ldlang.h
@@ -506,7 +506,6 @@ extern lang_statement_list_type *stat_ptr;
 extern bfd_boolean delete_output_file_on_failure;
 
 extern struct bfd_sym_chain entry_symbol;
-extern struct bfd_elf_version_expr export_dynamic_symbol_list;
 extern const char *entry_section;
 extern bfd_boolean entry_from_cmdline;
 extern lang_statement_list_type file_chain;
@@ -675,7 +674,6 @@ extern void lang_register_vers_node
 extern void lang_append_dynamic_list (struct bfd_elf_version_expr *);
 extern void lang_append_dynamic_list_cpp_typeinfo (void);
 extern void lang_append_dynamic_list_cpp_new (void);
-extern void lang_append_export_dynamic_symbol_list (struct bfd_elf_version_expr *);
 extern void lang_add_unique
   (const char *);
 extern const char *lang_get_output_target
diff --git a/ld/lexsup.c b/ld/lexsup.c
index c8d033709a..a26f70f947 100644
--- a/ld/lexsup.c
+++ b/ld/lexsup.c
@@ -583,6 +583,7 @@ parse_args (unsigned argc, char **argv)
   {
     dynamic_list_unset = 0,
     dynamic_list_data,
+    dynamic_list_export,
     dynamic_list
   } opt_dynamic_list = dynamic_list_unset;
 
@@ -1431,12 +1432,15 @@ parse_args (unsigned argc, char **argv)
 	  break;
 	case OPTION_EXPORT_DYNAMIC_SYMBOL:
 	  {
-            struct bfd_elf_version_expr *expr
-                = lang_new_vers_pattern (NULL, xstrdup (optarg), NULL, FALSE);
-            expr->next = export_dynamic_symbol_list.next;
-            export_dynamic_symbol_list.next = expr;
-          }
-	  break;
+	    struct bfd_elf_version_expr *expr
+	      = lang_new_vers_pattern (NULL, xstrdup (optarg), NULL,
+				       FALSE);
+	    expr->symbolic = FALSE;
+	    lang_append_dynamic_list (expr);
+	    if (opt_dynamic_list == dynamic_list_unset)
+	      opt_dynamic_list = dynamic_list_export;
+	  }
+	break;
 	case OPTION_EXPORT_DYNAMIC_SYMBOL_LIST:
 	  {
 	    FILE *hold_script_handle = saved_script_handle;
@@ -1444,6 +1448,8 @@ parse_args (unsigned argc, char **argv)
 	    saved_script_handle = hold_script_handle;
 	    parser_input = input_export_dynamic_symbol_list;
 	    yyparse ();
+	    if (opt_dynamic_list == dynamic_list_unset)
+	      opt_dynamic_list = dynamic_list_export;
 	  }
 	  break;
 	case OPTION_WARN_COMMON:
@@ -1680,15 +1686,6 @@ parse_args (unsigned argc, char **argv)
 	break;
       }
 
-  if (opt_dynamic_list != dynamic_list_unset || !bfd_link_dll (&link_info))
-    {
-      if (export_dynamic_symbol_list.next)
-        lang_append_dynamic_list (export_dynamic_symbol_list.next);
-      if (export_dynamic_symbol_list.next
-          && opt_dynamic_list != dynamic_list_data)
-        opt_dynamic_list = dynamic_list;
-    }
-
   switch (opt_dynamic_list)
     {
     case dynamic_list_unset:
@@ -1699,6 +1696,10 @@ parse_args (unsigned argc, char **argv)
     case dynamic_list:
       link_info.dynamic = TRUE;
       break;
+    case dynamic_list_export:
+      if (bfd_link_executable (&link_info))
+	link_info.dynamic = TRUE;
+      break;
     }
 
   if (!bfd_link_dll (&link_info))
On 2020-05-13, H.J. Lu wrote:
>On Wed, May 13, 2020 at 3:41 PM H.J. Lu <hjl.tools@gmail.com> wrote:

>>

>> On Wed, May 13, 2020 at 8:36 AM H.J. Lu <hjl.tools@gmail.com> wrote:

>> >

>> > On Wed, May 13, 2020 at 8:24 AM Fangrui Song <maskray@google.com> wrote:

>> > >

>> > > On 2020-05-13, H.J. Lu wrote:

>> > > >On Tue, May 12, 2020 at 9:38 PM Fangrui Song <maskray@google.com> wrote:

>> > > >>

>> > > >> On 2020-05-11, H.J. Lu wrote:

>> > > >> >On Sun, May 10, 2020 at 11:46 PM Fangrui Song <maskray@google.com> wrote:

>> > > >> >>

>> > > >> >> On 2020-05-08, H.J. Lu wrote:

>> > > >> >> >On Fri, May 8, 2020 at 8:12 AM Fangrui Song <maskray@google.com> wrote:

>> > > >> >> >>

>> > > >> >> >>

>> > > >> >> >> On 2020-05-08, H.J. Lu wrote:

>> > > >> >> >> >On Fri, May 8, 2020 at 7:54 AM Fangrui Song <maskray@google.com> wrote:

>> > > >> >> >> >>

>> > > >> >> >> >> On 2020-05-08, H.J. Lu wrote:

>> > > >> >> >> >> >On Wed, May 6, 2020 at 11:42 AM Fangrui Song <maskray@google.com> wrote:

>> > > >> >> >> >> >>

>> > > >> >> >> >> >> On 2020-05-05, H.J. Lu wrote:

>> > > >> >> >> >> >> >On Tue, May 5, 2020 at 9:55 AM Fangrui Song <maskray@google.com> wrote:

>> > > >> >> >> >> >> >>

>> > > >> >> >> >> >> >>

>> > > >> >> >> >> >> >> On 2020-05-05, H.J. Lu wrote:

>> > > >> >> >> >> >> >> >On Tue, May 5, 2020 at 8:30 AM Fangrui Song <maskray@google.com> wrote:

>> > > >> >> >> >> >> >> >>

>> > > >> >> >> >> >> >> >> On 2020-05-05, H.J. Lu wrote:

>> > > >> >> >> >> >> >> >> >On Mon, May 4, 2020 at 7:10 PM Fangrui Song <maskray@google.com> wrote:

>> > > >> >> >> >> >> >> >> >>

>> > > >> >> >> >> >> >> >> >> On 2020-05-04, H.J. Lu wrote:

>> > > >> >> >> >> >> >> >> >> >On Mon, May 4, 2020 at 10:48 AM Fangrui Song <maskray@google.com> wrote:

>> > > >> >> >> >> >> >> >> >> >>

>> > > >> >> >> >> >> >> >> >> >> On 2020-05-03, H.J. Lu wrote:

>> > > >> >> >> >> >> >> >> >> >> >On Sat, May 2, 2020 at 11:15 PM Fangrui Song via Binutils

>> > > >> >> >> >> >> >> >> >> >> ><binutils@sourceware.org> wrote:

>> > > >> >> >> >> >> >> >> >> >> >>

>> > > >> >> >> >> >> >> >> >> >> >>         PR ld/25910

>> > > >> >> >> >> >> >> >> >> >> >>         * ldlang.c (export_dynamic_symbol_list): New.

>> > > >> >> >> >> >> >> >> >> >> >>         (ldlang_add_export_dynamic_symbol): New.

>> > > >> >> >> >> >> >> >> >> >> >>         (lang_place_export_dynamic_symbols): New.

>> > > >> >> >> >> >> >> >> >> >> >>         (lang_process): Handle export_dynamic_symbol_list.

>> > > >> >> >> >> >> >> >> >> >> >>         * ldlang.h (ldlang_add_export_dynamic_symbol): New.

>> > > >> >> >> >> >> >> >> >> >> >>         * ldlex.h (option_values): Add OPTION_EXPORT_DYNAMIC_SYMBOL.

>> > > >> >> >> >> >> >> >> >> >> >>         * lexsup.c (ld_options): Add entry for OPTION_EXPORT_DYNAMIC_SYMBOL.

>> > > >> >> >> >> >> >> >> >> >> >>         (parse_args): Handle it.

>> > > >> >> >> >> >> >> >> >> >> >>         * ld.texi: Add --export-dynamic-symbol documentation.

>> > > >> >> >> >> >> >> >> >> >> >>         * testsuite/ld-undefined/export-dynamic-symbol.exp: Run new test.

>> > > >> >> >> >> >> >> >> >> >> >>         * testsuite/ld-undefined/export-dynamic-symbol-1.d: New.

>> > > >> >> >> >> >> >> >> >> >> >> ---

>> > > >> >> >> >> >> >> >> >> >> >>  ld/ld.texi                                    |  8 +++++

>> > > >> >> >> >> >> >> >> >> >> >>  ld/ldlang.c                                   | 26 ++++++++++++++

>> > > >> >> >> >> >> >> >> >> >> >>  ld/ldlang.h                                   |  2 ++

>> > > >> >> >> >> >> >> >> >> >> >>  ld/ldlex.h                                    |  1 +

>> > > >> >> >> >> >> >> >> >> >> >>  ld/lexsup.c                                   |  7 ++++

>> > > >> >> >> >> >> >> >> >> >> >>  .../ld-undefined/export-dynamic-symbol-1.d    |  8 +++++

>> > > >> >> >> >> >> >> >> >> >> >>  .../ld-undefined/export-dynamic-symbol.exp    | 35 +++++++++++++++++++

>> > > >> >> >> >> >> >> >> >> >> >>  7 files changed, 87 insertions(+)

>> > > >> >> >> >> >> >> >> >> >> >>  create mode 100644 ld/testsuite/ld-undefined/export-dynamic-symbol-1.d

>> > > >> >> >> >> >> >> >> >> >> >>  create mode 100644 ld/testsuite/ld-undefined/export-dynamic-symbol.exp

>> > > >> >> >> >> >> >> >> >> >> >>

>> > > >> >> >> >> >> >> >> >> >> >> diff --git a/ld/ld.texi b/ld/ld.texi

>> > > >> >> >> >> >> >> >> >> >> >> index 4dc78e65fa..b3dc95f314 100644

>> > > >> >> >> >> >> >> >> >> >> >> --- a/ld/ld.texi

>> > > >> >> >> >> >> >> >> >> >> >> +++ b/ld/ld.texi

>> > > >> >> >> >> >> >> >> >> >> >> @@ -569,6 +569,14 @@ Note that this option is specific to ELF targeted ports.  PE targets

>> > > >> >> >> >> >> >> >> >> >> >>  support a similar function to export all symbols from a DLL or EXE; see

>> > > >> >> >> >> >> >> >> >> >> >>  the description of @samp{--export-all-symbols} below.

>> > > >> >> >> >> >> >> >> >> >> >>

>> > > >> >> >> >> >> >> >> >> >> >> +@kindex --export-dynamic-symbol=@var{symbol}

>> > > >> >> >> >> >> >> >> >> >> >> +@cindex export dynamic symbol

>> > > >> >> >> >> >> >> >> >> >> >> +@item --export-dynamic-symbol=@var{symbol}

>> > > >> >> >> >> >> >> >> >> >> >> +Specify a symbol that should be added to the dynamic symbol table.

>> > > >> >> >> >> >> >> >> >> >> >> +Additionally, force @var{symbol} to be entered in the output file as an

>> > > >> >> >> >> >> >> >> >> >> >> +undefined symbol.  Doing this may, for example, trigger linking of additional

>> > > >> >> >> >> >> >> >> >> >> >> +modules from archives.

>> > > >> >> >> >> >> >> >> >> >> >> +

>> > > >> >> >> >> >> >> >> >> >> >>  @ifclear SingleFormat

>> > > >> >> >> >> >> >> >> >> >> >>  @cindex big-endian objects

>> > > >> >> >> >> >> >> >> >> >> >>  @cindex endianness

>> > > >> >> >> >> >> >> >> >> >> >> diff --git a/ld/ldlang.c b/ld/ldlang.c

>> > > >> >> >> >> >> >> >> >> >> >> index b2cdb3603a..e7ecdfeaf0 100644

>> > > >> >> >> >> >> >> >> >> >> >> --- a/ld/ldlang.c

>> > > >> >> >> >> >> >> >> >> >> >> +++ b/ld/ldlang.c

>> > > >> >> >> >> >> >> >> >> >> >> @@ -3910,6 +3910,26 @@ lang_place_undefineds (void)

>> > > >> >> >> >> >> >> >> >> >> >>      insert_undefined (ptr->name);

>> > > >> >> >> >> >> >> >> >> >> >>  }

>> > > >> >> >> >> >> >> >> >> >> >>

>> > > >> >> >> >> >> >> >> >> >> >> +static struct bfd_sym_chain export_dynamic_symbol_list = { NULL, NULL };

>> > > >> >> >> >> >> >> >> >> >> >> +

>> > > >> >> >> >> >> >> >> >> >> >> +void

>> > > >> >> >> >> >> >> >> >> >> >> +ldlang_add_export_dynamic_symbol (const char *const name)

>> > > >> >> >> >> >> >> >> >> >> >> +{

>> > > >> >> >> >> >> >> >> >> >> >> +  struct bfd_sym_chain *sym;

>> > > >> >> >> >> >> >> >> >> >> >> +  sym = stat_alloc (sizeof (*sym));

>> > > >> >> >> >> >> >> >> >> >> >> +  sym->name = xstrdup (name);

>> > > >> >> >> >> >> >> >> >> >> >> +  sym->next = export_dynamic_symbol_list.next;

>> > > >> >> >> >> >> >> >> >> >> >> +  export_dynamic_symbol_list.next = sym;

>> > > >> >> >> >> >> >> >> >> >> >> +}

>> > > >> >> >> >> >> >> >> >> >> >> +

>> > > >> >> >> >> >> >> >> >> >> >> +static void

>> > > >> >> >> >> >> >> >> >> >> >> +lang_place_export_dynamic_symbols (void)

>> > > >> >> >> >> >> >> >> >> >> >> +{

>> > > >> >> >> >> >> >> >> >> >> >> +  struct bfd_sym_chain *sym;

>> > > >> >> >> >> >> >> >> >> >> >> +  for (sym = export_dynamic_symbol_list.next; sym != NULL; sym = sym->next)

>> > > >> >> >> >> >> >> >> >> >> >> +    insert_undefined (sym->name);

>> > > >> >> >> >> >> >> >> >> >> >> +}

>> > > >> >> >> >> >> >> >> >> >> >> +

>> > > >> >> >> >> >> >> >> >> >> >>  /* Structure used to build the list of symbols that the user has required

>> > > >> >> >> >> >> >> >> >> >> >>     be defined.  */

>> > > >> >> >> >> >> >> >> >> >> >>

>> > > >> >> >> >> >> >> >> >> >> >> @@ -7795,6 +7815,10 @@ void

>> > > >> >> >> >> >> >> >> >> >> >>  lang_process (void)

>> > > >> >> >> >> >> >> >> >> >> >>  {

>> > > >> >> >> >> >> >> >> >> >> >>    /* Finalize dynamic list.  */

>> > > >> >> >> >> >> >> >> >> >> >> +  struct bfd_sym_chain *sym;

>> > > >> >> >> >> >> >> >> >> >> >> +  for (sym = export_dynamic_symbol_list.next; sym != NULL; sym = sym->next)

>> > > >> >> >> >> >> >> >> >> >> >> +    lang_append_dynamic_list (

>> > > >> >> >> >> >> >> >> >> >> >> +        lang_new_vers_pattern (NULL, sym->name, NULL, FALSE));

>> > > >> >> >> >> >> >> >> >> >> >>    if (link_info.dynamic_list)

>> > > >> >> >> >> >> >> >> >> >> >>      lang_finalize_version_expr_head (&link_info.dynamic_list->head);

>> > > >> >> >> >> >> >> >> >> >> >>

>> > > >> >> >> >> >> >> >> >> >> >> @@ -7808,6 +7832,8 @@ lang_process (void)

>> > > >> >> >> >> >> >> >> >> >> >>

>> > > >> >> >> >> >> >> >> >> >> >>    /* Add to the hash table all undefineds on the command line.  */

>> > > >> >> >> >> >> >> >> >> >> >>    lang_place_undefineds ();

>> > > >> >> >> >> >> >> >> >> >> >> +  /* Add --export-dynamic-symbol symbols to the hash table.  */

>> > > >> >> >> >> >> >> >> >> >> >> +  lang_place_export_dynamic_symbols ();

>> > > >> >> >> >> >> >> >> >> >> >>

>> > > >> >> >> >> >> >> >> >> >> >>    if (!bfd_section_already_linked_table_init ())

>> > > >> >> >> >> >> >> >> >> >> >>      einfo (_("%F%P: can not create hash table: %E\n"));

>> > > >> >> >> >> >> >> >> >> >> >> diff --git a/ld/ldlang.h b/ld/ldlang.h

>> > > >> >> >> >> >> >> >> >> >> >> index 2aa3930f95..8c004b173c 100644

>> > > >> >> >> >> >> >> >> >> >> >> --- a/ld/ldlang.h

>> > > >> >> >> >> >> >> >> >> >> >> +++ b/ld/ldlang.h

>> > > >> >> >> >> >> >> >> >> >> >> @@ -606,6 +606,8 @@ extern lang_output_section_statement_type *next_matching_output_section_statemen

>> > > >> >> >> >> >> >> >> >> >> >>    (lang_output_section_statement_type *, int);

>> > > >> >> >> >> >> >> >> >> >> >>  extern void ldlang_add_undef

>> > > >> >> >> >> >> >> >> >> >> >>    (const char *const, bfd_boolean);

>> > > >> >> >> >> >> >> >> >> >> >> +extern void ldlang_add_export_dynamic_symbol

>> > > >> >> >> >> >> >> >> >> >> >> +  (const char *const);

>> > > >> >> >> >> >> >> >> >> >> >>  extern void ldlang_add_require_defined

>> > > >> >> >> >> >> >> >> >> >> >>    (const char *const);

>> > > >> >> >> >> >> >> >> >> >> >>  extern void lang_add_output_format

>> > > >> >> >> >> >> >> >> >> >> >> diff --git a/ld/ldlex.h b/ld/ldlex.h

>> > > >> >> >> >> >> >> >> >> >> >> index 22b928d2d9..70f2da5636 100644

>> > > >> >> >> >> >> >> >> >> >> >> --- a/ld/ldlex.h

>> > > >> >> >> >> >> >> >> >> >> >> +++ b/ld/ldlex.h

>> > > >> >> >> >> >> >> >> >> >> >> @@ -81,6 +81,7 @@ enum option_values

>> > > >> >> >> >> >> >> >> >> >> >>    OPTION_DYNAMIC_LIST_CPP_NEW,

>> > > >> >> >> >> >> >> >> >> >> >>    OPTION_DYNAMIC_LIST_CPP_TYPEINFO,

>> > > >> >> >> >> >> >> >> >> >> >>    OPTION_DYNAMIC_LIST_DATA,

>> > > >> >> >> >> >> >> >> >> >> >> +  OPTION_EXPORT_DYNAMIC_SYMBOL,

>> > > >> >> >> >> >> >> >> >> >> >>    OPTION_WARN_COMMON,

>> > > >> >> >> >> >> >> >> >> >> >>    OPTION_WARN_CONSTRUCTORS,

>> > > >> >> >> >> >> >> >> >> >> >>    OPTION_WARN_FATAL,

>> > > >> >> >> >> >> >> >> >> >> >> diff --git a/ld/lexsup.c b/ld/lexsup.c

>> > > >> >> >> >> >> >> >> >> >> >> index d1955b9afa..0a0c2f2873 100644

>> > > >> >> >> >> >> >> >> >> >> >> --- a/ld/lexsup.c

>> > > >> >> >> >> >> >> >> >> >> >> +++ b/ld/lexsup.c

>> > > >> >> >> >> >> >> >> >> >> >> @@ -504,6 +504,8 @@ static const struct ld_option ld_options[] =

>> > > >> >> >> >> >> >> >> >> >> >>      '\0', NULL, N_("Use C++ typeinfo dynamic list"), TWO_DASHES },

>> > > >> >> >> >> >> >> >> >> >> >>    { {"dynamic-list", required_argument, NULL, OPTION_DYNAMIC_LIST},

>> > > >> >> >> >> >> >> >> >> >> >>      '\0', N_("FILE"), N_("Read dynamic list"), TWO_DASHES },

>> > > >> >> >> >> >> >> >> >> >> >> +  { {"export-dynamic-symbol", required_argument, NULL, OPTION_EXPORT_DYNAMIC_SYMBOL},

>> > > >> >> >> >> >> >> >> >> >> >> +    '\0', N_("SYMBOL"), N_("Read dynamic list"), TWO_DASHES },

>> > > >> >> >> >> >> >> >> >> >> >>    { {"warn-common", no_argument, NULL, OPTION_WARN_COMMON},

>> > > >> >> >> >> >> >> >> >> >> >>      '\0', NULL, N_("Warn about duplicate common symbols"), TWO_DASHES },

>> > > >> >> >> >> >> >> >> >> >> >>    { {"warn-constructors", no_argument, NULL, OPTION_WARN_CONSTRUCTORS},

>> > > >> >> >> >> >> >> >> >> >> >> @@ -1425,6 +1427,11 @@ parse_args (unsigned argc, char **argv)

>> > > >> >> >> >> >> >> >> >> >> >>           if (opt_symbolic == symbolic)

>> > > >> >> >> >> >> >> >> >> >> >>             opt_symbolic = symbolic_unset;

>> > > >> >> >> >> >> >> >> >> >> >>           break;

>> > > >> >> >> >> >> >> >> >> >> >> +       case OPTION_EXPORT_DYNAMIC_SYMBOL:

>> > > >> >> >> >> >> >> >> >> >> >> +         ldlang_add_export_dynamic_symbol (optarg);

>> > > >> >> >> >> >> >> >> >> >> >> +         if (opt_dynamic_list != dynamic_list_data)

>> > > >> >> >> >> >> >> >> >> >> >> +           opt_dynamic_list = dynamic_list;

>> > > >> >> >> >> >> >> >> >> >> >> +         break;

>> > > >> >> >> >> >> >> >> >> >> >>         case OPTION_WARN_COMMON:

>> > > >> >> >> >> >> >> >> >> >> >>           config.warn_common = TRUE;

>> > > >> >> >> >> >> >> >> >> >> >>           break;

>> > > >> >> >> >> >> >> >> >> >> >> diff --git a/ld/testsuite/ld-undefined/export-dynamic-symbol-1.d b/ld/testsuite/ld-undefined/export-dynamic-symbol-1.d

>> > > >> >> >> >> >> >> >> >> >> >> new file mode 100644

>> > > >> >> >> >> >> >> >> >> >> >> index 0000000000..768bf0abd6

>> > > >> >> >> >> >> >> >> >> >> >> --- /dev/null

>> > > >> >> >> >> >> >> >> >> >> >> +++ b/ld/testsuite/ld-undefined/export-dynamic-symbol-1.d

>> > > >> >> >> >> >> >> >> >> >> >> @@ -0,0 +1,8 @@

>> > > >> >> >> >> >> >> >> >> >> >> +#name: --export-dynamic-symbol foo archive

>> > > >> >> >> >> >> >> >> >> >> >> +#source: require-defined.s

>> > > >> >> >> >> >> >> >> >> >> >> +#ld: -pie --export-dynamic-symbol foo tmpdir/libentry.a

>> > > >> >> >> >> >> >> >> >> >> >

>> > > >> >> >> >> >> >> >> >> >> >I assume that it supports

>> > > >> >> >> >> >> >> >> >> >> >

>> > > >> >> >> >> >> >> >> >> >> >$ ld -pie --export-dynamic-symbol foo --export-dynamic-symbol bar ...

>> > > >> >> >> >> >> >> >> >> >> >

>> > > >> >> >> >> >> >> >> >> >> >Please add another --export-dynamic-symbol to your test.

>> > > >> >> >> >> >> >> >> >> >> >

>> > > >> >> >> >> >> >> >> >> >> >--

>> > > >> >> >> >> >> >> >> >> >> >H.J.

>> > > >> >> >> >> >> >> >> >> >>

>> > > >> >> >> >> >> >> >> >> >> I face a test difficulty. If I add another `#nm:`, runtest complains:

>> > > >> >> >> >> >> >> >> >> >>

>> > > >> >> >> >> >> >> >> >> >> % cd Debug/ld

>> > > >> >> >> >> >> >> >> >> >> % runtest --tool ld --srcdir ../../ld/testsuite/ export-dynamic-symbol.exp

>> > > >> >> >> >> >> >> >> >> >> ...

>> > > >> >> >> >> >> >> >> >> >> ERROR: option nm multiply set in ../../ld/testsuite/ld-undefined/export-dynamic-symbol-1.d

>> > > >> >> >> >> >> >> >> >> >>

>> > > >> >> >> >> >> >> >> >> >> There may also be a problem of symbol table order determinism. I don't

>> > > >> >> >> >> >> >> >> >> >> know whether another symbol may be ordered before foo in some ports and

>> > > >> >> >> >> >> >> >> >> >> after foo in other ports.

>> > > >> >> >> >> >> >> >> >> >>

>> > > >> >> >> >> >> >> >> >> >> Honestly, I think for a number of tests, even if they test generic

>> > > >> >> >> >> >> >> >> >> >> behavior, it might be fine to restrict them to run on certain hosts,

>> > > >> >> >> >> >> >> >> >> >> e.g. Linux x86. What I know about testing is lacking, though, I don't

>> > > >> >> >> >> >> >> >> >> >> know what can be tested.

>> > > >> >> >> >> >> >> >> >> >>

>> > > >> >> >> >> >> >> >> >> >> Ideally `#nm:` should just be free-form shell scripts but unfortunately

>> > > >> >> >> >> >> >> >> >> >> it seems to support very limited features (undocumented?)

>> > > >> >> >> >> >> >> >> >> >

>> > > >> >> >> >> >> >> >> >> >You can't add another #nm.  But you can pass additional options to nm.

>> > > >> >> >> >> >> >> >> >> >

>> > > >> >> >> >> >> >> >> >> >--

>> > > >> >> >> >> >> >> >> >> >H.J.

>> > > >> >> >> >> >> >> >> >>

>> > > >> >> >> >> >> >> >> >> Attached PATCH v2.

>> > > >> >> >> >> >> >> >> >>

>> > > >> >> >> >> >> >> >> >> Added export-dynamic-symbol-2.d

>> > > >> >> >> >> >> >> >> >

>> > > >> >> >> >> >> >> >> >There is

>> > > >> >> >> >> >> >> >> >

>> > > >> >> >> >> >> >> >> >'--dynamic-list=DYNAMIC-LIST-FILE'

>> > > >> >> >> >> >> >> >> >     Specify the name of a dynamic list file to the linker.  This is

>> > > >> >> >> >> >> >> >> >     typically used when creating shared libraries to specify a list of

>> > > >> >> >> >> >> >> >> >     global symbols whose references shouldn't be bound to the

>> > > >> >> >> >> >> >> >> >     definition within the shared library, or creating dynamically

>> > > >> >> >> >> >> >> >> >     linked executables to specify a list of symbols which should be

>> > > >> >> >> >> >> >> >> >     added to the symbol table in the executable.  This option is only

>> > > >> >> >> >> >> >> >> >     meaningful on ELF platforms which support shared libraries.

>> > > >> >> >> >> >> >> >> >

>> > > >> >> >> >> >> >> >> >The new --export-dynamic-symbol option puts it on command-line

>> > > >> >> >> >> >> >> >> >and implicitly adds -u.  This makes the new option different from

>> > > >> >> >> >> >> >> >> >--dynamic-list.  I don't think -u should be added implicitly.  If needed,

>> > > >> >> >> >> >> >> >> >you should add another option to add -u for all symbols on dynamic

>> > > >> >> >> >> >> >> >> >list.

>> > > >> >> >> >> >> >> >> >

>> > > >> >> >> >> >> >> >> >--

>> > > >> >> >> >> >> >> >> >H.J.

>> > > >> >> >> >> >> >> >>

>> > > >> >> >> >> >> >> >> I would also hope gold did not add -u. I don't particularly like it (see

>> > > >> >> >> >> >> >> >> also https://reviews.llvm.org/D43103)

>> > > >> >> >> >> >> >> >

>> > > >> >> >> >> >> >> >Please drop implicit -u.

>> > > >> >> >> >> >> >>

>> > > >> >> >> >> >> >> Done. Attached PATCH v3.

>> > > >> >> >> >> >> >> Improved tests to check a glob pattern and multiple --export-dynamic-symbol.

>> > > >> >> >> >> >> >>

>> > > >> >> >> >> >> >> Moved ld-undefined/ to ld-dynamic/ since the feature is decoupled from -u now.

>> > > >> >> >> >> >> >>

>> > > >> >> >> >> >> >> >> If you think we can correct this, I think it should be fine.

>> > > >> >> >> >> >> >> >

>> > > >> >> >> >> >> >> >Please open a gold bug for this.

>> > > >> >> >> >> >> >> >

>> > > >> >> >> >> >> >> >Thanks.

>> > > >> >> >> >> >> >> >

>> > > >> >> >> >> >> >> >--

>> > > >> >> >> >> >> >> >H.J.

>> > > >> >> >> >> >> >>

>> > > >> >> >> >> >> >> Filed https://sourceware.org/bugzilla/show_bug.cgi?id=25925 (--export-dynamic-symbol should drop implicit -u)

>> > > >> >> >> >> >> >>

>> > > >> >> >> >> >> >>

>> > > >> >> >> >> >> >> I may have to migrate some internal projects if they rely on the

>> > > >> >> >> >> >> >> --export-dynamic-symbol semantics, but hopefully there will not be much

>> > > >> >> >> >> >> >> work. I am glad that --export-dynamic-symbol semantic will be orthogonal!

>> > > >> >> >> >> >> >

>> > > >> >> >> >> >> >+ case OPTION_EXPORT_DYNAMIC_SYMBOL:

>> > > >> >> >> >> >> >+   ldlang_add_export_dynamic_symbol (optarg);

>> > > >> >> >> >> >> >

>> > > >> >> >> >> >> >Can you simply call

>> > > >> >> >> >> >> >

>> > > >> >> >> >> >> >lang_append_dynamic_list (lang_new_vers_pattern (NULL, optarg, NULL, FALSE));

>> > > >> >> >> >> >> >

>> > > >> >> >> >> >> >here?

>> > > >> >> >> >> >> >

>> > > >> >> >> >> >> >--

>> > > >> >> >> >> >> >H.J.

>> > > >> >> >> >> >>

>> > > >> >> >> >> >> Attached PATCH v4, which also handles -shared.  The previous patches do not handle -shared.

>> > > >> >> >> >> >> Added two tests to ld-elf/shared.exp

>> > > >> >> >> >> >>

>> > > >> >> >> >> >> The updated semantics:

>> > > >> >> >> >> >>

>> > > >> >> >> >> >> + @kindex --export-dynamic-symbol=@var{glob}

>> > > >> >> >> >> >> + @cindex export dynamic symbol

>> > > >> >> >> >> >> + @item --export-dynamic-symbol=@var{glob}

>> > > >> >> >> >> >> + When creating a dynamically linked executable, symbols matching

>> > > >> >> >> >> >> + @var{glob} will be added to the dynamic symbol table. When creating a

>> > > >> >> >> >> >> + shared library, references to symbols matching @var{glob} will not be

>> > > >> >> >> >> >> + bound to the definitions within the shared library. This option is a

>> > > >> >> >> >> >> + no-op when creating a shared library and @samp{--dynamic-list} is not

>> > > >> >> >> >> >> + specified. This option is only meaningful on ELF platforms which

>> > > >> >> >> >> >> + support shared libraries.

>> > > >> >> >> >> >>

>> > > >> >> >> >> >> i.e. --export-dynamic-symbol is like addition to --dynamic-list,

>> > > >> >> >> >> >> except: -shared --export-dynamic-symbol without --dynamic-list will not

>> > > >> >> >> >> >> act as -Bsymbolic.

>> > > >> >> >> >> >>

>> > > >> >> >> >> >> In the option processing loop, we cannot call lang_append_dynamic_list

>> > > >> >> >> >> >> because when -shared is specified but --dynamic-list is not specified,

>> > > >> >> >> >> >> --export-dynamic-symbol should be a no-op.

>> > > >> >> >> >> >

>> > > >> >> >> >> >--dynamic-list implies -Bsymbolic.  If we add --export-dynamic-symbol,

>> > > >> >> >> >> >we should also add --export-dynamic-symbol-list, which is similar to

>> > > >> >> >> >> >--dynamic-list, but without -Bsymbolic.

>> > > >> >> >> >>

>> > > >> >> >> >> --export-dynamic-symbol-list a.list  where a.list is a plain text like:

>> > > >> >> >> >> foo

>> > > >> >> >> >> bar

>> > > >> >> >> >> ?

>> > > >> >> >> >

>> > > >> >> >> >I prefer to use the same format as --dynamic-list.

>> > > >> >> >> >

>> > > >> >> >> >> The feature can be provided by a response file @a.rsp

>> > > >> >> >> >> --export-dynamic-symbol foo

>> > > >> >> >> >> --export-dynamic-symbol bar

>> > > >> >> >>

>> > > >> >> >> Adding --export-dynamic-symbol-list is fine. We can implement that separately.

>> > > >> >> >

>> > > >> >> >Since implement --export-dynamic-symbol-list at the same time may impact how

>> > > >> >> >--export-dynamic-symbol is implemented, they should be added together.

>> > > >> >>

>> > > >> >> OK. Added --export-dynamic-symbol-list as well.

>> > > >> >>

>> > > >> >> Retitled.

>> > > >> >

>> > > >> >A couple comments:

>> > > >>

>> > > >> Thanks for the review!

>> > > >>

>> > > >> >1. Please add an entry to ld/NEWS.

>> > > >> >2. Please a note to ld.texi for the difference between --dynamic-list and

>> > > >> >--export-dynamic-symbol.

>> > > >>

>> > > >> >3.  What happens when there are both --dynamic-list and and

>> > > >> >--export-dynamic-symbol, with and without -Bsymbolic?

>> > > >>

>> > > >> --export-symbol-symbol adds additional entries to --dynamic-list.

>> > > >

>> > > >I don't think so.  See below.

>> > > >

>> > > >>

>> > > >> I'd expect --dynamic-list to override -Bsymbolic (i.e. --dynamic-list is a

>> > > >> refined -Bsymbolic).

>> > > >> gold and

>> > > >> LLD (https://github.com/llvm/llvm-project/blob/master/lld/ELF/Symbols.cpp#L368)

>> > > >> behave this way.

>> > > >> GNU ld seems to make every symbol symbolic.

>> > > >

>> > > >Ld manual says

>> > > >

>> > > >'--dynamic-list=DYNAMIC-LIST-FILE'

>> > > >     Specify the name of a dynamic list file to the linker.  This is

>> > > >     typically used when creating shared libraries to specify a list of

>> > > >     global symbols whose references shouldn't be bound to the

>> > > >     definition within the shared library, or creating dynamically

>> > > >     linked executables to specify a list of symbols which should be

>> > > >     added to the symbol table in the executable.  This option is only

>> > > >     meaningful on ELF platforms which support shared libraries.

>> > > >

>> > > >     The format of the dynamic list is the same as the version node

>> > > >     without scope and node name.  See *note VERSION:: for more

>> > > >     information.

>> > > >

>> > > >When producing a shared library,  --dynamic-list implies -Bsymbolic

>> > > >with exception for the symbols on the dynamic list.

>> > >

>> > > This is my understanding. By using `implies`, do you mean -Bsymbolic is

>> > > ignored (gold and LLD's interpretation)? If so, GNU ld should be fixed.

>> >

>> > --dynamic-list should be the same as -Bsymbolic --dynamic-list.

>> >

>> > > I don't think any project is using the combination, so changing the

>> > > semantics should not be a problem.

>> > >

>> > > >> This can be tested with:

>> > > >>

>> > > >> .globl main, foo, bar

>> > > >> main: call foo

>> > > >> foo: call bar

>> > > >> bar: ret

>> > > >>

>> > > >> // a.list

>> > > >> { foo; };

>> > > >>

>> > > >> It is also fine if you think -Bsymbolic should override --dynamic-list.

>> > > >> (Please add a test for that so that I know how to test --export-dynamic-list)

>> > > >> We can then file a gold bug.

>> > > >>

>> > > >> >4.  Can you reuse lang_append_dynamic_list to implement

>> > > >> >--export-dynamic-symbol?

>> > > >>

>> > > >> This is difficult. It seems that another global variable needs to be introduced.

>> > > >> yacc code duplication may not be that bad compared with the alternative.

>> > > >

>> > > >Since --export-dynamic-symbol is a NOP for -shared and identical with

>> > > >--dynamic-list otherwise, let's only consider the -shared case:

>> > >

>> > > Combined with both points below, --export-dynamic-symbol can be treated

>> > > as a NOP when -shared is specified.  This is acceptable because (as far

>> > > as I can tell from my observation) --export-dynamic is a NOP with

>> > > -shared.

>> > >

>> > > >1. Without -Bsymbolic nor --dynamic-list,  --export-dynamic-symbol should

>> > > >be dropped.

>> > >

>> > > Looks good.

>> > >

>> > > >2. With -Bsymbolic or --dynamic-list, --export-dynamic-symbol should also

>> > > >be dropped since --export-dynamic-symbol doesn't change symbol binding.

>> > >

>> > > Is the intention that --export-dynamic-symbol should be similar more to

>> > > --export-dynamic and less to --dynamic-list? I'm fine with the change.

>> > >

>> > >

>> > > If a.list contains { foo; };

>> > >

>> > >

>> > > # all global symbols are exported. foo is symbolic. --export-dynamic is ignored.

>> > > ld.bfd -shared --dynamic-list=a.list --export-dynamic

>> > >

>> > > # all global symbols are exported. foo is symbolic. --export-dynamic-bar is ignored.

>> > > ld.bfd -shared --dynamic-list=a.list --export-dynamic-symbol=bar

>> > >

>> > > # all global symbols are exported.

>> > > ld.bfd -pie --dynamic-list=a.list --export-dynamic

>> > >

>> > > # foo and bar are exported.

>> > > ld.bfd -pie --dynamic-list=a.list --export-dynamic-symbol=bar

>> > >

>> > > >I think we should add a bit field to bfd_elf_version_expr to indicate if symbol

>> > > >binding should be symbolic (-Bsymbolic) and use lang_append_dynamic_list

>> > > >for both --dynamic-list and --export-dynamic-symbol.  The only

>> > > >difference is that

>> > > >symbols from --export-dynamic-symbol aren't symbolic and can be dropped for

>> > > >-shared.

>> > >

>> > > Like my patch does, we need a separate list for --export-dynamic-symbol.

>> > > We cannot call lang_append_dynamic_list yet when processing options,

>> > > because it is unknown whether -shared will occur.

>> >

>> > The dynamic list should be processed after all command line options have

>> > been seen.

>> >

>>

>> This is the patch on the top of yours.  But I got

>>

>> FAIL: Run with libdl2d.so

>> FAIL: Run with libdl2e.so

>> FAIL: Run with libdl2f.so

>> FAIL: Run with libdl2g.so

>>

>> Please find out why.

>>

>

>This only gets

>

>FAIL: Run with libdl2e.so

>FAIL: Run with libdl2g.so

>

>I think these tests are wrong since --export-dynamic-symbol shouldn't change

>symbol binding in the shared library.

>

>-- 

>H.J.


I think we should just let --dynamic-list* override -Bsymbolic -Bsymbolic-functions.

--dynamic-list = --dynamic-list -Bsymbolic = -Bsymbolic --dynamic-list


Created https://sourceware.org/pipermail/binutils/2020-May/111211.html
[PATCH] ld: Make --dynamic-list* override -Bsymbolic -Bsymbolic-functions

Patch

From 6e07405e21f9c7b8f8779f3c23a179a5a38ede1c Mon Sep 17 00:00:00 2001
From: Fangrui Song <maskray@google.com>
Date: Wed, 22 Apr 2020 22:12:42 -0700
Subject: [PATCH] ld: Add --export-dynamic-symbol and
 --export-dynamic-symbol-list

--export-dynamic-symbol-list is like a dynamic list, but without
the symbolic property for unspecified symbols.

When creating an executable, --export-dynamic-symbol-list specifies
symbols which should be added to the dynamic symbol table. When creating
a shared library, references to matched symbols will not be bound to the
definitions within the shared library.

	PR ld/25910
	* ldlex.h (option_values): Add OPTION_EXPORT_DYNAMIC_SYMBOL and
	OPTION_EXPORT_DYNAMIC_SYMBOL_LIST.
	(input_enum): Add input_export_dynamic_symbol_list.
	* ldlex.l: Handle input_export_dynamic_symbol_list.
	* ldgram.y: Parse export dynamic symbol list.
	* ldlang.c (export_dynamic_symbol_list): New.
	(lang_append_export_dynamic_symbol_list): New.
	* ldlang.h: Declare.
	* lexsup.c (ld_options): Add entries for OPTION_EXPORT_DYNAMIC_SYMBOL and
	OPTION_EXPORT_DYNAMIC_SYMBOL_LIST.
	(parse_args): Handle --export-dynamic-symbol and
	--export-dynamic-symbol-list.
	* ld.texi: Add documentation.
	* testsuite/ld-dynamic/export-dynamic-symbol.exp: Run new test.
	* testsuite/ld-dynamic/export-dynamic-symbol.s: New.
	* testsuite/ld-dynamic/export-dynamic-symbol-1.d: New.
	* testsuite/ld-dynamic/export-dynamic-symbol-2.d: New.
	* testsuite/ld-dynamic/export-dynamic-symbol-glob.d: New.
	* testsuite/ld-dynamic/export-dynamic-symbol-list-1.d: New.
	* testsuite/ld-dynamic/export-dynamic-symbol-list-2.d: New.
	* testsuite/ld-dynamic/export-dynamic-symbol-list-glob.d: New.
	* testsuite/ld-dynamic/foo.s: New.
	* testsuite/ld-dynamic/foo.list: New.
	* testsuite/ld-dynamic/foo-bar.list: New.
	* testsuite/ld-dynamic/fstar.list: New.
	* testsuite/ld-elf/shared.exp: New test.
	* testsuite/ld-elf/dlempty.list: New.
---
 ld/ld.texi                                    | 18 +++++++++
 ld/ldgram.y                                   | 31 ++++++++++++++-
 ld/ldlang.c                                   | 13 +++++++
 ld/ldlang.h                                   |  2 +
 ld/ldlex.h                                    |  3 ++
 ld/ldlex.l                                    |  1 +
 ld/lexsup.c                                   | 30 ++++++++++++++
 .../ld-dynamic/export-dynamic-symbol-1.d      |  9 +++++
 .../ld-dynamic/export-dynamic-symbol-2.d      |  9 +++++
 .../ld-dynamic/export-dynamic-symbol-glob.d   |  8 ++++
 .../ld-dynamic/export-dynamic-symbol-list-1.d |  9 +++++
 .../ld-dynamic/export-dynamic-symbol-list-2.d |  9 +++++
 .../export-dynamic-symbol-list-glob.d         |  8 ++++
 .../ld-dynamic/export-dynamic-symbol.exp      | 39 +++++++++++++++++++
 .../ld-dynamic/export-dynamic-symbol.s        |  9 +++++
 ld/testsuite/ld-dynamic/foo-bar.list          |  1 +
 ld/testsuite/ld-dynamic/foo.list              |  1 +
 ld/testsuite/ld-dynamic/foo.s                 |  4 ++
 ld/testsuite/ld-dynamic/fstar.list            |  1 +
 ld/testsuite/ld-elf/dlempty.list              |  3 ++
 ld/testsuite/ld-elf/shared.exp                | 24 ++++++++++++
 21 files changed, 231 insertions(+), 1 deletion(-)
 create mode 100644 ld/testsuite/ld-dynamic/export-dynamic-symbol-1.d
 create mode 100644 ld/testsuite/ld-dynamic/export-dynamic-symbol-2.d
 create mode 100644 ld/testsuite/ld-dynamic/export-dynamic-symbol-glob.d
 create mode 100644 ld/testsuite/ld-dynamic/export-dynamic-symbol-list-1.d
 create mode 100644 ld/testsuite/ld-dynamic/export-dynamic-symbol-list-2.d
 create mode 100644 ld/testsuite/ld-dynamic/export-dynamic-symbol-list-glob.d
 create mode 100644 ld/testsuite/ld-dynamic/export-dynamic-symbol.exp
 create mode 100644 ld/testsuite/ld-dynamic/export-dynamic-symbol.s
 create mode 100644 ld/testsuite/ld-dynamic/foo-bar.list
 create mode 100644 ld/testsuite/ld-dynamic/foo.list
 create mode 100644 ld/testsuite/ld-dynamic/foo.s
 create mode 100644 ld/testsuite/ld-dynamic/fstar.list
 create mode 100644 ld/testsuite/ld-elf/dlempty.list

diff --git a/ld/ld.texi b/ld/ld.texi
index 4dc78e65fa..1244d91a70 100644
--- a/ld/ld.texi
+++ b/ld/ld.texi
@@ -569,6 +569,24 @@  Note that this option is specific to ELF targeted ports.  PE targets
 support a similar function to export all symbols from a DLL or EXE; see
 the description of @samp{--export-all-symbols} below.
 
+@kindex --export-dynamic-symbol=@var{glob}
+@cindex export dynamic symbol
+@item --export-dynamic-symbol=@var{glob}
+When creating a dynamically linked executable, symbols matching
+@var{glob} will be added to the dynamic symbol table. When creating a
+shared library, references to symbols matching @var{glob} will not be
+bound to the definitions within the shared library. This option is a
+no-op when creating a shared library and @samp{--dynamic-list} is not
+specified. This option is only meaningful on ELF platforms which
+support shared libraries.
+
+@kindex --export-dynamic-symbol-list=@var{file}
+@cindex export dynamic symbol list
+@item --export-dynamic-symbol-list=@var{file}
+Specify a @samp{--export-dynamic-symbol} for each pattern in the file.
+The format of the file is the same as the version node without
+scope and node name.  See @ref{VERSION} for more information.
+
 @ifclear SingleFormat
 @cindex big-endian objects
 @cindex endianness
diff --git a/ld/ldgram.y b/ld/ldgram.y
index df5c035c03..34ff1db63d 100644
--- a/ld/ldgram.y
+++ b/ld/ldgram.y
@@ -159,7 +159,7 @@  static int error_index;
 %type <versyms> vers_defns
 %type <versnode> vers_tag
 %type <deflist> verdep
-%token INPUT_DYNAMIC_LIST
+%token INPUT_DYNAMIC_LIST INPUT_EXPORT_DYNAMIC_SYMBOL_LIST
 
 %%
 
@@ -168,6 +168,7 @@  file:
 	|	INPUT_MRI_SCRIPT mri_script_file
 	|	INPUT_VERSION_SCRIPT version_script_file
 	|	INPUT_DYNAMIC_LIST dynamic_list_file
+	|	INPUT_EXPORT_DYNAMIC_SYMBOL_LIST export_dynamic_symbol_list_file
 	|	INPUT_DEFSYM defsym_expr
 	;
 
@@ -1317,6 +1318,34 @@  dynamic_list_tag:
 		}
 	;
 
+export_dynamic_symbol_list_file:
+		{
+		  ldlex_version_file ();
+		  PUSH_ERROR (_("export dynamic symbol list"));
+		}
+		export_dynamic_symbol_list_nodes
+		{
+		  ldlex_popstate ();
+		  POP_ERROR ();
+		}
+	;
+
+export_dynamic_symbol_list_nodes:
+		export_dynamic_symbol_list_node
+	|	export_dynamic_symbol_list_nodes export_dynamic_symbol_list_node
+	;
+
+export_dynamic_symbol_list_node:
+		'{' export_dynamic_symbol_list_tag '}' ';'
+	;
+
+export_dynamic_symbol_list_tag:
+		vers_defns ';'
+		{
+		  lang_append_export_dynamic_symbol_list ($1);
+		}
+	;
+
 /* This syntax is used within an external version script file.  */
 
 version_script_file:
diff --git a/ld/ldlang.c b/ld/ldlang.c
index b2cdb3603a..1f72630b8f 100644
--- a/ld/ldlang.c
+++ b/ld/ldlang.c
@@ -119,6 +119,7 @@  lang_statement_list_type file_chain = { NULL, NULL };
 lang_statement_list_type input_file_chain;
 static const char *current_input_file;
 struct bfd_sym_chain entry_symbol = { NULL, NULL };
+struct bfd_elf_version_expr export_dynamic_symbol_list = { NULL };
 const char *entry_section = ".text";
 struct lang_input_statement_flags input_flags;
 bfd_boolean entry_from_cmdline;
@@ -9389,6 +9390,18 @@  lang_append_dynamic_list_cpp_new (void)
   lang_append_dynamic_list (dynamic);
 }
 
+void
+lang_append_export_dynamic_symbol_list (struct bfd_elf_version_expr *dynamic)
+{
+  struct bfd_elf_version_expr *next;
+  for (; dynamic; dynamic = next)
+    {
+      next = dynamic->next;
+      dynamic->next = export_dynamic_symbol_list.next;
+      export_dynamic_symbol_list.next = dynamic;
+    }
+}
+
 /* Scan a space and/or comma separated string of features.  */
 
 void
diff --git a/ld/ldlang.h b/ld/ldlang.h
index 2aa3930f95..53bc475679 100644
--- a/ld/ldlang.h
+++ b/ld/ldlang.h
@@ -506,6 +506,7 @@  extern lang_statement_list_type *stat_ptr;
 extern bfd_boolean delete_output_file_on_failure;
 
 extern struct bfd_sym_chain entry_symbol;
+extern struct bfd_elf_version_expr export_dynamic_symbol_list;
 extern const char *entry_section;
 extern bfd_boolean entry_from_cmdline;
 extern lang_statement_list_type file_chain;
@@ -674,6 +675,7 @@  extern void lang_register_vers_node
 extern void lang_append_dynamic_list (struct bfd_elf_version_expr *);
 extern void lang_append_dynamic_list_cpp_typeinfo (void);
 extern void lang_append_dynamic_list_cpp_new (void);
+extern void lang_append_export_dynamic_symbol_list (struct bfd_elf_version_expr *);
 extern void lang_add_unique
   (const char *);
 extern const char *lang_get_output_target
diff --git a/ld/ldlex.h b/ld/ldlex.h
index 22b928d2d9..930f41877d 100644
--- a/ld/ldlex.h
+++ b/ld/ldlex.h
@@ -81,6 +81,8 @@  enum option_values
   OPTION_DYNAMIC_LIST_CPP_NEW,
   OPTION_DYNAMIC_LIST_CPP_TYPEINFO,
   OPTION_DYNAMIC_LIST_DATA,
+  OPTION_EXPORT_DYNAMIC_SYMBOL,
+  OPTION_EXPORT_DYNAMIC_SYMBOL_LIST,
   OPTION_WARN_COMMON,
   OPTION_WARN_CONSTRUCTORS,
   OPTION_WARN_FATAL,
@@ -161,6 +163,7 @@  typedef enum input_enum {
   input_mri_script,
   input_version_script,
   input_dynamic_list,
+  input_export_dynamic_symbol_list,
   input_defsym
 } input_type;
 
diff --git a/ld/ldlex.l b/ld/ldlex.l
index 0fcbe84c8b..c70268868c 100644
--- a/ld/ldlex.l
+++ b/ld/ldlex.l
@@ -125,6 +125,7 @@  V_IDENTIFIER [*?.$_a-zA-Z\[\]\-\!\^\\]([*?.$_a-zA-Z0-9\[\]\-\!\^\\]|::)*
 	case input_mri_script: return INPUT_MRI_SCRIPT; break;
 	case input_version_script: return INPUT_VERSION_SCRIPT; break;
 	case input_dynamic_list: return INPUT_DYNAMIC_LIST; break;
+	case input_export_dynamic_symbol_list: return INPUT_EXPORT_DYNAMIC_SYMBOL_LIST; break;
 	case input_defsym: return INPUT_DEFSYM; break;
 	default: abort ();
 	}
diff --git a/ld/lexsup.c b/ld/lexsup.c
index d1955b9afa..bccbe2fc53 100644
--- a/ld/lexsup.c
+++ b/ld/lexsup.c
@@ -504,6 +504,10 @@  static const struct ld_option ld_options[] =
     '\0', NULL, N_("Use C++ typeinfo dynamic list"), TWO_DASHES },
   { {"dynamic-list", required_argument, NULL, OPTION_DYNAMIC_LIST},
     '\0', N_("FILE"), N_("Read dynamic list"), TWO_DASHES },
+  { {"export-dynamic-symbol", required_argument, NULL, OPTION_EXPORT_DYNAMIC_SYMBOL},
+    '\0', N_("SYMBOL"), N_("Export the specified symbol"), EXACTLY_TWO_DASHES },
+  { {"export-dynamic-symbol-list", required_argument, NULL, OPTION_EXPORT_DYNAMIC_SYMBOL_LIST},
+    '\0', N_("FILE"), N_("Read export dynamic symbol list"), EXACTLY_TWO_DASHES },
   { {"warn-common", no_argument, NULL, OPTION_WARN_COMMON},
     '\0', NULL, N_("Warn about duplicate common symbols"), TWO_DASHES },
   { {"warn-constructors", no_argument, NULL, OPTION_WARN_CONSTRUCTORS},
@@ -1425,6 +1429,23 @@  parse_args (unsigned argc, char **argv)
 	  if (opt_symbolic == symbolic)
 	    opt_symbolic = symbolic_unset;
 	  break;
+	case OPTION_EXPORT_DYNAMIC_SYMBOL:
+	  {
+            struct bfd_elf_version_expr *expr
+                = lang_new_vers_pattern (NULL, xstrdup (optarg), NULL, FALSE);
+            expr->next = export_dynamic_symbol_list.next;
+            export_dynamic_symbol_list.next = expr;
+          }
+	  break;
+	case OPTION_EXPORT_DYNAMIC_SYMBOL_LIST:
+	  {
+	    FILE *hold_script_handle = saved_script_handle;
+	    ldfile_open_command_file (optarg);
+	    saved_script_handle = hold_script_handle;
+	    parser_input = input_export_dynamic_symbol_list;
+	    yyparse ();
+	  }
+	  break;
 	case OPTION_WARN_COMMON:
 	  config.warn_common = TRUE;
 	  break;
@@ -1659,6 +1680,15 @@  parse_args (unsigned argc, char **argv)
 	break;
       }
 
+  if (opt_dynamic_list != dynamic_list_unset || !bfd_link_dll (&link_info))
+    {
+      if (export_dynamic_symbol_list.next)
+        lang_append_dynamic_list (export_dynamic_symbol_list.next);
+      if (export_dynamic_symbol_list.next
+          && opt_dynamic_list != dynamic_list_data)
+        opt_dynamic_list = dynamic_list;
+    }
+
   switch (opt_dynamic_list)
     {
     case dynamic_list_unset:
diff --git a/ld/testsuite/ld-dynamic/export-dynamic-symbol-1.d b/ld/testsuite/ld-dynamic/export-dynamic-symbol-1.d
new file mode 100644
index 0000000000..c1dd4e2f55
--- /dev/null
+++ b/ld/testsuite/ld-dynamic/export-dynamic-symbol-1.d
@@ -0,0 +1,9 @@ 
+#name: --export-dynamic-symbol foo archive
+#source: export-dynamic-symbol.s
+#ld: -pie --export-dynamic-symbol foo tmpdir/libfoo.a
+#nm: -n
+
+#failif
+#...
+[0-9a-f]+ T +foo
+#...
diff --git a/ld/testsuite/ld-dynamic/export-dynamic-symbol-2.d b/ld/testsuite/ld-dynamic/export-dynamic-symbol-2.d
new file mode 100644
index 0000000000..7ec4eed3ed
--- /dev/null
+++ b/ld/testsuite/ld-dynamic/export-dynamic-symbol-2.d
@@ -0,0 +1,9 @@ 
+#name: -u --export-dynamic-symbol foo archive
+#source: export-dynamic-symbol.s
+#ld: -pie -u foo --export-dynamic-symbol foo --export-dynamic-symbol=bar tmpdir/libfoo.a
+#nm: -D
+
+#...
+[0-9a-f]+ T +bar
+[0-9a-f]+ T +foo
+#...
diff --git a/ld/testsuite/ld-dynamic/export-dynamic-symbol-glob.d b/ld/testsuite/ld-dynamic/export-dynamic-symbol-glob.d
new file mode 100644
index 0000000000..05a6e15b3b
--- /dev/null
+++ b/ld/testsuite/ld-dynamic/export-dynamic-symbol-glob.d
@@ -0,0 +1,8 @@ 
+#name: -u --export-dynamic-symbol f* archive
+#source: export-dynamic-symbol.s
+#ld: -pie -u foo --export-dynamic-symbol f* tmpdir/libfoo.a
+#nm: -D
+
+#...
+[0-9a-f]+ T +foo
+#...
diff --git a/ld/testsuite/ld-dynamic/export-dynamic-symbol-list-1.d b/ld/testsuite/ld-dynamic/export-dynamic-symbol-list-1.d
new file mode 100644
index 0000000000..aa1b8839e6
--- /dev/null
+++ b/ld/testsuite/ld-dynamic/export-dynamic-symbol-list-1.d
@@ -0,0 +1,9 @@ 
+#name: --export-dynamic-symbol-list foo archive
+#source: export-dynamic-symbol.s
+#ld: -pie --export-dynamic-symbol-list foo.list tmpdir/libfoo.a
+#nm: -n
+
+#failif
+#...
+[0-9a-f]+ T +foo
+#...
diff --git a/ld/testsuite/ld-dynamic/export-dynamic-symbol-list-2.d b/ld/testsuite/ld-dynamic/export-dynamic-symbol-list-2.d
new file mode 100644
index 0000000000..367a07c1bb
--- /dev/null
+++ b/ld/testsuite/ld-dynamic/export-dynamic-symbol-list-2.d
@@ -0,0 +1,9 @@ 
+#name: -u --export-dynamic-symbol-list foo bar archive
+#source: export-dynamic-symbol.s
+#ld: -pie -u foo --export-dynamic-symbol-list foo-bar.list tmpdir/libfoo.a
+#nm: -D
+
+#...
+[0-9a-f]+ T +bar
+[0-9a-f]+ T +foo
+#...
diff --git a/ld/testsuite/ld-dynamic/export-dynamic-symbol-list-glob.d b/ld/testsuite/ld-dynamic/export-dynamic-symbol-list-glob.d
new file mode 100644
index 0000000000..f0e3427306
--- /dev/null
+++ b/ld/testsuite/ld-dynamic/export-dynamic-symbol-list-glob.d
@@ -0,0 +1,8 @@ 
+#name: -u --export-dynamic-symbol-list fstar archive
+#source: export-dynamic-symbol.s
+#ld: -pie -u foo --export-dynamic-symbol-list fstar.list tmpdir/libfoo.a
+#nm: -D
+
+#...
+[0-9a-f]+ T +foo
+#...
diff --git a/ld/testsuite/ld-dynamic/export-dynamic-symbol.exp b/ld/testsuite/ld-dynamic/export-dynamic-symbol.exp
new file mode 100644
index 0000000000..d0b4bc4eb0
--- /dev/null
+++ b/ld/testsuite/ld-dynamic/export-dynamic-symbol.exp
@@ -0,0 +1,39 @@ 
+# Expect script for ld --export-dynamic-symbol tests
+#   Copyright (C) 2020 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.
+#
+
+if ![is_elf_format] {
+    return
+}
+
+set build_tests {
+  {"Build libfoo.a"
+   "" "" ""
+   {foo.s} {} "libfoo.a"}
+}
+
+run_ld_link_tests $build_tests
+
+set test_list [lsort [glob -nocomplain $srcdir/$subdir/export-dynamic-symbol-*.d]]
+foreach test_file $test_list {
+    set test_name [file rootname $test_file]
+    verbose $test_name
+    run_dump_test $test_name
+}
diff --git a/ld/testsuite/ld-dynamic/export-dynamic-symbol.s b/ld/testsuite/ld-dynamic/export-dynamic-symbol.s
new file mode 100644
index 0000000000..4b1b8ebd5c
--- /dev/null
+++ b/ld/testsuite/ld-dynamic/export-dynamic-symbol.s
@@ -0,0 +1,9 @@ 
+	.text
+	.global _start
+_start:
+	.word 0
+
+	.section .text.1, "ax"
+	.global bar
+bar:
+	.word 0
diff --git a/ld/testsuite/ld-dynamic/foo-bar.list b/ld/testsuite/ld-dynamic/foo-bar.list
new file mode 100644
index 0000000000..87732e1de4
--- /dev/null
+++ b/ld/testsuite/ld-dynamic/foo-bar.list
@@ -0,0 +1 @@ 
+{ foo; bar; };
diff --git a/ld/testsuite/ld-dynamic/foo.list b/ld/testsuite/ld-dynamic/foo.list
new file mode 100644
index 0000000000..f89f569438
--- /dev/null
+++ b/ld/testsuite/ld-dynamic/foo.list
@@ -0,0 +1 @@ 
+{ foo; };
diff --git a/ld/testsuite/ld-dynamic/foo.s b/ld/testsuite/ld-dynamic/foo.s
new file mode 100644
index 0000000000..4a70181776
--- /dev/null
+++ b/ld/testsuite/ld-dynamic/foo.s
@@ -0,0 +1,4 @@ 
+	.text
+	.globl foo
+foo:
+	.byte 0
diff --git a/ld/testsuite/ld-dynamic/fstar.list b/ld/testsuite/ld-dynamic/fstar.list
new file mode 100644
index 0000000000..330d1dd2b8
--- /dev/null
+++ b/ld/testsuite/ld-dynamic/fstar.list
@@ -0,0 +1 @@ 
+{ f*; };
diff --git a/ld/testsuite/ld-elf/dlempty.list b/ld/testsuite/ld-elf/dlempty.list
new file mode 100644
index 0000000000..9b3884b10e
--- /dev/null
+++ b/ld/testsuite/ld-elf/dlempty.list
@@ -0,0 +1,3 @@ 
+{
+  empty;
+};
diff --git a/ld/testsuite/ld-elf/shared.exp b/ld/testsuite/ld-elf/shared.exp
index 3366430515..2579668342 100644
--- a/ld/testsuite/ld-elf/shared.exp
+++ b/ld/testsuite/ld-elf/shared.exp
@@ -598,6 +598,18 @@  set build_tests {
   {"Build libdl2c.so with --dynamic-list-data and dl2xxx.list"
    "-shared -Wl,--dynamic-list-data,--dynamic-list=dl2xxx.list" "-fPIC"
    {dl2.c dl2xxx.c} {} "libdl2c.so"}
+  {"Build libdl2d.so with --export-dynamic-symbol=foo"
+   "-shared -Wl,--export-dynamic-symbol=foo" "-fPIC"
+   {dl2.c dl2xxx.c} {} "libdl2d.so"}
+  {"Build libdl2e.so with --dynamic-list=dlempty.list and --export-dynamic-symbol=foo"
+   "-shared -Wl,--dynamic-list=dlempty.list,--export-dynamic-symbol=foo" "-fPIC"
+   {dl2.c dl2xxx.c} {} "libdl2e.so"}
+  {"Build libdl2f.so with --export-dynamic-symbol-list=dl2.list"
+   "-shared -Wl,--export-dynamic-symbol-list=dl2.list" "-fPIC"
+   {dl2.c dl2xxx.c} {} "libdl2f.so"}
+  {"Build libdl2g.so with --dynamic-list=dlempty.list and --export-dynamic-symbol-list=dl2.list"
+   "-shared -Wl,--dynamic-list=dlempty.list,--export-dynamic-symbol-list=dl2.list" "-fPIC"
+   {dl2.c dl2xxx.c} {} "libdl2g.so"}
   {"Build libdl4a.so with --dynamic-list=dl4.list"
    "-shared -Wl,--dynamic-list=dl4.list" "-fPIC"
    {dl4.c dl4xxx.c} {} "libdl4a.so"}
@@ -874,6 +886,18 @@  set run_tests [list \
     [list "Run with libdl2c.so" \
      "-Wl,--no-as-needed tmpdir/libdl2c.so" "" \
      {dl2main.c} "dl2c" "dl2b.out" ] \
+    [list "Run with libdl2d.so" \
+     "-Wl,--no-as-needed tmpdir/libdl2d.so" "" \
+     {dl2main.c} "dl2d" "dl2b.out" ] \
+    [list "Run with libdl2e.so" \
+     "-Wl,--no-as-needed tmpdir/libdl2e.so" "" \
+     {dl2main.c} "dl2e" "dl2a.out" ] \
+    [list "Run with libdl2f.so" \
+     "-Wl,--no-as-needed tmpdir/libdl2f.so" "" \
+     {dl2main.c} "dl2f" "dl2b.out" ] \
+    [list "Run with libdl2g.so" \
+     "-Wl,--no-as-needed tmpdir/libdl2g.so" "" \
+     {dl2main.c} "dl2g" "dl2a.out" ] \
     [list "Run with libdl4a.so" \
      "-Wl,--no-as-needed tmpdir/libdl4a.so" "" \
      {dl4main.c} "dl4a" "dl4a.out" ] \
-- 
2.26.2.645.ge9eca65c58-goog