Treat common symbol as undefined for --no-define-common
authorH.J. Lu <hjl.tools@gmail.com>
Sun, 6 Aug 2017 15:18:53 +0000 (08:18 -0700)
committerH.J. Lu <hjl.tools@gmail.com>
Sun, 6 Aug 2017 15:19:04 +0000 (08:19 -0700)
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.

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.

16 files changed:
bfd/ChangeLog
bfd/elflink.c
include/ChangeLog
include/bfdlink.h
ld/ChangeLog
ld/ld.h
ld/ldgram.y
ld/ldlang.c
ld/ldmain.c
ld/lexsup.c
ld/testsuite/ld-elf/pr21903.s [new file with mode: 0644]
ld/testsuite/ld-elf/pr21903a.d [new file with mode: 0644]
ld/testsuite/ld-elf/pr21903b.d [new file with mode: 0644]
ld/testsuite/ld-elf/pr21903c.d [new file with mode: 0644]
ld/testsuite/ld-elf/pr21903d.d [new file with mode: 0644]
ld/testsuite/ld-elf/pr21903e.d [new file with mode: 0644]

index 63813e47f715e737a40707ec0e6583d66b73d9fa..7c58a866e54c5a7f7ee0db15e9b48a64a1488f23 100644 (file)
@@ -1,3 +1,9 @@
+2017-08-06  H.J. Lu  <hongjiu.lu@intel.com>
+
+       PR ld/21903:
+       * elflink.c (elf_link_add_object_symbols): Treat common symbol
+       as undefined for --no-define-common.
+
 2017-08-05  Alan Modra  <amodra@gmail.com>
 
        * elf32-hppa.c (elf32_hppa_set_gp): Don't require an
index eff53acbbe35bf569829b6e331a7274162c1b1c3..0cc5f871db914f0c66b16f93ad6db68e7c7eac7d 100644 (file)
@@ -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;
index 443cab06213cc8c077dae077a0722c7867a8e7e2..332ae9356c35728d11fb034634ec715d18ddd015 100644 (file)
@@ -1,3 +1,8 @@
+2017-08-06  H.J. Lu  <hongjiu.lu@intel.com>
+
+       PR ld/21903:
+       * bfdlink.h (bfd_link_info): Add inhibit_common_definition.
+
 2017-07-31  Nick Clifton  <nickc@redhat.com>
 
        PR 21850
index e7c7836f7fa3fc8fb7017f71fb2b808f7d515468..2370c0d45a3cec5d50bb2050069fadd645b52342 100644 (file)
@@ -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;
 
index eb002e99422e0002dd7a073dcf2c40cb5caf4302..a041f0a07480420ef6e99eabfa7f92421c2cf4a7 100644 (file)
@@ -1,3 +1,19 @@
+2017-08-06  H.J. Lu  <hongjiu.lu@intel.com>
+
+       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.
+
 2017-08-05  Alan Modra  <amodra@gmail.com>
 
        * testsuite/ld-unique/pr21529.d: Don't xfail hppa.
diff --git a/ld/ld.h b/ld/ld.h
index 162e156f0848bc73dc04b5cf67f22128caf3edb0..c6fa1247f00ef024426e4a8b40c8dd6962e8da86 100644 (file)
--- 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;
index 771d990a5c29efde02c9ab548411459f2aad64cf..e2998f15533456e51987b74d52dd2028773589b7 100644 (file)
@@ -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 (); }
index b8b214dfdb056ac183df9c879661b03e55dc80fc..196b2ccc729d97cf4f4b5fca9de371d4a007948f 100644 (file)
@@ -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)
index 5d1a3f46f556184aa65cfb1d2d9514ece1ac1ca2..cb1e2d158b7e509435b186d3d189d3567edb8df3 100644 (file)
@@ -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)
index 08106bcc1a9bd5d8b0aeb501c93351e25da6b479..effa277b16d1a29fa027e9fa675e800b0fcb70f6 100644 (file)
@@ -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 (file)
index 0000000..9dbf96c
--- /dev/null
@@ -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 (file)
index 0000000..020c561
--- /dev/null
@@ -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 (file)
index 0000000..decd4f3
--- /dev/null
@@ -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 (file)
index 0000000..d3910ec
--- /dev/null
@@ -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 (file)
index 0000000..ec72900
--- /dev/null
@@ -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 (file)
index 0000000..894c595
--- /dev/null
@@ -0,0 +1,3 @@
+#source: pr21903.s
+#ld: -r --no-define-common
+#error: --no-define-common may not be used without -shared