[v4] ld: Add --export-dynamic-symbol

Message ID 20200506184212.iz6ozuazke5yshxe@google.com
State New
Headers show
Series
  • [v4] ld: Add --export-dynamic-symbol
Related show

Commit Message

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.

Comments

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.

-- 
H.J.
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
?

The feature can be provided by a response file @a.rsp
--export-dynamic-symbol foo
--export-dynamic-symbol bar
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




-- 
H.J.
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.
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.

-- 
H.J.

Patch

From 20d52868e64b8c068cd0bb29693029371c9bbfd7 Mon Sep 17 00:00:00 2001
From: Fangrui Song <maskray@google.com>
Date: Wed, 22 Apr 2020 22:12:42 -0700
Subject: [PATCH v4] ld: Add --export-dynamic-symbol

	PR ld/25910
	* ldlex.h (option_values): Add OPTION_EXPORT_DYNAMIC_SYMBOL.
	* lexsup.c (ld_options): Add entry for OPTION_EXPORT_DYNAMIC_SYMBOL.
	(parse_args): Handle --export-dynamic-symbol.
	* ld.texi: Add --export-dynamic-symbol documentation.
	* testsuite/ld-dynamic/export-dynamic-symbol.exp: Run new test.
	* 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.s: New.
	* testsuite/ld-dynamic/foo.s: New.
	* testsuite/ld-elf/shared.exp: New test.
	* testsuite/ld-elf/dlempty.list: New.
---
 ld/ld.texi                                    | 11 ++++++
 ld/ldlex.h                                    |  1 +
 ld/lexsup.c                                   | 24 ++++++++++++
 .../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.exp      | 39 +++++++++++++++++++
 .../ld-dynamic/export-dynamic-symbol.s        |  9 +++++
 ld/testsuite/ld-dynamic/foo.s                 |  4 ++
 ld/testsuite/ld-elf/dlempty.list              |  3 ++
 ld/testsuite/ld-elf/shared.exp                | 12 ++++++
 11 files changed, 129 insertions(+)
 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.exp
 create mode 100644 ld/testsuite/ld-dynamic/export-dynamic-symbol.s
 create mode 100644 ld/testsuite/ld-dynamic/foo.s
 create mode 100644 ld/testsuite/ld-elf/dlempty.list

diff --git a/ld/ld.texi b/ld/ld.texi
index 4dc78e65fa..042d96f303 100644
--- a/ld/ld.texi
+++ b/ld/ld.texi
@@ -569,6 +569,17 @@  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.
+
 @ifclear SingleFormat
 @cindex big-endian objects
 @cindex endianness
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..0e49be8ded 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},
@@ -582,6 +584,8 @@  parse_args (unsigned argc, char **argv)
     dynamic_list
   } opt_dynamic_list = dynamic_list_unset;
 
+  struct bfd_sym_chain export_dynamic_symbol_list = { NULL, NULL };
+
   shortopts = (char *) xmalloc (OPTION_COUNT * 3 + 2);
   longopts = (struct option *)
       xmalloc (sizeof (*longopts) * (OPTION_COUNT + 1));
@@ -1425,6 +1429,15 @@  parse_args (unsigned argc, char **argv)
 	  if (opt_symbolic == symbolic)
 	    opt_symbolic = symbolic_unset;
 	  break;
+	case OPTION_EXPORT_DYNAMIC_SYMBOL:
+	  {
+	    struct bfd_sym_chain *sym;
+	    sym = stat_alloc (sizeof (*sym));
+	    sym->name = xstrdup (optarg);
+	    sym->next = export_dynamic_symbol_list.next;
+	    export_dynamic_symbol_list.next = sym;
+	  }
+	  break;
 	case OPTION_WARN_COMMON:
 	  config.warn_common = TRUE;
 	  break;
@@ -1659,6 +1672,17 @@  parse_args (unsigned argc, char **argv)
 	break;
       }
 
+  if (opt_dynamic_list != dynamic_list_unset || !bfd_link_dll (&link_info))
+    {
+      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 (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.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.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-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..c5b6fb7736 100644
--- a/ld/testsuite/ld-elf/shared.exp
+++ b/ld/testsuite/ld-elf/shared.exp
@@ -598,6 +598,12 @@  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 libdl4a.so with --dynamic-list=dl4.list"
    "-shared -Wl,--dynamic-list=dl4.list" "-fPIC"
    {dl4.c dl4xxx.c} {} "libdl4a.so"}
@@ -874,6 +880,12 @@  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 libdl4a.so" \
      "-Wl,--no-as-needed tmpdir/libdl4a.so" "" \
      {dl4main.c} "dl4a" "dl4a.out" ] \
-- 
2.26.2.526.g744177e7f7-goog