This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
Re: [PATCH] PR ld/21903: Treat common symbol as undefined for --no-define-common
- From: "H.J. Lu" <hjl dot tools at gmail dot com>
- To: Binutils <binutils at sourceware dot org>
- Date: Sun, 6 Aug 2017 07:53:33 -0700
- Subject: Re: [PATCH] PR ld/21903: Treat common symbol as undefined for --no-define-common
- Authentication-results: sourceware.org; auth=none
- References: <20170804122212.GA15481@gmail.com>
On Fri, Aug 4, 2017 at 5:22 AM, H.J. Lu <hjl.tools@gmail.com> wrote:
> When --no-define-common is used to build shared library, treat common
> symbol as undefined so that common symbols that are referenced from a
> shared library to be assigned addresses only in the main program. This
> eliminates the unused duplicate space in the shared library, and also
> prevents any possible confusion over resolving to the wrong duplicate
> when there are many dynamic modules with specialized search paths for
> runtime symbol resolution.
>
> --no-define-common is only allowed when building a shared library.
>
> OK for master?
I am going to check it in.
> H.J.
> ---
> bfd/
>
> PR ld/21903:
> * elflink.c (elf_link_add_object_symbols): Treat common symbol
> as undefined for --no-define-common.
>
> include/
>
> PR ld/21903:
> * bfdlink.h (bfd_link_info): Add inhibit_common_definition.
>
> ld/
>
> PR ld/21903:
> * ld.h (command_line): Remove inhibit_common_definition.
> * ldgram.y: Replace command_line.inhibit_common_definition with
> link_info.inhibit_common_definition.
> * ldlang.c (lang_common): Likewise.
> * lexsup.c (parse_args): Likewise.
> * ldmain.c (main): Only allow --no-define-common with -shared.
> * testsuite/ld-elf/pr21903.s: New file.
> * testsuite/ld-elf/pr21903a.d: Likewise.
> * testsuite/ld-elf/pr21903b.d: Likewise.
> * testsuite/ld-elf/pr21903c.d: Likewise.
> * testsuite/ld-elf/pr21903d.d: Likewise.
> * testsuite/ld-elf/pr21903e.d: Likewise.
> ---
> bfd/elflink.c | 5 +++++
> include/bfdlink.h | 3 +++
> ld/ld.h | 3 ---
> ld/ldgram.y | 2 +-
> ld/ldlang.c | 2 +-
> ld/ldmain.c | 3 +++
> ld/lexsup.c | 2 +-
> ld/testsuite/ld-elf/pr21903.s | 15 +++++++++++++++
> ld/testsuite/ld-elf/pr21903a.d | 8 ++++++++
> ld/testsuite/ld-elf/pr21903b.d | 8 ++++++++
> ld/testsuite/ld-elf/pr21903c.d | 3 +++
> ld/testsuite/ld-elf/pr21903d.d | 4 ++++
> ld/testsuite/ld-elf/pr21903e.d | 3 +++
> 13 files changed, 55 insertions(+), 6 deletions(-)
> create mode 100644 ld/testsuite/ld-elf/pr21903.s
> create mode 100644 ld/testsuite/ld-elf/pr21903a.d
> create mode 100644 ld/testsuite/ld-elf/pr21903b.d
> create mode 100644 ld/testsuite/ld-elf/pr21903c.d
> create mode 100644 ld/testsuite/ld-elf/pr21903d.d
> create mode 100644 ld/testsuite/ld-elf/pr21903e.d
>
> diff --git a/bfd/elflink.c b/bfd/elflink.c
> index eff53acbbe..0cc5f871db 100644
> --- a/bfd/elflink.c
> +++ b/bfd/elflink.c
> @@ -4250,6 +4250,11 @@ error_free_dyn:
>
> override = FALSE;
>
> + /* Treat common symbol as undefined for --no-define-common. */
> + if (isym->st_shndx == SHN_COMMON
> + && info->inhibit_common_definition)
> + isym->st_shndx = SHN_UNDEF;
> +
> flags = BSF_NO_FLAGS;
> sec = NULL;
> value = isym->st_value;
> diff --git a/include/bfdlink.h b/include/bfdlink.h
> index e7c7836f7f..2370c0d45a 100644
> --- a/include/bfdlink.h
> +++ b/include/bfdlink.h
> @@ -489,6 +489,9 @@ struct bfd_link_info
> /* TRUE if generate a 1-byte NOP as suffix for x86 call instruction. */
> unsigned int call_nop_as_suffix : 1;
>
> + /* TRUE if common symbols should be treated as undefined. */
> + unsigned int inhibit_common_definition : 1;
> +
> /* The 1-byte NOP for x86 call instruction. */
> char call_nop_byte;
>
> diff --git a/ld/ld.h b/ld/ld.h
> index 162e156f08..c6fa1247f0 100644
> --- a/ld/ld.h
> +++ b/ld/ld.h
> @@ -132,9 +132,6 @@ typedef struct
> /* 1 => assign space to common symbols even if `relocatable_output'. */
> bfd_boolean force_common_definition;
>
> - /* 1 => do not assign addresses to common symbols. */
> - bfd_boolean inhibit_common_definition;
> -
> /* If TRUE, build MIPS embedded PIC relocation tables in the output
> file. */
> bfd_boolean embedded_relocs;
> diff --git a/ld/ldgram.y b/ld/ldgram.y
> index 771d990a5c..e2998f1553 100644
> --- a/ld/ldgram.y
> +++ b/ld/ldgram.y
> @@ -339,7 +339,7 @@ ifile_p1:
> | FORCE_GROUP_ALLOCATION
> { command_line.force_group_allocation = TRUE ; }
> | INHIBIT_COMMON_ALLOCATION
> - { command_line.inhibit_common_definition = TRUE ; }
> + { link_info.inhibit_common_definition = TRUE ; }
> | INPUT '(' input_list ')'
> | GROUP
> { lang_enter_group (); }
> diff --git a/ld/ldlang.c b/ld/ldlang.c
> index b8b214dfdb..196b2ccc72 100644
> --- a/ld/ldlang.c
> +++ b/ld/ldlang.c
> @@ -6260,7 +6260,7 @@ lang_check (void)
> static void
> lang_common (void)
> {
> - if (command_line.inhibit_common_definition)
> + if (link_info.inhibit_common_definition)
> return;
> if (bfd_link_relocatable (&link_info)
> && !command_line.force_common_definition)
> diff --git a/ld/ldmain.c b/ld/ldmain.c
> index 5d1a3f46f5..cb1e2d158b 100644
> --- a/ld/ldmain.c
> +++ b/ld/ldmain.c
> @@ -395,6 +395,9 @@ main (int argc, char **argv)
> if (argc == 2 && version_printed)
> xexit (0);
>
> + if (link_info.inhibit_common_definition && !bfd_link_dll (&link_info))
> + einfo (_("%P%F: --no-define-common may not be used without -shared\n"));
> +
> if (!lang_has_input_file)
> {
> if (version_printed || command_line.print_output_format)
> diff --git a/ld/lexsup.c b/ld/lexsup.c
> index 08106bcc1a..effa277b16 100644
> --- a/ld/lexsup.c
> +++ b/ld/lexsup.c
> @@ -908,7 +908,7 @@ parse_args (unsigned argc, char **argv)
> input_flags.dynamic = FALSE;
> break;
> case OPTION_NO_DEFINE_COMMON:
> - command_line.inhibit_common_definition = TRUE;
> + link_info.inhibit_common_definition = TRUE;
> break;
> case OPTION_NO_DEMANGLE:
> demangling = FALSE;
> diff --git a/ld/testsuite/ld-elf/pr21903.s b/ld/testsuite/ld-elf/pr21903.s
> new file mode 100644
> index 0000000000..9dbf96c62e
> --- /dev/null
> +++ b/ld/testsuite/ld-elf/pr21903.s
> @@ -0,0 +1,15 @@
> + .text
> + .global start /* Used by SH targets. */
> +start:
> + .global _start
> +_start:
> + .global __start
> +__start:
> + .global main /* Used by HPPA targets. */
> +main:
> + .dc.a foo
> + .ifdef HPUX
> +foo .comm 4
> + .else
> + .comm foo, 4, 4
> + .endif
> diff --git a/ld/testsuite/ld-elf/pr21903a.d b/ld/testsuite/ld-elf/pr21903a.d
> new file mode 100644
> index 0000000000..020c5612e9
> --- /dev/null
> +++ b/ld/testsuite/ld-elf/pr21903a.d
> @@ -0,0 +1,8 @@
> +#source: pr21903.s
> +#ld: -shared --no-define-common
> +#readelf: --dyn-syms
> +#target: *-*-linux* *-*-gnu*
> +
> +#...
> +.*: 0+0 +0 +OBJECT +GLOBAL +DEFAULT +UND foo
> +#pass
> diff --git a/ld/testsuite/ld-elf/pr21903b.d b/ld/testsuite/ld-elf/pr21903b.d
> new file mode 100644
> index 0000000000..decd4f3e27
> --- /dev/null
> +++ b/ld/testsuite/ld-elf/pr21903b.d
> @@ -0,0 +1,8 @@
> +#source: pr21903.s
> +#ld: -shared
> +#readelf: --dyn-syms
> +#target: *-*-linux* *-*-gnu*
> +
> +#...
> +.*: [0-9a-f]+ +4 +OBJECT +GLOBAL +DEFAULT +[0-9]+ foo
> +#pass
> diff --git a/ld/testsuite/ld-elf/pr21903c.d b/ld/testsuite/ld-elf/pr21903c.d
> new file mode 100644
> index 0000000000..d3910ec79b
> --- /dev/null
> +++ b/ld/testsuite/ld-elf/pr21903c.d
> @@ -0,0 +1,3 @@
> +#source: pr21903.s
> +#ld: --no-define-common
> +#error: --no-define-common may not be used without -shared
> diff --git a/ld/testsuite/ld-elf/pr21903d.d b/ld/testsuite/ld-elf/pr21903d.d
> new file mode 100644
> index 0000000000..ec729007d1
> --- /dev/null
> +++ b/ld/testsuite/ld-elf/pr21903d.d
> @@ -0,0 +1,4 @@
> +#source: pr21903.s
> +#ld: --no-define-common -pie
> +#target: *-*-linux* *-*-gnu*
> +#error: --no-define-common may not be used without -shared
> diff --git a/ld/testsuite/ld-elf/pr21903e.d b/ld/testsuite/ld-elf/pr21903e.d
> new file mode 100644
> index 0000000000..894c595c43
> --- /dev/null
> +++ b/ld/testsuite/ld-elf/pr21903e.d
> @@ -0,0 +1,3 @@
> +#source: pr21903.s
> +#ld: -r --no-define-common
> +#error: --no-define-common may not be used without -shared
> --
> 2.13.3
>
--
H.J.