Properly implement STT_COMMON
authorH.J. Lu <hjl.tools@gmail.com>
Mon, 22 Feb 2016 17:18:52 +0000 (09:18 -0800)
committerH.J. Lu <hjl.tools@gmail.com>
Fri, 26 Feb 2016 13:01:34 +0000 (05:01 -0800)
The BFD configure option, --enable-elf-stt-common, can't be to used to
verify STT_COMMON implementation with the normal binutils build.  Instead,
this patch removes it from BFD.  It adds --elf-stt-common=[no|yes] to ELF
assembler/objcopy and adds -z common/-z nocommon to ld.

A configure option, --enable-elf-stt-common, is added to gas to specify
whether ELF assembler should generate common symbols with the STT_COMMON
type by default.

Since BSF_KEEP_G is never used, it is renamed to BSF_ELF_COMMON for ELF
common symbols.

bfd/

PR ld/19645
* bfd.c (bfd): Change flags to 20 bits.
(BFD_CONVERT_ELF_COMMON): New.
(BFD_USE_ELF_STT_COMMON): Likewise.
(BFD_FLAGS_SAVED): Add BFD_CONVERT_ELF_COMMON and
BFD_USE_ELF_STT_COMMON.
(BFD_FLAGS_FOR_BFD_USE_MASK): Likewise.
* configure.ac: Remove --enable-elf-stt-common.
* elf.c (swap_out_syms): Choose STT_COMMON or STT_OBJECT for
common symbol depending on BFD_CONVERT_ELF_COMMON and
BFD_USE_ELF_STT_COMMON.
* elfcode.h (elf_slurp_symbol_table): Set BSF_ELF_COMMON for
STT_COMMON.
* elflink.c (bfd_elf_link_mark_dynamic_symbol): Also check
STT_COMMON.
(elf_link_convert_common_type): New function.
(elf_link_output_extsym): Choose STT_COMMON or STT_OBJECT for
common symbol depending on BFD_CONVERT_ELF_COMMON and
BFD_USE_ELF_STT_COMMON.  Set sym.st_info after sym.st_shndx.
* elfxx-target.h (TARGET_BIG_SYM): Add BFD_CONVERT_ELF_COMMON
and BFD_USE_ELF_STT_COMMON to object_flags.
(TARGET_LITTLE_SYM): Likewise.
* syms.c (BSF_KEEP_G): Renamed to ...
(BSF_ELF_COMMON): This.
* bfd-in2.h: Regenerated.
* config.in: Likewise.
* configure: Likewise.

binutils/

PR ld/19645
* NEWS: Mention --elf-stt-common= for objcopy.
* doc/binutils.texi: Document --elf-stt-common= for objcopy.
* objcopy.c (do_elf_stt_common): New.
(command_line_switch): Add OPTION_ELF_STT_COMMON.
(copy_options): Add --elf-stt-common=.
(copy_usage): Add --elf-stt-common=.
(copy_object): Also check do_elf_stt_common for ELF targets.
(copy_file): Handle do_elf_stt_common.
(copy_main): Handle OPTION_ELF_STT_COMMON.
* readelf.c (apply_relocations): Support STT_COMMON.
* testsuite/binutils-all/common-1.s: New file.
* testsuite/binutils-all/common-1a.d: Likewise.
* testsuite/binutils-all/common-1b.d: Likewise.
* testsuite/binutils-all/common-1c.d: Likewise.
* testsuite/binutils-all/common-1d.d: Likewise.
* testsuite/binutils-all/common-1e.d: Likewise.
* testsuite/binutils-all/common-1f.d: Likewise.
* testsuite/binutils-all/common-2.s: Likewise.
* testsuite/binutils-all/common-2a.d: Likewise.
* testsuite/binutils-all/common-2b.d: Likewise.
* testsuite/binutils-all/common-2c.d: Likewise.
* testsuite/binutils-all/common-2d.d: Likewise.
* testsuite/binutils-all/common-2e.d: Likewise.
* testsuite/binutils-all/common-2f.d: Likewise.
* testsuite/binutils-all/objcopy.exp
(objcopy_test_elf_common_symbols): New proc.
Run objcopy_test_elf_common_symbols for ELF targets

gas/

PR ld/19645
* NEWS: Mention --enable-elf-stt-common and --elf-stt-common=
for ELF assemblers.
* as.c (flag_use_elf_stt_common): New.
(show_usage): Add --elf-stt-common=.
(option_values): Add OPTION_ELF_STT_COMMON.
(std_longopts): Add --elf-stt-common=.
(parse_args): Handle --elf-stt-common=.
* as.h (flag_use_elf_stt_common): New.
* config.in: Regenerated.
* configure: Likewise.
* configure.ac: Add --enable-elf-stt-common and define
DEFAULT_GENERATE_ELF_STT_COMMON.
* gas/write.c (write_object_file): Set BFD_CONVERT_ELF_COMMON
and BFD_USE_ELF_STT_COMMON if flag_use_elf_stt_common is set.
* doc/as.texinfo: Document --elf-stt-common=.
* testsuite/gas/elf/common3.s: New file.
* testsuite/gas/elf/common3a.d: Likewise.
* testsuite/gas/elf/common3b.d: Likewise.
* testsuite/gas/elf/common4.s: Likewise.
* testsuite/gas/elf/common4a.d: Likewise.
* testsuite/gas/elf/common4b.d: Likewise.
* testsuite/gas/i386/dw2-compress-3b.d: Likewise.
* testsuite/gas/i386/dw2-compressed-3b.d: Likewise.
* testsuite/gas/elf/elf.exp: Run common3a, common3b, common4a
and common4b.
* testsuite/gas/i386/dw2-compress-3.d: Renamed to ...
* testsuite/gas/i386/dw2-compress-3a.d: This.  Pass
--elf-stt-common=no to as.
* testsuite/gas/i386/dw2-compressed-3.d: Renamed to ...
* testsuite/gas/i386/dw2-compressed-3a.d: This.  Pass
--elf-stt-common=no to as.
* testsuite/gas/i386/i386.exp: Run dw2-compress-3a,
dw2-compress-3b, dw2-compressed-3a and dw2-compressed-3b instead
of dw2-compress-3 and dw2-compressed-3.

include/

PR ld/19645
* bfdlink.h (bfd_link_elf_stt_common): New enum.
(bfd_link_info): Add elf_stt_common.

ld/

PR ld/19645
* NEWS: Mention -z common/-z nocommon for ELF targets.
* emultempl/elf32.em (gld${EMULATION_NAME}_handle_option): Handle
-z common and -z nocommon.
* ld.texinfo: Document -z common/-z nocommon.
* lexsup.c (elf_shlib_list_options): Add -z common/-z nocommon.
* testsuite/ld-elf/tls_common.exp: Test --elf-stt-common=no and
--elf-stt-common=yes with assembler.
* testsuite/ld-elfcomm/common-1.s: New file.
* testsuite/ld-elfcomm/common-1a.d: Likewise.
* testsuite/ld-elfcomm/common-1b.d: Likewise.
* testsuite/ld-elfcomm/common-1c.d: Likewise.
* testsuite/ld-elfcomm/common-1d.d: Likewise.
* testsuite/ld-elfcomm/common-1e.d: Likewise.
* testsuite/ld-elfcomm/common-1f.d: Likewise.
* testsuite/ld-elfcomm/common-2.s: Likewise.
* testsuite/ld-elfcomm/common-2a.d: Likewise.
* testsuite/ld-elfcomm/common-2b.d: Likewise.
* testsuite/ld-elfcomm/common-2c.d: Likewise.
* testsuite/ld-elfcomm/common-2d.d: Likewise.
* testsuite/ld-elfcomm/common-2e.d: Likewise.
* testsuite/ld-elfcomm/common-2f.d: Likewise.
* testsuite/ld-elfcomm/common-3a.rd: Likewise.
* testsuite/ld-elfcomm/common-3b.rd: Likewise.
* testsuite/ld-i386/pr19645.d: Likewise.
* testsuite/ld-i386/pr19645.s: Likewise.
* testsuite/ld-x86-64/largecomm-1.s: Likewise.
* testsuite/ld-x86-64/largecomm-1a.d: Likewise.
* testsuite/ld-x86-64/largecomm-1b.d: Likewise.
* testsuite/ld-x86-64/largecomm-1c.d: Likewise.
* testsuite/ld-x86-64/largecomm-1d.d: Likewise.
* testsuite/ld-x86-64/largecomm-1e.d: Likewise.
* testsuite/ld-x86-64/largecomm-1f.d: Likewise.
* testsuite/ld-x86-64/pr19645.d: Likewise.
* testsuite/ld-x86-64/pr19645.s: Likewise.
* testsuite/ld-elfcomm/elfcomm.exp: Test --elf-stt-common=yes
with assembler.
(assembler_generates_commons): Removed.
Run -z common/-z nocommon tests.  Run *.d tests.
* testsuite/ld-i386/i386.exp: Run pr19645.
* testsuite/ld-x86-64/x86-64.exp: Likewise.
* testsuite/ld-x86-64/dwarfreloc.exp: Test --elf-stt-common with
assembler.  Test STT_COMMON with readelf.

89 files changed:
bfd/bfd-in2.h
bfd/bfd.c
bfd/config.in
bfd/configure
bfd/configure.ac
bfd/elf.c
bfd/elfcode.h
bfd/elflink.c
bfd/elfxx-target.h
bfd/syms.c
binutils/NEWS
binutils/doc/binutils.texi
binutils/objcopy.c
binutils/readelf.c
binutils/testsuite/binutils-all/common-1.s [new file with mode: 0644]
binutils/testsuite/binutils-all/common-1a.d [new file with mode: 0644]
binutils/testsuite/binutils-all/common-1b.d [new file with mode: 0644]
binutils/testsuite/binutils-all/common-1c.d [new file with mode: 0644]
binutils/testsuite/binutils-all/common-1d.d [new file with mode: 0644]
binutils/testsuite/binutils-all/common-1e.d [new file with mode: 0644]
binutils/testsuite/binutils-all/common-1f.d [new file with mode: 0644]
binutils/testsuite/binutils-all/common-2.s [new file with mode: 0644]
binutils/testsuite/binutils-all/common-2a.d [new file with mode: 0644]
binutils/testsuite/binutils-all/common-2b.d [new file with mode: 0644]
binutils/testsuite/binutils-all/common-2c.d [new file with mode: 0644]
binutils/testsuite/binutils-all/common-2d.d [new file with mode: 0644]
binutils/testsuite/binutils-all/common-2e.d [new file with mode: 0644]
binutils/testsuite/binutils-all/common-2f.d [new file with mode: 0644]
binutils/testsuite/binutils-all/objcopy.exp
gas/NEWS
gas/as.c
gas/as.h
gas/config.in
gas/configure
gas/configure.ac
gas/doc/as.texinfo
gas/testsuite/gas/elf/common3.s [new file with mode: 0644]
gas/testsuite/gas/elf/common3a.d [new file with mode: 0644]
gas/testsuite/gas/elf/common3b.d [new file with mode: 0644]
gas/testsuite/gas/elf/common4.s [new file with mode: 0644]
gas/testsuite/gas/elf/common4a.d [new file with mode: 0644]
gas/testsuite/gas/elf/common4b.d [new file with mode: 0644]
gas/testsuite/gas/elf/elf.exp
gas/testsuite/gas/i386/dw2-compress-3.d [deleted file]
gas/testsuite/gas/i386/dw2-compress-3a.d [new file with mode: 0644]
gas/testsuite/gas/i386/dw2-compress-3b.d [new file with mode: 0644]
gas/testsuite/gas/i386/dw2-compressed-3.d [deleted file]
gas/testsuite/gas/i386/dw2-compressed-3a.d [new file with mode: 0644]
gas/testsuite/gas/i386/dw2-compressed-3b.d [new file with mode: 0644]
gas/testsuite/gas/i386/i386.exp
gas/write.c
include/bfdlink.h
ld/NEWS
ld/emultempl/elf32.em
ld/ld.texinfo
ld/lexsup.c
ld/testsuite/ld-elf/tls_common.exp
ld/testsuite/ld-elfcomm/common-1.s [new file with mode: 0644]
ld/testsuite/ld-elfcomm/common-1a.d [new file with mode: 0644]
ld/testsuite/ld-elfcomm/common-1b.d [new file with mode: 0644]
ld/testsuite/ld-elfcomm/common-1c.d [new file with mode: 0644]
ld/testsuite/ld-elfcomm/common-1d.d [new file with mode: 0644]
ld/testsuite/ld-elfcomm/common-1e.d [new file with mode: 0644]
ld/testsuite/ld-elfcomm/common-1f.d [new file with mode: 0644]
ld/testsuite/ld-elfcomm/common-2.s [new file with mode: 0644]
ld/testsuite/ld-elfcomm/common-2a.d [new file with mode: 0644]
ld/testsuite/ld-elfcomm/common-2b.d [new file with mode: 0644]
ld/testsuite/ld-elfcomm/common-2c.d [new file with mode: 0644]
ld/testsuite/ld-elfcomm/common-2d.d [new file with mode: 0644]
ld/testsuite/ld-elfcomm/common-2e.d [new file with mode: 0644]
ld/testsuite/ld-elfcomm/common-2f.d [new file with mode: 0644]
ld/testsuite/ld-elfcomm/common-3a.rd [new file with mode: 0644]
ld/testsuite/ld-elfcomm/common-3b.rd [new file with mode: 0644]
ld/testsuite/ld-elfcomm/dummy.s [new file with mode: 0644]
ld/testsuite/ld-elfcomm/elfcomm.exp
ld/testsuite/ld-i386/i386.exp
ld/testsuite/ld-i386/pr19645.d [new file with mode: 0644]
ld/testsuite/ld-i386/pr19645.s [new file with mode: 0644]
ld/testsuite/ld-x86-64/dwarfreloc.exp
ld/testsuite/ld-x86-64/largecomm-1.s [new file with mode: 0644]
ld/testsuite/ld-x86-64/largecomm-1a.d [new file with mode: 0644]
ld/testsuite/ld-x86-64/largecomm-1b.d [new file with mode: 0644]
ld/testsuite/ld-x86-64/largecomm-1c.d [new file with mode: 0644]
ld/testsuite/ld-x86-64/largecomm-1d.d [new file with mode: 0644]
ld/testsuite/ld-x86-64/largecomm-1e.d [new file with mode: 0644]
ld/testsuite/ld-x86-64/largecomm-1f.d [new file with mode: 0644]
ld/testsuite/ld-x86-64/pr19645.d [new file with mode: 0644]
ld/testsuite/ld-x86-64/pr19645.s [new file with mode: 0644]
ld/testsuite/ld-x86-64/x86-64.exp

index 612ab4b5644677de6507cd848ddaddc8f8d93deb..dd7fb1a33be5fec976332f62d6cae332037d4e69 100644 (file)
@@ -6378,7 +6378,9 @@ typedef struct bfd_symbol
 
   /* Used by the linker.  */
 #define BSF_KEEP               (1 << 5)
-#define BSF_KEEP_G             (1 << 6)
+
+  /* An ELF common symbol.  */
+#define BSF_ELF_COMMON         (1 << 6)
 
   /* A weak global symbol, overridable without warnings by
      a regular global symbol of the same name.  */
@@ -6570,7 +6572,7 @@ struct bfd
   ENUM_BITFIELD (bfd_direction) direction : 2;
 
   /* Format_specific flags.  */
-  flagword flags : 18;
+  flagword flags : 20;
 
   /* Values that may appear in the flags field of a BFD.  These also
      appear in the object_flags field of the bfd_target structure, where
@@ -6650,16 +6652,23 @@ struct bfd
   /* Compress sections in this BFD with SHF_COMPRESSED from gABI.  */
 #define BFD_COMPRESS_GABI 0x20000
 
+  /* Convert ELF common symbol type to STT_COMMON or STT_OBJECT in this
+     BFD.  */
+#define BFD_CONVERT_ELF_COMMON 0x40000
+
+  /* Use the ELF STT_COMMON type in this BFD.  */
+#define BFD_USE_ELF_STT_COMMON 0x80000
+
   /* Flags bits to be saved in bfd_preserve_save.  */
 #define BFD_FLAGS_SAVED \
   (BFD_IN_MEMORY | BFD_COMPRESS | BFD_DECOMPRESS | BFD_PLUGIN \
-   | BFD_COMPRESS_GABI)
+   | BFD_COMPRESS_GABI | BFD_CONVERT_ELF_COMMON | BFD_USE_ELF_STT_COMMON)
 
   /* Flags bits which are for BFD use only.  */
 #define BFD_FLAGS_FOR_BFD_USE_MASK \
   (BFD_IN_MEMORY | BFD_COMPRESS | BFD_DECOMPRESS | BFD_LINKER_CREATED \
    | BFD_PLUGIN | BFD_TRADITIONAL_FORMAT | BFD_DETERMINISTIC_OUTPUT \
-   | BFD_COMPRESS_GABI)
+   | BFD_COMPRESS_GABI | BFD_CONVERT_ELF_COMMON | BFD_USE_ELF_STT_COMMON)
 
   /* Is the file descriptor being cached?  That is, can it be closed as
      needed, and re-opened when accessed later?  */
index 58c27c9d480a1fe82a33fbcf7510644152473e1f..7400c4ed5d24d69aba6c5f6a9e036b93f7c03915 100644 (file)
--- a/bfd/bfd.c
+++ b/bfd/bfd.c
@@ -91,7 +91,7 @@ CODE_FRAGMENT
 .  ENUM_BITFIELD (bfd_direction) direction : 2;
 .
 .  {* Format_specific flags.  *}
-.  flagword flags : 18;
+.  flagword flags : 20;
 .
 .  {* Values that may appear in the flags field of a BFD.  These also
 .     appear in the object_flags field of the bfd_target structure, where
@@ -171,16 +171,23 @@ CODE_FRAGMENT
 .  {* Compress sections in this BFD with SHF_COMPRESSED from gABI.  *}
 .#define BFD_COMPRESS_GABI 0x20000
 .
+.  {* Convert ELF common symbol type to STT_COMMON or STT_OBJECT in this
+.     BFD.  *}
+.#define BFD_CONVERT_ELF_COMMON 0x40000
+.
+.  {* Use the ELF STT_COMMON type in this BFD.  *}
+.#define BFD_USE_ELF_STT_COMMON 0x80000
+.
 .  {* Flags bits to be saved in bfd_preserve_save.  *}
 .#define BFD_FLAGS_SAVED \
 .  (BFD_IN_MEMORY | BFD_COMPRESS | BFD_DECOMPRESS | BFD_PLUGIN \
-.   | BFD_COMPRESS_GABI)
+.   | BFD_COMPRESS_GABI | BFD_CONVERT_ELF_COMMON | BFD_USE_ELF_STT_COMMON)
 .
 .  {* Flags bits which are for BFD use only.  *}
 .#define BFD_FLAGS_FOR_BFD_USE_MASK \
 .  (BFD_IN_MEMORY | BFD_COMPRESS | BFD_DECOMPRESS | BFD_LINKER_CREATED \
 .   | BFD_PLUGIN | BFD_TRADITIONAL_FORMAT | BFD_DETERMINISTIC_OUTPUT \
-.   | BFD_COMPRESS_GABI)
+.   | BFD_COMPRESS_GABI | BFD_CONVERT_ELF_COMMON | BFD_USE_ELF_STT_COMMON)
 .
 .  {* Is the file descriptor being cached?  That is, can it be closed as
 .     needed, and re-opened when accessed later?  *}
index 58248bd9b7c359a47d09903981a3d0eb255829cf..cffadbb21920b3b3fc9a63eb89a7c282b6ba35b6 100644 (file)
 /* Define if we should default to creating read-only plt entries */
 #undef USE_SECUREPLT
 
-/* Define if we may generate symbols with ELF's STT_COMMON type */
-#undef USE_STT_COMMON
-
 /* Enable extensions on AIX 3, Interix.  */
 #ifndef _ALL_SOURCE
 # undef _ALL_SOURCE
index c37664445142b2fe7ae1c0d6f34b11655aa24941..1229323a89f734d54ed5b227de3731204e7cd3f8 100755 (executable)
@@ -791,7 +791,6 @@ with_mmap
 enable_secureplt
 enable_leading_mingw64_underscores
 with_separate_debug_dir
-enable_elf_stt_common
 with_pkgversion
 with_bugurl
 enable_werror
@@ -1444,7 +1443,6 @@ Optional Features:
   --enable-secureplt      Default to creating read-only plt entries
   --enable-leading-mingw64-underscores
                           Enable leading underscores on 64 bit mingw targets
-  --enable-elf-stt-common Allow the generation of ELF symbols with the STT_COMMON type
   --enable-werror         treat compile warnings as errors
   --enable-build-warnings enable build-time compiler warnings
   --enable-maintainer-mode  enable make rules and dependencies not useful
@@ -11423,7 +11421,7 @@ else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<_LT_EOF
-#line 11426 "configure"
+#line 11424 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -11529,7 +11527,7 @@ else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<_LT_EOF
-#line 11532 "configure"
+#line 11530 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
 
 
 
-# Check to see if we should allow the generation of
-# symbols with the ELF standard's STT_COMMON type.
-# Check whether --enable-elf-stt-common was given.
-if test "${enable_elf_stt_common+set}" = set; then :
-  enableval=$enable_elf_stt_common; case "${enableval}" in
-  yes) want_elf_stt_common=true ;;
-  no)  want_elf_stt_common=false ;;
-  *)   as_fn_error "bad value ${enableval} for ELF STT_COMMON option" "$LINENO" 5 ;;
- esac
-else
-  # We have to choose a default behaviour.  For native builds we could
-# test whether the loader supports the STT_COMMON type, but that would
-# mean that built binaries could not be exported to older systems where
-# the loader does not support it. So by default we always choose to
-# disable this feature.
-  want_elf_stt_common=false
-fi
-if test $want_elf_stt_common = true; then
-
-$as_echo "#define USE_STT_COMMON 1" >>confdefs.h
-
-fi
-
 
 
 # Check whether --with-pkgversion was given.
index b69891c56ab81121eff1bd14d831d927b6ebd867..f57d4d78dc2473f1a6687940208c7f7e6e5886f2 100644 (file)
@@ -103,26 +103,6 @@ AC_ARG_WITH(separate-debug-dir,
 [DEBUGDIR="${withval}"])
 AC_SUBST(DEBUGDIR)
 
-# Check to see if we should allow the generation of
-# symbols with the ELF standard's STT_COMMON type.
-AC_ARG_ENABLE(elf-stt-common,
-[  --enable-elf-stt-common Allow the generation of ELF symbols with the STT_COMMON type],
-[case "${enableval}" in
-  yes) want_elf_stt_common=true ;;
-  no)  want_elf_stt_common=false ;;
-  *)   AC_MSG_ERROR(bad value ${enableval} for ELF STT_COMMON option) ;;
- esac],
-# We have to choose a default behaviour.  For native builds we could
-# test whether the loader supports the STT_COMMON type, but that would
-# mean that built binaries could not be exported to older systems where
-# the loader does not support it. So by default we always choose to
-# disable this feature.
-  want_elf_stt_common=false)dnl
-if test $want_elf_stt_common = true; then
-  AC_DEFINE(USE_STT_COMMON, 1,
-    [Define if we may generate symbols with ELF's STT_COMMON type])
-fi
-
 ACX_PKGVERSION([GNU Binutils])
 ACX_BUGURL([http://www.sourceware.org/bugzilla/])
 
index 30112ae90023a106e0d441364a7b9f0a7a29fba4..1013644b95ed833f8e3a66fc7c7fd39af8a5233f 100644 (file)
--- a/bfd/elf.c
+++ b/bfd/elf.c
@@ -7470,12 +7470,16 @@ Unable to find equivalent output section for symbol '%s' from section '%s'"),
        }
       else if (bfd_is_com_section (syms[idx]->section))
        {
-#ifdef USE_STT_COMMON
-         if (type == STT_OBJECT)
-           sym.st_info = ELF_ST_INFO (STB_GLOBAL, STT_COMMON);
-         else
-#endif
-           sym.st_info = ELF_ST_INFO (STB_GLOBAL, type);
+         if (type != STT_TLS)
+           {
+             if ((abfd->flags & BFD_CONVERT_ELF_COMMON))
+               type = ((abfd->flags & BFD_USE_ELF_STT_COMMON)
+                       ? STT_COMMON : STT_OBJECT);
+             else
+               type = ((flags & BSF_ELF_COMMON) != 0
+                       ? STT_COMMON : STT_OBJECT);
+           }
+         sym.st_info = ELF_ST_INFO (STB_GLOBAL, type);
        }
       else if (bfd_is_und_section (syms[idx]->section))
        sym.st_info = ELF_ST_INFO (((flags & BSF_WEAK)
index 7223dd3756db9921647f51474ea6b2b004f3ee06..79a14f3e3342e81860e8f5dda5de0972c4c42fcf 100644 (file)
@@ -1302,6 +1302,7 @@ elf_slurp_symbol_table (bfd *abfd, asymbol **symptrs, bfd_boolean dynamic)
            case STT_COMMON:
              /* FIXME: Do we have to put the size field into the value field
                 as we do with symbols in SHN_COMMON sections (see above) ?  */
+             sym->symbol.flags |= BSF_ELF_COMMON;
              /* Fall through.  */
            case STT_OBJECT:
              sym->symbol.flags |= BSF_OBJECT;
index 993e9b91628385ed384394f89d46bcbe3867200d..0e3abff5ce4aef94767dd2863f042104c331c429 100644 (file)
@@ -525,8 +525,10 @@ bfd_elf_link_mark_dynamic_symbol (struct bfd_link_info *info,
 
   if ((info->dynamic_data
        && (h->type == STT_OBJECT
+          || h->type == STT_COMMON
           || (sym != NULL
-              && ELF_ST_TYPE (sym->st_info) == STT_OBJECT)))
+              && (ELF_ST_TYPE (sym->st_info) == STT_OBJECT
+                  || ELF_ST_TYPE (sym->st_info) == STT_COMMON))))
       || (d != NULL
          && h->root.type == bfd_link_hash_new
          && (*d->match) (&d->head, NULL, h->root.root.string)))
@@ -9038,6 +9040,28 @@ elf_link_check_versioned_symbol (struct bfd_link_info *info,
   return FALSE;
 }
 
+/* Convert ELF common symbol TYPE.  */
+
+static int
+elf_link_convert_common_type (struct bfd_link_info *info, int type)
+{
+  /* Commom symbol can only appear in relocatable link.  */
+  if (!bfd_link_relocatable (info))
+    abort ();
+  switch (info->elf_stt_common)
+    {
+    case unchanged:
+      break;
+    case elf_stt_common:
+      type = STT_COMMON;
+      break;
+    case no_elf_stt_common:
+      type = STT_OBJECT;
+      break;
+    }
+  return type;
+}
+
 /* Add an external symbol to the symbol table.  This is called from
    the hash table traversal routine.  When generating a shared object,
    we go through the symbol table twice.  The first time we output
@@ -9057,6 +9081,7 @@ elf_link_output_extsym (struct bfd_hash_entry *bh, void *data)
   const struct elf_backend_data *bed;
   long indx;
   int ret;
+  unsigned int type;
   /* A symbol is bound locally if it is forced local or it is locally
      defined, hidden versioned, not referenced by shared library and
      not exported when linking executable.  */
@@ -9191,35 +9216,21 @@ elf_link_output_extsym (struct bfd_hash_entry *bh, void *data)
           && (h->root.u.undef.abfd->flags & BFD_PLUGIN) != 0)
     strip = TRUE;
 
+  type = h->type;
+
   /* If we're stripping it, and it's not a dynamic symbol, there's
      nothing else to do.   However, if it is a forced local symbol or
      an ifunc symbol we need to give the backend finish_dynamic_symbol
      function a chance to make it dynamic.  */
   if (strip
       && h->dynindx == -1
-      && h->type != STT_GNU_IFUNC
+      && type != STT_GNU_IFUNC
       && !h->forced_local)
     return TRUE;
 
   sym.st_value = 0;
   sym.st_size = h->size;
   sym.st_other = h->other;
-  if (local_bind)
-    {
-      sym.st_info = ELF_ST_INFO (STB_LOCAL, h->type);
-      /* Turn off visibility on local symbol.  */
-      sym.st_other &= ~ELF_ST_VISIBILITY (-1);
-    }
-  /* Set STB_GNU_UNIQUE only if symbol is defined in regular object.  */
-  else if (h->unique_global && h->def_regular)
-    sym.st_info = ELF_ST_INFO (STB_GNU_UNIQUE, h->type);
-  else if (h->root.type == bfd_link_hash_undefweak
-          || h->root.type == bfd_link_hash_defweak)
-    sym.st_info = ELF_ST_INFO (STB_WEAK, h->type);
-  else
-    sym.st_info = ELF_ST_INFO (STB_GLOBAL, h->type);
-  sym.st_target_internal = h->target_internal;
-
   switch (h->root.type)
     {
     default:
@@ -9294,6 +9305,42 @@ elf_link_output_extsym (struct bfd_hash_entry *bh, void *data)
       return TRUE;
     }
 
+  if (type == STT_COMMON || type == STT_OBJECT)
+    switch (h->root.type)
+      {
+      case bfd_link_hash_common:
+       type = elf_link_convert_common_type (flinfo->info, type);
+       break;
+      case bfd_link_hash_defined:
+      case bfd_link_hash_defweak:
+       if (bed->common_definition (&sym))
+         type = elf_link_convert_common_type (flinfo->info, type);
+       else
+         type = STT_OBJECT;
+       break;
+      case bfd_link_hash_undefined:
+      case bfd_link_hash_undefweak:
+       break;
+      default:
+       abort ();
+      }
+
+  if (local_bind)
+    {
+      sym.st_info = ELF_ST_INFO (STB_LOCAL, type);
+      /* Turn off visibility on local symbol.  */
+      sym.st_other &= ~ELF_ST_VISIBILITY (-1);
+    }
+  /* Set STB_GNU_UNIQUE only if symbol is defined in regular object.  */
+  else if (h->unique_global && h->def_regular)
+    sym.st_info = ELF_ST_INFO (STB_GNU_UNIQUE, type);
+  else if (h->root.type == bfd_link_hash_undefweak
+          || h->root.type == bfd_link_hash_defweak)
+    sym.st_info = ELF_ST_INFO (STB_WEAK, type);
+  else
+    sym.st_info = ELF_ST_INFO (STB_GLOBAL, type);
+  sym.st_target_internal = h->target_internal;
+
   /* Give the processor backend a chance to tweak the symbol value,
      and also to finish up anything that needs to be done for this
      symbol.  FIXME: Not calling elf_backend_finish_dynamic_symbol for
@@ -9330,7 +9377,7 @@ elf_link_output_extsym (struct bfd_hash_entry *bh, void *data)
          || ELF_ST_BIND (sym.st_info) == STB_WEAK))
     {
       int bindtype;
-      unsigned int type = ELF_ST_TYPE (sym.st_info);
+      type = ELF_ST_TYPE (sym.st_info);
 
       /* Turn an undefined IFUNC symbol into a normal FUNC symbol. */
       if (type == STT_GNU_IFUNC)
index b3227ed3c521ad4e7dacbd0f0d433f4b45e4ba5f..ca30b1d9d1437accb3d50a5e5611e40f2dfb9a74 100644 (file)
@@ -850,7 +850,7 @@ const bfd_target TARGET_BIG_SYM =
   /* object_flags: mask of all file flags */
   (HAS_RELOC | EXEC_P | HAS_LINENO | HAS_DEBUG | HAS_SYMS | HAS_LOCALS
    | DYNAMIC | WP_TEXT | D_PAGED | BFD_COMPRESS | BFD_DECOMPRESS
-   | BFD_COMPRESS_GABI),
+   | BFD_COMPRESS_GABI | BFD_CONVERT_ELF_COMMON | BFD_USE_ELF_STT_COMMON),
 
   /* section_flags: mask of all section flags */
   (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_READONLY
@@ -949,7 +949,7 @@ const bfd_target TARGET_LITTLE_SYM =
   /* object_flags: mask of all file flags */
   (HAS_RELOC | EXEC_P | HAS_LINENO | HAS_DEBUG | HAS_SYMS | HAS_LOCALS
    | DYNAMIC | WP_TEXT | D_PAGED | BFD_COMPRESS | BFD_DECOMPRESS
-   | BFD_COMPRESS_GABI),
+   | BFD_COMPRESS_GABI | BFD_CONVERT_ELF_COMMON | BFD_USE_ELF_STT_COMMON),
 
   /* section_flags: mask of all section flags */
   (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_READONLY
index 5e860f9c102b86cc23794b49a85f5f80cdcd1ee2..118595d3d0f070c72983bb7f392f87b2a582eb99 100644 (file)
@@ -231,7 +231,9 @@ CODE_FRAGMENT
 .
 .  {* Used by the linker.  *}
 .#define BSF_KEEP              (1 << 5)
-.#define BSF_KEEP_G            (1 << 6)
+.
+.  {* An ELF common symbol.  *}
+.#define BSF_ELF_COMMON                (1 << 6)
 .
 .  {* A weak global symbol, overridable without warnings by
 .     a regular global symbol of the same name.  *}
index 6d68ade10f121504de83755816118e807c44442b..712604b0e4d7e327a9e0e6bd12785d3470b798c1 100644 (file)
@@ -1,5 +1,8 @@
 -*- text -*-
 
+* Add --elf-stt-common= option to objcopy for ELF targets to control
+  whether to convert common symbols to the STT_COMMON type.
+
 Changes in 2.26:
 
 * Add option to objcopy to insert new symbols into a file:
index 31ef8f2931c3986e3097441d07beed327d9e2b4a..a60ab66ee081dbf2cc9666e1f5ab620317d130fb 100644 (file)
@@ -1131,6 +1131,7 @@ objcopy [@option{-F} @var{bfdname}|@option{--target=}@var{bfdname}]
         [@option{--decompress-debug-sections}]
         [@option{--dwarf-depth=@var{n}}]
         [@option{--dwarf-start=@var{n}}]
+        [@option{--elf-stt-common=@var{val}}]
         [@option{-v}|@option{--verbose}]
         [@option{-V}|@option{--version}]
         [@option{--help}] [@option{--info}]
@@ -1886,6 +1887,14 @@ renamed.
 Decompress DWARF debug sections using zlib.  The original section
 names of the compressed sections are restored.
 
+@item --elf-stt-common=yes
+@itemx --elf-stt-common=no
+For ELF files, these options control whether common symbols should be
+converted to the @code{STT_COMMON} or @code{STT_OBJECT} type.
+@option{--elf-stt-common=yes} converts common symbol type to
+@code{STT_COMMON}. @option{--elf-stt-common=no} converts common symbol
+type to @code{STT_OBJECT}.
+
 @item -V
 @itemx --version
 Show the version number of @command{objcopy}.
index 8185f2830c89e207c771029756a3a7555f6f5a95..198ba3a2071e1670f33c9888d30db1342fd54e01 100644 (file)
@@ -220,6 +220,9 @@ static enum
   decompress = 1 << 4
 } do_debug_sections = nothing;
 
+/* Whether to generate ELF common symbols with the STT_COMMON type.  */
+static enum bfd_link_discard do_elf_stt_common = unchanged;
+
 /* Whether to change the leading character in symbol names.  */
 static bfd_boolean change_leading_char = FALSE;
 
@@ -294,6 +297,7 @@ enum command_line_switch
   OPTION_DEBUGGING,
   OPTION_DECOMPRESS_DEBUG_SECTIONS,
   OPTION_DUMP_SECTION,
+  OPTION_ELF_STT_COMMON,
   OPTION_EXTRACT_DWO,
   OPTION_EXTRACT_SYMBOL,
   OPTION_FILE_ALIGNMENT,
@@ -403,6 +407,7 @@ static struct option copy_options[] =
   {"discard-all", no_argument, 0, 'x'},
   {"discard-locals", no_argument, 0, 'X'},
   {"dump-section", required_argument, 0, OPTION_DUMP_SECTION},
+  {"elf-stt-common", required_argument, 0, OPTION_ELF_STT_COMMON},
   {"enable-deterministic-archives", no_argument, 0, 'D'},
   {"extract-dwo", no_argument, 0, OPTION_EXTRACT_DWO},
   {"extract-symbol", no_argument, 0, OPTION_EXTRACT_SYMBOL},
@@ -622,6 +627,8 @@ copy_usage (FILE *stream, int exit_status)
      --compress-debug-sections[={none|zlib|zlib-gnu|zlib-gabi}]\n\
                                    Compress DWARF debug sections using zlib\n\
      --decompress-debug-sections   Decompress DWARF debug sections using zlib\n\
+     --elf-stt-common=[yes|no]     Generate ELF common symbols with STT_COMMON\n\
+                                     type\n\
   -v --verbose                     List all object files modified\n\
   @<file>                          Read options from <file>\n\
   -V --version                     Display this program's version number\n\
@@ -1820,13 +1827,22 @@ copy_object (bfd *ibfd, bfd *obfd, const bfd_arch_info_type *input_arch)
       return FALSE;
     }
 
-  if ((do_debug_sections & compress) != 0
-      && do_debug_sections != compress
-      && ibfd->xvec->flavour != bfd_target_elf_flavour)
+  if (ibfd->xvec->flavour != bfd_target_elf_flavour)
     {
-      non_fatal (_("--compress-debug-sections=[zlib|zlib-gnu|zlib-gabi] is unsupported on `%s'"),
-                bfd_get_archive_filename (ibfd));
-      return FALSE;
+      if ((do_debug_sections & compress) != 0
+         && do_debug_sections != compress)
+       {
+         non_fatal (_("--compress-debug-sections=[zlib|zlib-gnu|zlib-gabi] is unsupported on `%s'"),
+                    bfd_get_archive_filename (ibfd));
+         return FALSE;
+       }
+
+      if (do_elf_stt_common)
+       {
+         non_fatal (_("--elf-stt-common=[yes|no] is unsupported on `%s'"),
+                    bfd_get_archive_filename (ibfd));
+         return FALSE;
+       }
     }
 
   if (verbose)
@@ -2767,6 +2783,19 @@ copy_file (const char *input_filename, const char *output_filename,
       break;
     }
 
+  switch (do_elf_stt_common)
+    {
+    case elf_stt_common:
+      ibfd->flags |= BFD_CONVERT_ELF_COMMON | BFD_USE_ELF_STT_COMMON;
+      break;
+      break;
+    case no_elf_stt_common:
+      ibfd->flags |= BFD_CONVERT_ELF_COMMON;
+      break;
+    default:
+      break;
+    }
+
   if (bfd_check_format (ibfd, bfd_archive))
     {
       bfd_boolean force_output_target;
@@ -4246,6 +4275,16 @@ copy_main (int argc, char *argv[])
          do_debug_sections = decompress;
          break;
 
+       case OPTION_ELF_STT_COMMON:
+         if (strcasecmp (optarg, "yes") == 0)
+           do_elf_stt_common = elf_stt_common;
+         else if (strcasecmp (optarg, "no") == 0)
+           do_elf_stt_common = no_elf_stt_common;
+         else
+           fatal (_("unrecognized --elf-stt-common= option `%s'"),
+                  optarg);
+         break;
+
        case OPTION_GAP_FILL:
          {
            bfd_vma gap_fill_vma;
index 7a755b4670884899e57fda98d0915fab8f71e8a3..a40453d367fcc0d527857de28d94232f7b1001f6 100644 (file)
@@ -11982,6 +11982,7 @@ apply_relocations (void *                     file,
             referencing a global array.  For an example of this see
             the _clz.o binary in libgcc.a.  */
          if (sym != symtab
+             && ELF_ST_TYPE (sym->st_info) != STT_COMMON
              && ELF_ST_TYPE (sym->st_info) > STT_SECTION)
            {
              warn (_("skipping unexpected symbol type %s in %ld'th relocation in section %s\n"),
diff --git a/binutils/testsuite/binutils-all/common-1.s b/binutils/testsuite/binutils-all/common-1.s
new file mode 100644 (file)
index 0000000..f684da4
--- /dev/null
@@ -0,0 +1 @@
+       .comm foobar,30,4
diff --git a/binutils/testsuite/binutils-all/common-1a.d b/binutils/testsuite/binutils-all/common-1a.d
new file mode 100644 (file)
index 0000000..f8c6fea
--- /dev/null
@@ -0,0 +1,8 @@
+#source: common-1.s
+#as: --elf-stt-common=yes
+#PROG: objcopy
+#readelf: -s -W
+
+#...
+ +[0-9]+: +0+4 +30 +COMMON +GLOBAL +DEFAULT +COM +foobar
+#pass
diff --git a/binutils/testsuite/binutils-all/common-1b.d b/binutils/testsuite/binutils-all/common-1b.d
new file mode 100644 (file)
index 0000000..5a56c6e
--- /dev/null
@@ -0,0 +1,8 @@
+#source: common-1.s
+#as: --elf-stt-common=no
+#PROG: objcopy
+#readelf: -s -W
+
+#...
+ +[0-9]+: +0+4 +30 +OBJECT +GLOBAL +DEFAULT +COM +foobar
+#pass
diff --git a/binutils/testsuite/binutils-all/common-1c.d b/binutils/testsuite/binutils-all/common-1c.d
new file mode 100644 (file)
index 0000000..bbdc49e
--- /dev/null
@@ -0,0 +1,9 @@
+#source: common-1.s
+#as: --elf-stt-common=yes
+#PROG: objcopy
+#objcopy: --elf-stt-common=no
+#readelf: -s -W
+
+#...
+ +[0-9]+: +0+4 +30 +OBJECT +GLOBAL +DEFAULT +COM +foobar
+#pass
diff --git a/binutils/testsuite/binutils-all/common-1d.d b/binutils/testsuite/binutils-all/common-1d.d
new file mode 100644 (file)
index 0000000..c0df029
--- /dev/null
@@ -0,0 +1,9 @@
+#source: common-1.s
+#as: --elf-stt-common=yes
+#PROG: objcopy
+#objcopy: --elf-stt-common=yes
+#readelf: -s -W
+
+#...
+ +[0-9]+: +0+4 +30 +COMMON +GLOBAL +DEFAULT +COM +foobar
+#pass
diff --git a/binutils/testsuite/binutils-all/common-1e.d b/binutils/testsuite/binutils-all/common-1e.d
new file mode 100644 (file)
index 0000000..9f84955
--- /dev/null
@@ -0,0 +1,9 @@
+#source: common-1.s
+#as: --elf-stt-common=no
+#PROG: objcopy
+#objcopy: --elf-stt-common=yes
+#readelf: -s -W
+
+#...
+ +[0-9]+: +0+4 +30 +COMMON +GLOBAL +DEFAULT +COM +foobar
+#pass
diff --git a/binutils/testsuite/binutils-all/common-1f.d b/binutils/testsuite/binutils-all/common-1f.d
new file mode 100644 (file)
index 0000000..bdbdca5
--- /dev/null
@@ -0,0 +1,9 @@
+#source: common-1.s
+#as: --elf-stt-common=no
+#PROG: objcopy
+#objcopy: --elf-stt-common=no
+#readelf: -s -W
+
+#...
+ +[0-9]+: +0+4 +30 +OBJECT +GLOBAL +DEFAULT +COM +foobar
+#pass
diff --git a/binutils/testsuite/binutils-all/common-2.s b/binutils/testsuite/binutils-all/common-2.s
new file mode 100644 (file)
index 0000000..bf2c26c
--- /dev/null
@@ -0,0 +1 @@
+       .tls_common foobar,30,4
diff --git a/binutils/testsuite/binutils-all/common-2a.d b/binutils/testsuite/binutils-all/common-2a.d
new file mode 100644 (file)
index 0000000..75e6217
--- /dev/null
@@ -0,0 +1,8 @@
+#source: common-2.s
+#as: --elf-stt-common=yes
+#PROG: objcopy
+#readelf: -s -W
+
+#...
+ +[0-9]+: +0+4 +30 +TLS +GLOBAL +DEFAULT +COM +foobar
+#pass
diff --git a/binutils/testsuite/binutils-all/common-2b.d b/binutils/testsuite/binutils-all/common-2b.d
new file mode 100644 (file)
index 0000000..7c7a194
--- /dev/null
@@ -0,0 +1,8 @@
+#source: common-2.s
+#as: --elf-stt-common=no
+#PROG: objcopy
+#readelf: -s -W
+
+#...
+ +[0-9]+: +0+4 +30 +TLS +GLOBAL +DEFAULT +COM +foobar
+#pass
diff --git a/binutils/testsuite/binutils-all/common-2c.d b/binutils/testsuite/binutils-all/common-2c.d
new file mode 100644 (file)
index 0000000..c203dd2
--- /dev/null
@@ -0,0 +1,9 @@
+#source: common-2.s
+#as: --elf-stt-common=yes
+#PROG: objcopy
+#objcopy: --elf-stt-common=yes
+#readelf: -s -W
+
+#...
+ +[0-9]+: +0+4 +30 +TLS +GLOBAL +DEFAULT +COM +foobar
+#pass
diff --git a/binutils/testsuite/binutils-all/common-2d.d b/binutils/testsuite/binutils-all/common-2d.d
new file mode 100644 (file)
index 0000000..da221d6
--- /dev/null
@@ -0,0 +1,9 @@
+#source: common-2.s
+#as: --elf-stt-common=yes
+#PROG: objcopy
+#objcopy: --elf-stt-common=no
+#readelf: -s -W
+
+#...
+ +[0-9]+: +0+4 +30 +TLS +GLOBAL +DEFAULT +COM +foobar
+#pass
diff --git a/binutils/testsuite/binutils-all/common-2e.d b/binutils/testsuite/binutils-all/common-2e.d
new file mode 100644 (file)
index 0000000..04b1faf
--- /dev/null
@@ -0,0 +1,9 @@
+#source: common-2.s
+#as: --elf-stt-common=no
+#PROG: objcopy
+#objcopy: --elf-stt-common=yes
+#readelf: -s -W
+
+#...
+ +[0-9]+: +0+4 +30 +TLS +GLOBAL +DEFAULT +COM +foobar
+#pass
diff --git a/binutils/testsuite/binutils-all/common-2f.d b/binutils/testsuite/binutils-all/common-2f.d
new file mode 100644 (file)
index 0000000..4748e5d
--- /dev/null
@@ -0,0 +1,9 @@
+#source: common-2.s
+#as: --elf-stt-common=no
+#PROG: objcopy
+#objcopy: --elf-stt-common=no
+#readelf: -s -W
+
+#...
+ +[0-9]+: +0+4 +30 +TLS +GLOBAL +DEFAULT +COM +foobar
+#pass
index b2c54ea3a6c88fa193c1d0a831f0cd5a1f90776f..c348578cd54fa490a8f45c7211bb90de37b2d6e2 100644 (file)
@@ -1005,6 +1005,23 @@ proc objcopy_test_symbol_manipulation {} {
     }
 }
 
+proc objcopy_test_elf_common_symbols {} {
+    global srcdir
+    global subdir
+
+    # hpux has a non-standard common directive.
+    if { [istarget "*-*-hpux*"] } then {
+       return
+    }
+
+    set test_list [lsort [glob -nocomplain $srcdir/$subdir/common-*.d]]
+    foreach t $test_list {
+        # We need to strip the ".d", but can leave the dirname.
+        verbose [file rootname $t]
+        run_dump_test [file rootname $t]
+    }
+}
+
 # ia64 specific tests
 if { ([istarget "ia64-*-elf*"]
        || [istarget "ia64-*-linux*"]) } {
@@ -1014,6 +1031,7 @@ if { ([istarget "ia64-*-elf*"]
 # ELF specific tests
 if [is_elf_format] {
     objcopy_test_symbol_manipulation
+    objcopy_test_elf_common_symbols
     objcopy_test "ELF unknown section type" unknown.s
     objcopy_test_readelf "ELF group" group.s
     objcopy_test_readelf "ELF group" group-2.s
index dd34a9f6dc3078e5ed96da2e2ce009798d0ba4d3..a627028de15653c9b8a5c0690eff41f4909258d0 100644 (file)
--- a/gas/NEWS
+++ b/gas/NEWS
@@ -1,4 +1,11 @@
 -*- text -*-
+* Add a configure option --enable-elf-stt-common to decide whether ELF
+  assembler should generate common symbols with the STT_COMMON type by
+  default.  Default to no.
+
+* New command line option --elf-stt-common= for ELF targets to control
+  whether to generate common symbols with the STT_COMMON type.
+
 * Add ability to set section flags and types via numeric values for ELF
   based targets.
 
index 55214f43904fddd2ec658debcdf5b81604c80ab4..14980b97c2c7be357f473a4838cee2fabf5924ac 100644 (file)
--- a/gas/as.c
+++ b/gas/as.c
@@ -96,6 +96,10 @@ int debug_memory = 0;
 /* Enable verbose mode.  */
 int verbose = 0;
 
+#if defined OBJ_ELF || defined OBJ_MAYBE_ELF
+int flag_use_elf_stt_common = DEFAULT_GENERATE_ELF_STT_COMMON;
+#endif
+
 /* Keep the output file.  */
 static int keep_it = 0;
 
@@ -300,6 +304,9 @@ Options:\n\
   --size-check=[error|warning]\n\
                          ELF .size directive check (default --size-check=error)\n"));
   fprintf (stream, _("\
+  --elf-stt-common=[no|yes]\n\
+                          generate ELF common symbols with STT_COMMON type\n"));
+  fprintf (stream, _("\
   --sectname-subst        enable section name substitution sequences\n"));
 #endif
   fprintf (stream, _("\
@@ -464,6 +471,7 @@ parse_args (int * pargc, char *** pargv)
       OPTION_EXECSTACK,
       OPTION_NOEXECSTACK,
       OPTION_SIZE_CHECK,
+      OPTION_ELF_STT_COMMON,
       OPTION_SECTNAME_SUBST,
       OPTION_ALTERNATE,
       OPTION_AL,
@@ -499,6 +507,7 @@ parse_args (int * pargc, char *** pargv)
     ,{"execstack", no_argument, NULL, OPTION_EXECSTACK}
     ,{"noexecstack", no_argument, NULL, OPTION_NOEXECSTACK}
     ,{"size-check", required_argument, NULL, OPTION_SIZE_CHECK}
+    ,{"elf-stt-common", required_argument, NULL, OPTION_ELF_STT_COMMON}
     ,{"sectname-subst", no_argument, NULL, OPTION_SECTNAME_SUBST}
 #endif
     ,{"fatal-warnings", no_argument, NULL, OPTION_WARN_FATAL}
@@ -868,6 +877,16 @@ This program has absolutely no warranty.\n"));
            as_fatal (_("Invalid --size-check= option: `%s'"), optarg);
          break;
 
+       case OPTION_ELF_STT_COMMON:
+         if (strcasecmp (optarg, "no") == 0)
+           flag_use_elf_stt_common = 0;
+         else if (strcasecmp (optarg, "yes") == 0)
+           flag_use_elf_stt_common = 1;
+         else
+           as_fatal (_("Invalid --elf-stt-common= option: `%s'"),
+                     optarg);
+         break;
+
        case OPTION_SECTNAME_SUBST:
          flag_sectname_subst = 1;
          break;
index bf1206faed17a4de8e8fddc41b6bd884886dd3b7..4e5601b536d0336d0097924483871fddae56fb1f 100644 (file)
--- a/gas/as.h
+++ b/gas/as.h
@@ -592,6 +592,9 @@ COMMON enum
   }
 flag_size_check;
 
+/* If we should generate ELF common symbols with the STT_COMMON type.  */
+extern int flag_use_elf_stt_common;
+
 /* If section name substitution sequences should be honored */
 COMMON int flag_sectname_subst;
 #endif
index 8b040fc50846f49db096bfe89f704fe9c9e98104..e06f16031c90e8b24c253b12345a8806b2840048 100644 (file)
 /* Define if you want compressed debug sections by default. */
 #undef DEFAULT_FLAG_COMPRESS_DEBUG
 
+/* Define to 1 if you want to generate ELF common symbols with the STT_COMMON
+   type by default. */
+#undef DEFAULT_GENERATE_ELF_STT_COMMON
+
 /* Define to 1 if you want to generate x86 relax relocations by default. */
 #undef DEFAULT_GENERATE_X86_RELAX_RELOCATIONS
 
index cd7182f2942db258f204bf8a948c20984c961c54..bc5a1ba415dda88322a48aca6fe5f9678e2ed98b 100755 (executable)
@@ -766,6 +766,7 @@ enable_targets
 enable_checking
 enable_compressed_debug_sections
 enable_x86_relax_relocations
+enable_elf_stt_common
 enable_werror
 enable_build_warnings
 enable_nls
@@ -1418,6 +1419,8 @@ Optional Features:
                           compress debug sections by default
   --enable-x86-relax-relocations
                           generate x86 relax relocations by default
+  --enable-elf-stt-common generate ELF common symbols with STT_COMMON type by
+                          default
   --enable-werror         treat compile warnings as errors
   --enable-build-warnings enable build-time compiler warnings
   --disable-nls           do not use Native Language Support
@@ -10975,7 +10978,7 @@ else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<_LT_EOF
-#line 10978 "configure"
+#line 10981 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -11081,7 +11084,7 @@ else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<_LT_EOF
-#line 11084 "configure"
+#line 11087 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -11694,6 +11697,17 @@ if test "${enable_x86_relax_relocations+set}" = set; then :
 esac
 fi
 
+# Decide if ELF assembler should generate common symbols with the
+# STT_COMMON type.
+ac_default_elf_stt_common=unset
+# Provide a configure time option to override our default.
+# Check whether --enable-elf_stt_common was given.
+if test "${enable_elf_stt_common+set}" = set; then :
+  enableval=$enable_elf_stt_common; case "${enableval}" in
+  yes)  ac_default_elf_stt_common=1 ;;
+esac
+fi
+
 using_cgen=no
 
 
@@ -12539,6 +12553,15 @@ cat >>confdefs.h <<_ACEOF
 _ACEOF
 
 
+if test ${ac_default_elf_stt_common} = unset; then
+  ac_default_elf_stt_common=0
+fi
+
+cat >>confdefs.h <<_ACEOF
+#define DEFAULT_GENERATE_ELF_STT_COMMON $ac_default_elf_stt_common
+_ACEOF
+
+
 if test x$ac_default_compressed_debug_sections = xyes ; then
 
 $as_echo "#define DEFAULT_FLAG_COMPRESS_DEBUG 1" >>confdefs.h
index 377526e72b48b9f5887733f9376ecdd0f09a0223..8f718258ab10f8e55aacdd4ca966d27b55068035 100644 (file)
@@ -88,6 +88,17 @@ AC_ARG_ENABLE(x86_relax_relocations,
   no)  ac_default_x86_relax_relocations=0 ;;
 esac])dnl
 
+# Decide if ELF assembler should generate common symbols with the
+# STT_COMMON type.
+ac_default_elf_stt_common=unset
+# Provide a configure time option to override our default.
+AC_ARG_ENABLE(elf_stt_common,
+             AS_HELP_STRING([--enable-elf-stt-common],
+             [generate ELF common symbols with STT_COMMON type by default]),
+[case "${enableval}" in
+  yes)  ac_default_elf_stt_common=1 ;;
+esac])dnl
+
 using_cgen=no
 
 AM_BINUTILS_WARNINGS
@@ -578,6 +589,14 @@ AC_DEFINE_UNQUOTED(DEFAULT_GENERATE_X86_RELAX_RELOCATIONS,
   $ac_default_x86_relax_relocations,
   [Define to 1 if you want to generate x86 relax relocations by default.])
 
+if test ${ac_default_elf_stt_common} = unset; then
+  ac_default_elf_stt_common=0
+fi
+AC_DEFINE_UNQUOTED(DEFAULT_GENERATE_ELF_STT_COMMON,
+  $ac_default_elf_stt_common,
+  [Define to 1 if you want to generate ELF common symbols with the
+   STT_COMMON type by default.])
+
 if test x$ac_default_compressed_debug_sections = xyes ; then
   AC_DEFINE(DEFAULT_FLAG_COMPRESS_DEBUG, 1, [Define if you want compressed debug sections by default.])
 fi
index 055e2f7223bda6b3bcb813634f784bce69237a69..a0584d33ecad52d15b322e7c2a178c8d7ca47b93 100644 (file)
@@ -242,6 +242,7 @@ gcc(1), ld(1), and the Info entries for @file{binutils} and @file{ld}.
  [@b{-W}] [@b{--warn}] [@b{--fatal-warnings}] [@b{-w}] [@b{-x}]
  [@b{-Z}] [@b{@@@var{FILE}}]
  [@b{--sectname-subst}] [@b{--size-check=[error|warning]}]
+ [@b{--elf-stt-common=[no|yes]}]
  [@b{--target-help}] [@var{target-options}]
  [@b{--}|@var{files} @dots{}]
 @c
@@ -712,10 +713,18 @@ will have its dwarf line number information placed into a section called
 then debug line section will still be called just @var{.debug_line} without any
 suffix.
 
+@ifset ELF
 @item --size-check=error
 @itemx --size-check=warning
 Issue an error or warning for invalid ELF .size directive.
 
+@item --elf-stt-common=no
+@itemx --elf-stt-common=yes
+These options control whether the ELF assembler should generate common
+symbols with the @code{STT_COMMON} type.  The default can be controlled
+by a configure option @option{--enable-elf-stt-common}.
+@end ifset
+
 @item --help
 Print a summary of the command line options and exit.
 
diff --git a/gas/testsuite/gas/elf/common3.s b/gas/testsuite/gas/elf/common3.s
new file mode 100644 (file)
index 0000000..f684da4
--- /dev/null
@@ -0,0 +1 @@
+       .comm foobar,30,4
diff --git a/gas/testsuite/gas/elf/common3a.d b/gas/testsuite/gas/elf/common3a.d
new file mode 100644 (file)
index 0000000..fa9d5ce
--- /dev/null
@@ -0,0 +1,7 @@
+#source: common3.s
+#as: --elf-stt-common=yes
+#readelf: -s -W
+
+#...
+ +[0-9]+: +0+4 +30 +COMMON +GLOBAL +DEFAULT +COM +foobar
+#pass
diff --git a/gas/testsuite/gas/elf/common3b.d b/gas/testsuite/gas/elf/common3b.d
new file mode 100644 (file)
index 0000000..9481d13
--- /dev/null
@@ -0,0 +1,7 @@
+#source: common3.s
+#as: --elf-stt-common=no
+#readelf: -s -W
+
+#...
+ +[0-9]+: +0+4 +30 +OBJECT +GLOBAL +DEFAULT +COM +foobar
+#pass
diff --git a/gas/testsuite/gas/elf/common4.s b/gas/testsuite/gas/elf/common4.s
new file mode 100644 (file)
index 0000000..bf2c26c
--- /dev/null
@@ -0,0 +1 @@
+       .tls_common foobar,30,4
diff --git a/gas/testsuite/gas/elf/common4a.d b/gas/testsuite/gas/elf/common4a.d
new file mode 100644 (file)
index 0000000..fceb01b
--- /dev/null
@@ -0,0 +1,7 @@
+#source: common4.s
+#as: --elf-stt-common=yes
+#readelf: -s -W
+
+#...
+ +[0-9]+: +0+4 +30 +TLS +GLOBAL +DEFAULT +COM +foobar
+#pass
diff --git a/gas/testsuite/gas/elf/common4b.d b/gas/testsuite/gas/elf/common4b.d
new file mode 100644 (file)
index 0000000..c18284e
--- /dev/null
@@ -0,0 +1,7 @@
+#source: common4.s
+#as: --elf-stt-common=no
+#readelf: -s -W
+
+#...
+ +[0-9]+: +0+4 +30 +TLS +GLOBAL +DEFAULT +COM +foobar
+#pass
index a2a86dd299641d191e481f80f5dc579fae149b05..fb5619d5621c9f799d35564f49eec6cea7583f0d 100644 (file)
@@ -218,6 +218,10 @@ if { [is_elf_format] } then {
     if { ![istarget "*-*-hpux*"] } then {
        run_dump_test "common1"
        run_dump_test "common2"
+       run_dump_test "common3a"
+       run_dump_test "common3b"
+       run_dump_test "common4a"
+       run_dump_test "common4b"
     }
 
     run_dump_test "strtab"
diff --git a/gas/testsuite/gas/i386/dw2-compress-3.d b/gas/testsuite/gas/i386/dw2-compress-3.d
deleted file mode 100644 (file)
index d2aa8ef..0000000
+++ /dev/null
@@ -1,103 +0,0 @@
-#as: --compress-debug-sections
-#readelf: -w
-#name: DWARF2 debugging information 3
-
-Contents of the .debug_info section:
-
-  Compilation Unit @ offset 0x0:
-   Length:        0x32 \(32-bit\)
-   Version:       4
-   Abbrev Offset: 0x0
-   Pointer Size:  4
- <0><b>: Abbrev Number: 1 \(DW_TAG_compile_unit\)
-    <c>   DW_AT_producer    : \(indirect string, offset: 0x2\): GNU C 4.8.3
-    <10>   DW_AT_language    : 1       \(ANSI C\)
-    <11>   DW_AT_name        : \(indirect string, offset: 0xe\): dw2-compress-3.c
-    <15>   DW_AT_comp_dir    : \(indirect string, offset: 0x0\): .
-    <19>   DW_AT_stmt_list   : 0x0
- <1><1d>: Abbrev Number: 2 \(DW_TAG_variable\)
-    <1e>   DW_AT_name        : foo
-    <22>   DW_AT_decl_file   : 1
-    <23>   DW_AT_decl_line   : 1
-    <24>   DW_AT_type        : <0x2e>
-    <28>   DW_AT_external    : 1
-    <28>   DW_AT_location    : 5 byte block: 3 4 0 0 0         \(DW_OP_addr: 4\)
- <1><2e>: Abbrev Number: 3 \(DW_TAG_base_type\)
-    <2f>   DW_AT_byte_size   : 4
-    <30>   DW_AT_encoding    : 5       \(signed\)
-    <31>   DW_AT_name        : int
- <1><35>: Abbrev Number: 0
-
-Contents of the .debug_abbrev section:
-
-  Number TAG \(0x0\)
-   1      DW_TAG_compile_unit    \[has children\]
-    DW_AT_producer     DW_FORM_strp
-    DW_AT_language     DW_FORM_data1
-    DW_AT_name         DW_FORM_strp
-    DW_AT_comp_dir     DW_FORM_strp
-    DW_AT_stmt_list    DW_FORM_sec_offset
-    DW_AT value: 0     DW_FORM value: 0
-   2      DW_TAG_variable    \[no children\]
-    DW_AT_name         DW_FORM_string
-    DW_AT_decl_file    DW_FORM_data1
-    DW_AT_decl_line    DW_FORM_data1
-    DW_AT_type         DW_FORM_ref4
-    DW_AT_external     DW_FORM_flag_present
-    DW_AT_location     DW_FORM_exprloc
-    DW_AT value: 0     DW_FORM value: 0
-   3      DW_TAG_base_type    \[no children\]
-    DW_AT_byte_size    DW_FORM_data1
-    DW_AT_encoding     DW_FORM_data1
-    DW_AT_name         DW_FORM_string
-    DW_AT value: 0     DW_FORM value: 0
-
-Contents of the .debug_aranges section:
-
-  Length:                   20
-  Version:                  2
-  Offset into .debug_info:  0x0
-  Pointer Size:             4
-  Segment Size:             0
-
-    Address    Length
-    00000000 00000000 
-
-Raw dump of debug contents of section .debug_line:
-
-  Offset:                      0x0
-  Length:                      45
-  DWARF Version:               2
-  Prologue Length:             39
-  Minimum Instruction Length:  1
-  Initial value of 'is_stmt':  1
-  Line Base:                   -5
-  Line Range:                  14
-  Opcode Base:                 13
-
- Opcodes:
-  Opcode 1 has 0 args
-  Opcode 2 has 1 args
-  Opcode 3 has 1 args
-  Opcode 4 has 1 args
-  Opcode 5 has 1 args
-  Opcode 6 has 0 args
-  Opcode 7 has 0 args
-  Opcode 8 has 0 args
-  Opcode 9 has 1 args
-  Opcode 10 has 0 args
-  Opcode 11 has 0 args
-  Opcode 12 has 1 args
-
- The Directory Table is empty.
-
- The File Name Table \(offset 0x1c\):
-  Entry        Dir     Time    Size    Name
-  1    0       0       0       dw2-compress-3.c
-
- No Line Number Statements.
-Contents of the .debug_str section:
-
-  0x00000000 2e00474e 55204320 342e382e 33006477 ..GNU C 4.8.3.dw
-  0x00000010 322d636f 6d707265 73732d33 2e6300   2-compress-3.c.
-
diff --git a/gas/testsuite/gas/i386/dw2-compress-3a.d b/gas/testsuite/gas/i386/dw2-compress-3a.d
new file mode 100644 (file)
index 0000000..fe19884
--- /dev/null
@@ -0,0 +1,104 @@
+#source: dw2-compress-3.s
+#as: --compress-debug-sections --elf-stt-common=no
+#readelf: -w
+#name: DWARF2 debugging information 3 w/o STT_COMMON
+
+Contents of the .debug_info section:
+
+  Compilation Unit @ offset 0x0:
+   Length:        0x32 \(32-bit\)
+   Version:       4
+   Abbrev Offset: 0x0
+   Pointer Size:  4
+ <0><b>: Abbrev Number: 1 \(DW_TAG_compile_unit\)
+    <c>   DW_AT_producer    : \(indirect string, offset: 0x2\): GNU C 4.8.3
+    <10>   DW_AT_language    : 1       \(ANSI C\)
+    <11>   DW_AT_name        : \(indirect string, offset: 0xe\): dw2-compress-3.c
+    <15>   DW_AT_comp_dir    : \(indirect string, offset: 0x0\): .
+    <19>   DW_AT_stmt_list   : 0x0
+ <1><1d>: Abbrev Number: 2 \(DW_TAG_variable\)
+    <1e>   DW_AT_name        : foo
+    <22>   DW_AT_decl_file   : 1
+    <23>   DW_AT_decl_line   : 1
+    <24>   DW_AT_type        : <0x2e>
+    <28>   DW_AT_external    : 1
+    <28>   DW_AT_location    : 5 byte block: 3 4 0 0 0         \(DW_OP_addr: 4\)
+ <1><2e>: Abbrev Number: 3 \(DW_TAG_base_type\)
+    <2f>   DW_AT_byte_size   : 4
+    <30>   DW_AT_encoding    : 5       \(signed\)
+    <31>   DW_AT_name        : int
+ <1><35>: Abbrev Number: 0
+
+Contents of the .debug_abbrev section:
+
+  Number TAG \(0x0\)
+   1      DW_TAG_compile_unit    \[has children\]
+    DW_AT_producer     DW_FORM_strp
+    DW_AT_language     DW_FORM_data1
+    DW_AT_name         DW_FORM_strp
+    DW_AT_comp_dir     DW_FORM_strp
+    DW_AT_stmt_list    DW_FORM_sec_offset
+    DW_AT value: 0     DW_FORM value: 0
+   2      DW_TAG_variable    \[no children\]
+    DW_AT_name         DW_FORM_string
+    DW_AT_decl_file    DW_FORM_data1
+    DW_AT_decl_line    DW_FORM_data1
+    DW_AT_type         DW_FORM_ref4
+    DW_AT_external     DW_FORM_flag_present
+    DW_AT_location     DW_FORM_exprloc
+    DW_AT value: 0     DW_FORM value: 0
+   3      DW_TAG_base_type    \[no children\]
+    DW_AT_byte_size    DW_FORM_data1
+    DW_AT_encoding     DW_FORM_data1
+    DW_AT_name         DW_FORM_string
+    DW_AT value: 0     DW_FORM value: 0
+
+Contents of the .debug_aranges section:
+
+  Length:                   20
+  Version:                  2
+  Offset into .debug_info:  0x0
+  Pointer Size:             4
+  Segment Size:             0
+
+    Address    Length
+    00000000 00000000 
+
+Raw dump of debug contents of section .debug_line:
+
+  Offset:                      0x0
+  Length:                      45
+  DWARF Version:               2
+  Prologue Length:             39
+  Minimum Instruction Length:  1
+  Initial value of 'is_stmt':  1
+  Line Base:                   -5
+  Line Range:                  14
+  Opcode Base:                 13
+
+ Opcodes:
+  Opcode 1 has 0 args
+  Opcode 2 has 1 args
+  Opcode 3 has 1 args
+  Opcode 4 has 1 args
+  Opcode 5 has 1 args
+  Opcode 6 has 0 args
+  Opcode 7 has 0 args
+  Opcode 8 has 0 args
+  Opcode 9 has 1 args
+  Opcode 10 has 0 args
+  Opcode 11 has 0 args
+  Opcode 12 has 1 args
+
+ The Directory Table is empty.
+
+ The File Name Table \(offset 0x1c\):
+  Entry        Dir     Time    Size    Name
+  1    0       0       0       dw2-compress-3.c
+
+ No Line Number Statements.
+Contents of the .debug_str section:
+
+  0x00000000 2e00474e 55204320 342e382e 33006477 ..GNU C 4.8.3.dw
+  0x00000010 322d636f 6d707265 73732d33 2e6300   2-compress-3.c.
+
diff --git a/gas/testsuite/gas/i386/dw2-compress-3b.d b/gas/testsuite/gas/i386/dw2-compress-3b.d
new file mode 100644 (file)
index 0000000..aa0651e
--- /dev/null
@@ -0,0 +1,104 @@
+#source: dw2-compress-3.s
+#as: --compress-debug-sections --elf-stt-common=yes
+#readelf: -w
+#name: DWARF2 debugging information 3 with STT_COMMON
+
+Contents of the .debug_info section:
+
+  Compilation Unit @ offset 0x0:
+   Length:        0x32 \(32-bit\)
+   Version:       4
+   Abbrev Offset: 0x0
+   Pointer Size:  4
+ <0><b>: Abbrev Number: 1 \(DW_TAG_compile_unit\)
+    <c>   DW_AT_producer    : \(indirect string, offset: 0x2\): GNU C 4.8.3
+    <10>   DW_AT_language    : 1       \(ANSI C\)
+    <11>   DW_AT_name        : \(indirect string, offset: 0xe\): dw2-compress-3.c
+    <15>   DW_AT_comp_dir    : \(indirect string, offset: 0x0\): .
+    <19>   DW_AT_stmt_list   : 0x0
+ <1><1d>: Abbrev Number: 2 \(DW_TAG_variable\)
+    <1e>   DW_AT_name        : foo
+    <22>   DW_AT_decl_file   : 1
+    <23>   DW_AT_decl_line   : 1
+    <24>   DW_AT_type        : <0x2e>
+    <28>   DW_AT_external    : 1
+    <28>   DW_AT_location    : 5 byte block: 3 4 0 0 0         \(DW_OP_addr: 4\)
+ <1><2e>: Abbrev Number: 3 \(DW_TAG_base_type\)
+    <2f>   DW_AT_byte_size   : 4
+    <30>   DW_AT_encoding    : 5       \(signed\)
+    <31>   DW_AT_name        : int
+ <1><35>: Abbrev Number: 0
+
+Contents of the .debug_abbrev section:
+
+  Number TAG \(0x0\)
+   1      DW_TAG_compile_unit    \[has children\]
+    DW_AT_producer     DW_FORM_strp
+    DW_AT_language     DW_FORM_data1
+    DW_AT_name         DW_FORM_strp
+    DW_AT_comp_dir     DW_FORM_strp
+    DW_AT_stmt_list    DW_FORM_sec_offset
+    DW_AT value: 0     DW_FORM value: 0
+   2      DW_TAG_variable    \[no children\]
+    DW_AT_name         DW_FORM_string
+    DW_AT_decl_file    DW_FORM_data1
+    DW_AT_decl_line    DW_FORM_data1
+    DW_AT_type         DW_FORM_ref4
+    DW_AT_external     DW_FORM_flag_present
+    DW_AT_location     DW_FORM_exprloc
+    DW_AT value: 0     DW_FORM value: 0
+   3      DW_TAG_base_type    \[no children\]
+    DW_AT_byte_size    DW_FORM_data1
+    DW_AT_encoding     DW_FORM_data1
+    DW_AT_name         DW_FORM_string
+    DW_AT value: 0     DW_FORM value: 0
+
+Contents of the .debug_aranges section:
+
+  Length:                   20
+  Version:                  2
+  Offset into .debug_info:  0x0
+  Pointer Size:             4
+  Segment Size:             0
+
+    Address    Length
+    00000000 00000000 
+
+Raw dump of debug contents of section .debug_line:
+
+  Offset:                      0x0
+  Length:                      45
+  DWARF Version:               2
+  Prologue Length:             39
+  Minimum Instruction Length:  1
+  Initial value of 'is_stmt':  1
+  Line Base:                   -5
+  Line Range:                  14
+  Opcode Base:                 13
+
+ Opcodes:
+  Opcode 1 has 0 args
+  Opcode 2 has 1 args
+  Opcode 3 has 1 args
+  Opcode 4 has 1 args
+  Opcode 5 has 1 args
+  Opcode 6 has 0 args
+  Opcode 7 has 0 args
+  Opcode 8 has 0 args
+  Opcode 9 has 1 args
+  Opcode 10 has 0 args
+  Opcode 11 has 0 args
+  Opcode 12 has 1 args
+
+ The Directory Table is empty.
+
+ The File Name Table \(offset 0x1c\):
+  Entry        Dir     Time    Size    Name
+  1    0       0       0       dw2-compress-3.c
+
+ No Line Number Statements.
+Contents of the .debug_str section:
+
+  0x00000000 2e00474e 55204320 342e382e 33006477 ..GNU C 4.8.3.dw
+  0x00000010 322d636f 6d707265 73732d33 2e6300   2-compress-3.c.
+
diff --git a/gas/testsuite/gas/i386/dw2-compressed-3.d b/gas/testsuite/gas/i386/dw2-compressed-3.d
deleted file mode 100644 (file)
index bd2818b..0000000
+++ /dev/null
@@ -1,104 +0,0 @@
-#source: dw2-compress-3.s
-#as: --compress-debug-sections=zlib-gabi
-#readelf: -w
-#name: DWARF2 debugging information 3 with SHF_COMPRESSED
-
-Contents of the .debug_info section:
-
-  Compilation Unit @ offset 0x0:
-   Length:        0x32 \(32-bit\)
-   Version:       4
-   Abbrev Offset: 0x0
-   Pointer Size:  4
- <0><b>: Abbrev Number: 1 \(DW_TAG_compile_unit\)
-    <c>   DW_AT_producer    : \(indirect string, offset: 0x2\): GNU C 4.8.3
-    <10>   DW_AT_language    : 1       \(ANSI C\)
-    <11>   DW_AT_name        : \(indirect string, offset: 0xe\): dw2-compress-3.c
-    <15>   DW_AT_comp_dir    : \(indirect string, offset: 0x0\): .
-    <19>   DW_AT_stmt_list   : 0x0
- <1><1d>: Abbrev Number: 2 \(DW_TAG_variable\)
-    <1e>   DW_AT_name        : foo
-    <22>   DW_AT_decl_file   : 1
-    <23>   DW_AT_decl_line   : 1
-    <24>   DW_AT_type        : <0x2e>
-    <28>   DW_AT_external    : 1
-    <28>   DW_AT_location    : 5 byte block: 3 4 0 0 0         \(DW_OP_addr: 4\)
- <1><2e>: Abbrev Number: 3 \(DW_TAG_base_type\)
-    <2f>   DW_AT_byte_size   : 4
-    <30>   DW_AT_encoding    : 5       \(signed\)
-    <31>   DW_AT_name        : int
- <1><35>: Abbrev Number: 0
-
-Contents of the .debug_abbrev section:
-
-  Number TAG \(0x0\)
-   1      DW_TAG_compile_unit    \[has children\]
-    DW_AT_producer     DW_FORM_strp
-    DW_AT_language     DW_FORM_data1
-    DW_AT_name         DW_FORM_strp
-    DW_AT_comp_dir     DW_FORM_strp
-    DW_AT_stmt_list    DW_FORM_sec_offset
-    DW_AT value: 0     DW_FORM value: 0
-   2      DW_TAG_variable    \[no children\]
-    DW_AT_name         DW_FORM_string
-    DW_AT_decl_file    DW_FORM_data1
-    DW_AT_decl_line    DW_FORM_data1
-    DW_AT_type         DW_FORM_ref4
-    DW_AT_external     DW_FORM_flag_present
-    DW_AT_location     DW_FORM_exprloc
-    DW_AT value: 0     DW_FORM value: 0
-   3      DW_TAG_base_type    \[no children\]
-    DW_AT_byte_size    DW_FORM_data1
-    DW_AT_encoding     DW_FORM_data1
-    DW_AT_name         DW_FORM_string
-    DW_AT value: 0     DW_FORM value: 0
-
-Contents of the .debug_aranges section:
-
-  Length:                   20
-  Version:                  2
-  Offset into .debug_info:  0x0
-  Pointer Size:             4
-  Segment Size:             0
-
-    Address    Length
-    00000000 00000000 
-
-Raw dump of debug contents of section .debug_line:
-
-  Offset:                      0x0
-  Length:                      45
-  DWARF Version:               2
-  Prologue Length:             39
-  Minimum Instruction Length:  1
-  Initial value of 'is_stmt':  1
-  Line Base:                   -5
-  Line Range:                  14
-  Opcode Base:                 13
-
- Opcodes:
-  Opcode 1 has 0 args
-  Opcode 2 has 1 args
-  Opcode 3 has 1 args
-  Opcode 4 has 1 args
-  Opcode 5 has 1 args
-  Opcode 6 has 0 args
-  Opcode 7 has 0 args
-  Opcode 8 has 0 args
-  Opcode 9 has 1 args
-  Opcode 10 has 0 args
-  Opcode 11 has 0 args
-  Opcode 12 has 1 args
-
- The Directory Table is empty.
-
- The File Name Table \(offset 0x1c\):
-  Entry        Dir     Time    Size    Name
-  1    0       0       0       dw2-compress-3.c
-
- No Line Number Statements.
-Contents of the .debug_str section:
-
-  0x00000000 2e00474e 55204320 342e382e 33006477 ..GNU C 4.8.3.dw
-  0x00000010 322d636f 6d707265 73732d33 2e6300   2-compress-3.c.
-
diff --git a/gas/testsuite/gas/i386/dw2-compressed-3a.d b/gas/testsuite/gas/i386/dw2-compressed-3a.d
new file mode 100644 (file)
index 0000000..a0d16c7
--- /dev/null
@@ -0,0 +1,104 @@
+#source: dw2-compress-3.s
+#as: --compress-debug-sections=zlib-gabi --elf-stt-common=no
+#readelf: -w
+#name: DWARF2 debugging information 3 with SHF_COMPRESSED w/o STT_COMMON
+
+Contents of the .debug_info section:
+
+  Compilation Unit @ offset 0x0:
+   Length:        0x32 \(32-bit\)
+   Version:       4
+   Abbrev Offset: 0x0
+   Pointer Size:  4
+ <0><b>: Abbrev Number: 1 \(DW_TAG_compile_unit\)
+    <c>   DW_AT_producer    : \(indirect string, offset: 0x2\): GNU C 4.8.3
+    <10>   DW_AT_language    : 1       \(ANSI C\)
+    <11>   DW_AT_name        : \(indirect string, offset: 0xe\): dw2-compress-3.c
+    <15>   DW_AT_comp_dir    : \(indirect string, offset: 0x0\): .
+    <19>   DW_AT_stmt_list   : 0x0
+ <1><1d>: Abbrev Number: 2 \(DW_TAG_variable\)
+    <1e>   DW_AT_name        : foo
+    <22>   DW_AT_decl_file   : 1
+    <23>   DW_AT_decl_line   : 1
+    <24>   DW_AT_type        : <0x2e>
+    <28>   DW_AT_external    : 1
+    <28>   DW_AT_location    : 5 byte block: 3 4 0 0 0         \(DW_OP_addr: 4\)
+ <1><2e>: Abbrev Number: 3 \(DW_TAG_base_type\)
+    <2f>   DW_AT_byte_size   : 4
+    <30>   DW_AT_encoding    : 5       \(signed\)
+    <31>   DW_AT_name        : int
+ <1><35>: Abbrev Number: 0
+
+Contents of the .debug_abbrev section:
+
+  Number TAG \(0x0\)
+   1      DW_TAG_compile_unit    \[has children\]
+    DW_AT_producer     DW_FORM_strp
+    DW_AT_language     DW_FORM_data1
+    DW_AT_name         DW_FORM_strp
+    DW_AT_comp_dir     DW_FORM_strp
+    DW_AT_stmt_list    DW_FORM_sec_offset
+    DW_AT value: 0     DW_FORM value: 0
+   2      DW_TAG_variable    \[no children\]
+    DW_AT_name         DW_FORM_string
+    DW_AT_decl_file    DW_FORM_data1
+    DW_AT_decl_line    DW_FORM_data1
+    DW_AT_type         DW_FORM_ref4
+    DW_AT_external     DW_FORM_flag_present
+    DW_AT_location     DW_FORM_exprloc
+    DW_AT value: 0     DW_FORM value: 0
+   3      DW_TAG_base_type    \[no children\]
+    DW_AT_byte_size    DW_FORM_data1
+    DW_AT_encoding     DW_FORM_data1
+    DW_AT_name         DW_FORM_string
+    DW_AT value: 0     DW_FORM value: 0
+
+Contents of the .debug_aranges section:
+
+  Length:                   20
+  Version:                  2
+  Offset into .debug_info:  0x0
+  Pointer Size:             4
+  Segment Size:             0
+
+    Address    Length
+    00000000 00000000 
+
+Raw dump of debug contents of section .debug_line:
+
+  Offset:                      0x0
+  Length:                      45
+  DWARF Version:               2
+  Prologue Length:             39
+  Minimum Instruction Length:  1
+  Initial value of 'is_stmt':  1
+  Line Base:                   -5
+  Line Range:                  14
+  Opcode Base:                 13
+
+ Opcodes:
+  Opcode 1 has 0 args
+  Opcode 2 has 1 args
+  Opcode 3 has 1 args
+  Opcode 4 has 1 args
+  Opcode 5 has 1 args
+  Opcode 6 has 0 args
+  Opcode 7 has 0 args
+  Opcode 8 has 0 args
+  Opcode 9 has 1 args
+  Opcode 10 has 0 args
+  Opcode 11 has 0 args
+  Opcode 12 has 1 args
+
+ The Directory Table is empty.
+
+ The File Name Table \(offset 0x1c\):
+  Entry        Dir     Time    Size    Name
+  1    0       0       0       dw2-compress-3.c
+
+ No Line Number Statements.
+Contents of the .debug_str section:
+
+  0x00000000 2e00474e 55204320 342e382e 33006477 ..GNU C 4.8.3.dw
+  0x00000010 322d636f 6d707265 73732d33 2e6300   2-compress-3.c.
+
diff --git a/gas/testsuite/gas/i386/dw2-compressed-3b.d b/gas/testsuite/gas/i386/dw2-compressed-3b.d
new file mode 100644 (file)
index 0000000..6469ca9
--- /dev/null
@@ -0,0 +1,104 @@
+#source: dw2-compress-3.s
+#as: --compress-debug-sections=zlib-gabi --elf-stt-common=yes
+#readelf: -w
+#name: DWARF2 debugging information 3 with SHF_COMPRESSED with STT_COMMON
+
+Contents of the .debug_info section:
+
+  Compilation Unit @ offset 0x0:
+   Length:        0x32 \(32-bit\)
+   Version:       4
+   Abbrev Offset: 0x0
+   Pointer Size:  4
+ <0><b>: Abbrev Number: 1 \(DW_TAG_compile_unit\)
+    <c>   DW_AT_producer    : \(indirect string, offset: 0x2\): GNU C 4.8.3
+    <10>   DW_AT_language    : 1       \(ANSI C\)
+    <11>   DW_AT_name        : \(indirect string, offset: 0xe\): dw2-compress-3.c
+    <15>   DW_AT_comp_dir    : \(indirect string, offset: 0x0\): .
+    <19>   DW_AT_stmt_list   : 0x0
+ <1><1d>: Abbrev Number: 2 \(DW_TAG_variable\)
+    <1e>   DW_AT_name        : foo
+    <22>   DW_AT_decl_file   : 1
+    <23>   DW_AT_decl_line   : 1
+    <24>   DW_AT_type        : <0x2e>
+    <28>   DW_AT_external    : 1
+    <28>   DW_AT_location    : 5 byte block: 3 4 0 0 0         \(DW_OP_addr: 4\)
+ <1><2e>: Abbrev Number: 3 \(DW_TAG_base_type\)
+    <2f>   DW_AT_byte_size   : 4
+    <30>   DW_AT_encoding    : 5       \(signed\)
+    <31>   DW_AT_name        : int
+ <1><35>: Abbrev Number: 0
+
+Contents of the .debug_abbrev section:
+
+  Number TAG \(0x0\)
+   1      DW_TAG_compile_unit    \[has children\]
+    DW_AT_producer     DW_FORM_strp
+    DW_AT_language     DW_FORM_data1
+    DW_AT_name         DW_FORM_strp
+    DW_AT_comp_dir     DW_FORM_strp
+    DW_AT_stmt_list    DW_FORM_sec_offset
+    DW_AT value: 0     DW_FORM value: 0
+   2      DW_TAG_variable    \[no children\]
+    DW_AT_name         DW_FORM_string
+    DW_AT_decl_file    DW_FORM_data1
+    DW_AT_decl_line    DW_FORM_data1
+    DW_AT_type         DW_FORM_ref4
+    DW_AT_external     DW_FORM_flag_present
+    DW_AT_location     DW_FORM_exprloc
+    DW_AT value: 0     DW_FORM value: 0
+   3      DW_TAG_base_type    \[no children\]
+    DW_AT_byte_size    DW_FORM_data1
+    DW_AT_encoding     DW_FORM_data1
+    DW_AT_name         DW_FORM_string
+    DW_AT value: 0     DW_FORM value: 0
+
+Contents of the .debug_aranges section:
+
+  Length:                   20
+  Version:                  2
+  Offset into .debug_info:  0x0
+  Pointer Size:             4
+  Segment Size:             0
+
+    Address    Length
+    00000000 00000000 
+
+Raw dump of debug contents of section .debug_line:
+
+  Offset:                      0x0
+  Length:                      45
+  DWARF Version:               2
+  Prologue Length:             39
+  Minimum Instruction Length:  1
+  Initial value of 'is_stmt':  1
+  Line Base:                   -5
+  Line Range:                  14
+  Opcode Base:                 13
+
+ Opcodes:
+  Opcode 1 has 0 args
+  Opcode 2 has 1 args
+  Opcode 3 has 1 args
+  Opcode 4 has 1 args
+  Opcode 5 has 1 args
+  Opcode 6 has 0 args
+  Opcode 7 has 0 args
+  Opcode 8 has 0 args
+  Opcode 9 has 1 args
+  Opcode 10 has 0 args
+  Opcode 11 has 0 args
+  Opcode 12 has 1 args
+
+ The Directory Table is empty.
+
+ The File Name Table \(offset 0x1c\):
+  Entry        Dir     Time    Size    Name
+  1    0       0       0       dw2-compress-3.c
+
+ No Line Number Statements.
+Contents of the .debug_str section:
+
+  0x00000000 2e00474e 55204320 342e382e 33006477 ..GNU C 4.8.3.dw
+  0x00000010 322d636f 6d707265 73732d33 2e6300   2-compress-3.c.
+
index 22aca23b15d7025590e8c70883c77c228e2abeac..f1e7611efb24c3bf83aff9f274c1e48f448a7a88 100644 (file)
@@ -448,9 +448,11 @@ if [expr [istarget "i*86-*-*"] || [istarget "x86_64-*-*"]] then {
        run_list_test_stdin "list-2" "-al"
        run_list_test_stdin "list-3" "-al"
        run_dump_test "dw2-compress-1"
-       run_dump_test "dw2-compress-3"
+       run_dump_test "dw2-compress-3a"
+       run_dump_test "dw2-compress-3b"
        run_dump_test "dw2-compressed-1"
-       run_dump_test "dw2-compressed-3"
+       run_dump_test "dw2-compressed-3a"
+       run_dump_test "dw2-compressed-3b"
     }
 }
 
index f623b00e27846c008effde66c0b3458701880b24..24cd6ca40377410830a3be05ca09213fccfcb4e7 100644 (file)
@@ -2209,6 +2209,11 @@ write_object_file (void)
   obj_frob_file_after_relocs ();
 #endif
 
+#if defined OBJ_ELF || defined OBJ_MAYBE_ELF
+  if (IS_ELF && flag_use_elf_stt_common)
+    stdoutput->flags |= BFD_CONVERT_ELF_COMMON | BFD_USE_ELF_STT_COMMON;
+#endif
+
   /* Once all relocations have been written, we can compress the
      contents of the debug sections.  This needs to be done before
      we start writing any sections, because it will affect the file
index 860811c2a7867e21dbd649cc862813dde10ead09..eeea6ef7a97c7fedd66ce98fac2374c26e5ce396 100644 (file)
@@ -42,6 +42,15 @@ enum bfd_link_discard
   discard_all          /* Discard all locals.  */
 };
 
+/* Whether to generate ELF common symbols with the STT_COMMON type
+   during a relocatable link.  */
+enum bfd_link_elf_stt_common
+{
+  unchanged,
+  elf_stt_common,
+  no_elf_stt_common
+};
+
 /* Describes the type of hash table entry structure being used.
    Different hash table structure have different fields and so
    support different linking features.  */
@@ -321,6 +330,9 @@ struct bfd_link_info
   /* Which local symbols to discard.  */
   ENUM_BITFIELD (bfd_link_discard) discard : 2;
 
+  /* Whether to generate ELF common symbols with the STT_COMMON type.  */
+  ENUM_BITFIELD (bfd_link_elf_stt_common) elf_stt_common : 2;
+
   /* Criteria for skipping symbols when determining
      whether to include an object from an archive. */
   ENUM_BITFIELD (bfd_link_common_skip_ar_symbols) common_skip_ar_symbols : 2;
diff --git a/ld/NEWS b/ld/NEWS
index dce600d3d9482cdf24e91fa24b606a2fe88bd85b..4bf8091e52b57261cff8d683af648753f23c8770 100644 (file)
--- a/ld/NEWS
+++ b/ld/NEWS
@@ -1,5 +1,8 @@
 -*- text -*-
 
+* Add -z common/-z nocommon options for ELF targets to control whether to
+  convert common symbols to the STT_COMMON type during a relocatable link.
+
 * Support for -z nodynamic-undefined-weak in the x86 ELF linker, which
   avoids dynamic relocations against undefined weak symbols in executable.
 
index d9d3393ec04e48d690ddf528e86636e778bdccf3..f3ec875a7ee55d6365f2c7a5078ce20754ae8ab2 100644 (file)
@@ -2421,6 +2421,10 @@ fragment <<EOF
        link_info.relro = TRUE;
       else if (strcmp (optarg, "norelro") == 0)
        link_info.relro = FALSE;
+      else if (strcmp (optarg, "common") == 0)
+       link_info.elf_stt_common = elf_stt_common;
+      else if (strcmp (optarg, "nocommon") == 0)
+       link_info.elf_stt_common = no_elf_stt_common;
       else if (strcmp (optarg, "text") == 0)
        link_info.error_textrel = TRUE;
       else if (strcmp (optarg, "notext") == 0)
index ee462c5f7e5bbdb9e3198a1ac9255f03fa368b9f..b2b99ab66054ba5bc448908b5754a777bed0404b 100644 (file)
@@ -1092,6 +1092,10 @@ The recognized keywords are:
 Combines multiple reloc sections and sorts them to make dynamic symbol
 lookup caching possible.
 
+@item common
+Generate common symbols with the STT_COMMON type druing a relocatable
+link.
+
 @item defs
 Disallows undefined symbols in object files.  Undefined symbols in
 shared libraries are still allowed.
@@ -1132,6 +1136,10 @@ Allows multiple definitions.
 @item nocombreloc
 Disables multiple reloc sections combining.
 
+@item nocommon
+Generate common symbols with the STT_OBJECT type druing a relocatable
+link.
+
 @item nocopyreloc
 Disable linker generated .dynbss variables used in place of variables
 defined in shared libraries.  May result in dynamic text relocations.
index 559472f39f0c3743bdc30a0469032aeb267bd8c5..6e0f9329982ae784ae4034376e16a6d93eb1389a 100644 (file)
@@ -1759,6 +1759,10 @@ elf_shlib_list_options (FILE *file)
   fprintf (file, _("\
   -z norelro                  Don't create RELRO program header\n"));
   fprintf (file, _("\
+  -z common                   Generate common symbols with STT_COMMON type\n"));
+  fprintf (file, _("\
+  -z nocommon                 Generate common symbols with STT_OBJECT type\n"));
+  fprintf (file, _("\
   -z stacksize=SIZE           Set size of stack segment\n"));
   fprintf (file, _("\
   -z text                     Treat DT_TEXTREL in shared object as error\n"));
index 92240bf2a2794d8d39896405895227894699335b..f546e438279340063861faed78b07365b69b3ade 100644 (file)
@@ -41,17 +41,19 @@ global srcdir
 global subdir
 global link_output
 
-if { ![ld_assemble $as $srcdir/$subdir/tls_common.s tmpdir/tls_common.o ] } {
+if { ![ld_assemble $as "--elf-stt-common=no $srcdir/$subdir/tls_common.s" tmpdir/tls_commona.o]
+      || ![ld_assemble $as "--elf-stt-common=yes $srcdir/$subdir/tls_common.s" tmpdir/tls_commonb.o] } {
     unresolved "tls_common"
     return
 }
 
-if { ![ld_simple_link $ld tmpdir/tls_common1.o "-r tmpdir/tls_common.o"] } {
+if { ![ld_simple_link $ld tmpdir/tls_common1a.o "-r tmpdir/tls_commona.o"]
+     || ![ld_simple_link $ld tmpdir/tls_common1b.o "-r tmpdir/tls_commona.o"] } {
     fail "tls_common"
     return
 }
 
-if { ![ld_simple_link $ld tmpdir/tls_common "tmpdir/tls_common1.o"] } {
+if { ![ld_simple_link $ld tmpdir/tls_commona "tmpdir/tls_common1a.o"] } {
     if { [string match "*not supported*" $link_output]
         || [string match "*unrecognized option*" $link_output] } {
        unsupported "$ld_options is not supported by this target"
@@ -63,7 +65,26 @@ if { ![ld_simple_link $ld tmpdir/tls_common "tmpdir/tls_common1.o"] } {
     return
 }
 
-set readelf_output [run_host_cmd "$READELF" "-l --wide tmpdir/tls_common"]
+if { ![ld_simple_link $ld tmpdir/tls_commonb "tmpdir/tls_common1b.o"] } {
+    if { [string match "*not supported*" $link_output]
+        || [string match "*unrecognized option*" $link_output] } {
+       unsupported "$ld_options is not supported by this target"
+    } elseif { [string match "*Warning*alignment*of common symbol*" $link_output] } {
+       fail "tls_common"
+    } else {
+       unresolved "tls_common"
+    }
+    return
+}
+
+set readelf_output [run_host_cmd "$READELF" "-l --wide tmpdir/tls_commona"]
+if ![regexp ".*TLS.*0x0+ 0x0+4 R .*" $readelf_output] then {
+    send_log "$readelf_output\n"
+    fail "tls_common"
+    return
+}
+
+set readelf_output [run_host_cmd "$READELF" "-l --wide tmpdir/tls_commona"]
 if ![regexp ".*TLS.*0x0+ 0x0+4 R .*" $readelf_output] then {
     send_log "$readelf_output\n"
     fail "tls_common"
diff --git a/ld/testsuite/ld-elfcomm/common-1.s b/ld/testsuite/ld-elfcomm/common-1.s
new file mode 100644 (file)
index 0000000..97e2bf4
--- /dev/null
@@ -0,0 +1,3 @@
+       .data
+       .dc.a foobar
+       .comm foobar,30,4
diff --git a/ld/testsuite/ld-elfcomm/common-1a.d b/ld/testsuite/ld-elfcomm/common-1a.d
new file mode 100644 (file)
index 0000000..28ed86b
--- /dev/null
@@ -0,0 +1,8 @@
+#source: common-1.s
+#as: --elf-stt-common=yes
+#ld: -r
+#readelf: -s -W
+
+#...
+ +[0-9]+: +0+4 +30 +COMMON +GLOBAL +DEFAULT +COM +foobar
+#pass
diff --git a/ld/testsuite/ld-elfcomm/common-1b.d b/ld/testsuite/ld-elfcomm/common-1b.d
new file mode 100644 (file)
index 0000000..f0d135a
--- /dev/null
@@ -0,0 +1,8 @@
+#source: common-1.s
+#as: --elf-stt-common=no
+#ld: -r
+#readelf: -s -W
+
+#...
+ +[0-9]+: +0+4 +30 +OBJECT +GLOBAL +DEFAULT +COM +foobar
+#pass
diff --git a/ld/testsuite/ld-elfcomm/common-1c.d b/ld/testsuite/ld-elfcomm/common-1c.d
new file mode 100644 (file)
index 0000000..c2805c3
--- /dev/null
@@ -0,0 +1,8 @@
+#source: common-1.s
+#as: --elf-stt-common=yes
+#ld: -r -z nocommon
+#readelf: -s -W
+
+#...
+ +[0-9]+: +0+4 +30 +OBJECT +GLOBAL +DEFAULT +COM +foobar
+#pass
diff --git a/ld/testsuite/ld-elfcomm/common-1d.d b/ld/testsuite/ld-elfcomm/common-1d.d
new file mode 100644 (file)
index 0000000..33c5c43
--- /dev/null
@@ -0,0 +1,8 @@
+#source: common-1.s
+#as: --elf-stt-common=yes
+#ld: -r -z common
+#readelf: -s -W
+
+#...
+ +[0-9]+: +0+4 +30 +COMMON +GLOBAL +DEFAULT +COM +foobar
+#pass
diff --git a/ld/testsuite/ld-elfcomm/common-1e.d b/ld/testsuite/ld-elfcomm/common-1e.d
new file mode 100644 (file)
index 0000000..a296db3
--- /dev/null
@@ -0,0 +1,8 @@
+#source: common-1.s
+#as: --elf-stt-common=no
+#ld: -r -z common
+#readelf: -s -W
+
+#...
+ +[0-9]+: +0+4 +30 +COMMON +GLOBAL +DEFAULT +COM +foobar
+#pass
diff --git a/ld/testsuite/ld-elfcomm/common-1f.d b/ld/testsuite/ld-elfcomm/common-1f.d
new file mode 100644 (file)
index 0000000..91b530a
--- /dev/null
@@ -0,0 +1,8 @@
+#source: common-1.s
+#as: --elf-stt-common=no
+#ld: -r -z nocommon
+#readelf: -s -W
+
+#...
+ +[0-9]+: +0+4 +30 +OBJECT +GLOBAL +DEFAULT +COM +foobar
+#pass
diff --git a/ld/testsuite/ld-elfcomm/common-2.s b/ld/testsuite/ld-elfcomm/common-2.s
new file mode 100644 (file)
index 0000000..9e51c8e
--- /dev/null
@@ -0,0 +1,3 @@
+       .data
+       .dc.a foobar
+       .tls_common foobar,30,4
diff --git a/ld/testsuite/ld-elfcomm/common-2a.d b/ld/testsuite/ld-elfcomm/common-2a.d
new file mode 100644 (file)
index 0000000..aacaad4
--- /dev/null
@@ -0,0 +1,8 @@
+#source: common-2.s
+#as: --elf-stt-common=yes
+#ld: -r
+#readelf: -s -W
+
+#...
+ +[0-9]+: +0+4 +30 +TLS +GLOBAL +DEFAULT +COM +foobar
+#pass
diff --git a/ld/testsuite/ld-elfcomm/common-2b.d b/ld/testsuite/ld-elfcomm/common-2b.d
new file mode 100644 (file)
index 0000000..4cb9e8e
--- /dev/null
@@ -0,0 +1,8 @@
+#source: common-2.s
+#as: --elf-stt-common=no
+#ld: -r
+#readelf: -s -W
+
+#...
+ +[0-9]+: +0+4 +30 +TLS +GLOBAL +DEFAULT +COM +foobar
+#pass
diff --git a/ld/testsuite/ld-elfcomm/common-2c.d b/ld/testsuite/ld-elfcomm/common-2c.d
new file mode 100644 (file)
index 0000000..c4ddd6a
--- /dev/null
@@ -0,0 +1,8 @@
+#source: common-2.s
+#as: --elf-stt-common=yes
+#ld: -r -z common
+#readelf: -s -W
+
+#...
+ +[0-9]+: +0+4 +30 +TLS +GLOBAL +DEFAULT +COM +foobar
+#pass
diff --git a/ld/testsuite/ld-elfcomm/common-2d.d b/ld/testsuite/ld-elfcomm/common-2d.d
new file mode 100644 (file)
index 0000000..577c381
--- /dev/null
@@ -0,0 +1,8 @@
+#source: common-2.s
+#as: --elf-stt-common=yes
+#ld: -r -z nocommon
+#readelf: -s -W
+
+#...
+ +[0-9]+: +0+4 +30 +TLS +GLOBAL +DEFAULT +COM +foobar
+#pass
diff --git a/ld/testsuite/ld-elfcomm/common-2e.d b/ld/testsuite/ld-elfcomm/common-2e.d
new file mode 100644 (file)
index 0000000..e6a3649
--- /dev/null
@@ -0,0 +1,8 @@
+#source: common-2.s
+#as: --elf-stt-common=no
+#ld: -r -z common
+#readelf: -s -W
+
+#...
+ +[0-9]+: +0+4 +30 +TLS +GLOBAL +DEFAULT +COM +foobar
+#pass
diff --git a/ld/testsuite/ld-elfcomm/common-2f.d b/ld/testsuite/ld-elfcomm/common-2f.d
new file mode 100644 (file)
index 0000000..728a099
--- /dev/null
@@ -0,0 +1,8 @@
+#source: common-2.s
+#as: --elf-stt-common=no
+#ld: -r -z nocommon
+#readelf: -s -W
+
+#...
+ +[0-9]+: +0+4 +30 +TLS +GLOBAL +DEFAULT +COM +foobar
+#pass
diff --git a/ld/testsuite/ld-elfcomm/common-3a.rd b/ld/testsuite/ld-elfcomm/common-3a.rd
new file mode 100644 (file)
index 0000000..5d75572
--- /dev/null
@@ -0,0 +1,6 @@
+#ld: -r
+#readelf: -s -W
+
+#...
+ +[0-9]+: +0+4 +30 +OBJECT +GLOBAL +DEFAULT +COM +foobar
+#pass
diff --git a/ld/testsuite/ld-elfcomm/common-3b.rd b/ld/testsuite/ld-elfcomm/common-3b.rd
new file mode 100644 (file)
index 0000000..7859718
--- /dev/null
@@ -0,0 +1,6 @@
+#ld: -r
+#readelf: -s -W
+
+#...
+ +[0-9]+: +0+4 +30 +COMMON +GLOBAL +DEFAULT +COM +foobar
+#pass
diff --git a/ld/testsuite/ld-elfcomm/dummy.s b/ld/testsuite/ld-elfcomm/dummy.s
new file mode 100644 (file)
index 0000000..403f980
--- /dev/null
@@ -0,0 +1 @@
+# Dummy
index 81fd520106936d294dd10902ff6a69c41c2a1683..926b98ce7a05183af6a1f2c264af622e467ff941 100644 (file)
@@ -144,7 +144,7 @@ proc stt_common_test { options testname } {
     global READELF
     global ld
 
-    set options "$options tmpdir/common1a.o"
+    set options "$options tmpdir/common1c.o"
 
     if { ! [ld_simple_link $ld tmpdir/common.exe $options] } {
       unresolved $testname
@@ -154,7 +154,7 @@ proc stt_common_test { options testname } {
     send_log "$READELF --syms tmpdir/common.exe | grep foo\n"
     set exec_output [run_host_cmd "$READELF" "--syms tmpdir/common.exe | grep foo"]
 
-    if {![regexp "(\[  \]*)(\[0-9\]+):(\[      \]*)(\[0-9\]+)(\[       \]+)(\[0-9\]+)(\[       \]+)COMMON(\[   \]+)GLOBAL(\[   \]+)DEFAULT(\[  \]+)(\[0-9\]+)(\[       \]+)_?foo2" $exec_output] } {
+    if {![regexp { +[0-9a-f]+. +[0-9a-f]+ OBJECT + GLOBAL +DEFAULT +[0-9]+ _?foo2} $exec_output] } {
        fail $testname
        return 0
     }
@@ -163,23 +163,6 @@ proc stt_common_test { options testname } {
     return 1
 }
 
-# Check to see if the assembler is generating symbols with the STT_COMMON type.
-proc assembler_generates_commons {} {
-    global exec_output
-    global READELF
-
-    verbose "Check to see if STT_COMMON symbols are being generated:"
-    set exec_output [run_host_cmd "$READELF" "--syms tmpdir/common1a.o | grep foo"]
-
-    if { ![regexp "(\[         \]*)(\[0-9\]+):(\[      \]*)(\[0\]*)80(\[       \]+).(\[        \]+)COMMON(\[   \]+)GLOBAL(\[   \]+)DEFAULT(\[  \]+)(PRC\\\[0xff03\\\]|COM|SCOM)(\[     \]+)_?foo2" $exec_output] } {
-       verbose "STT_COMMON not generated"
-       return 0
-    }
-
-    verbose "STT_COMMON's are generated"
-    return 1
-}
-
 if [istarget nios2*-*-*] {
     set CFLAGS "$CFLAGS -G0"
 }
@@ -187,7 +170,9 @@ if [istarget nios2*-*-*] {
 # Explicitly use "-fcommon" so that even if $CFLAGS includes
 # "-fno-common", these tests are compiled as expected.
 if {   ![ld_compile "$CC $CFLAGS -fcommon" $srcdir/$subdir/common1a.c tmpdir/common1a.o]
-    || ![ld_compile "$CC $CFLAGS -fcommon" $srcdir/$subdir/common1b.c tmpdir/common1b.o] } {
+    || ![ld_compile "$CC $CFLAGS -fcommon" $srcdir/$subdir/common1b.c tmpdir/common1b.o]
+    || ![ld_compile "$CC $CFLAGS -Wa,--elf-stt-common=yes -fcommon" $srcdir/$subdir/common1b.c tmpdir/common1c.o] } {
+    unresolved $test1
     unresolved $test1
     return
 }
@@ -261,12 +246,56 @@ if { [dump_common1 $test1c2] } {
 #
 # The following tests are for when we are generating STT_COMMON symbols only.
 #
-
-if { ![assembler_generates_commons] } {
-    return
-}
-
 stt_common_test "-static -e 0" "static link of common symbols"
 stt_common_test "-shared"      "shared link of common symbols"
 stt_common_test "-pie"         "position independent link of common symbols"
 
+run_ld_link_tests [list \
+  [list \
+    "Build common-3x.o" \
+     "-r" "" "--elf-stt-common=no" \
+     {common-1.s} {} "common-3x.o" \
+  ] \
+  [list \
+    "Build common-3y.o" \
+     "-r" "" "--elf-stt-common=yes" \
+     {common-1.s} {} "common-3y.o" \
+  ] \
+  [list \
+    "Build common-3a.o" \
+    "-r tmpdir/common-3x.o tmpdir/common-3y.o" "" "" \
+    {dummy.s} {{readelf {-s -W} common-3a.rd}} "common-3a.o" \
+  ] \
+  [list \
+    "Build common-3b.o" \
+    "-r tmpdir/common-3y.o tmpdir/common-3x.o" "" "" \
+    {dummy.s} {{readelf {-s -W} common-3b.rd}} "common-3b.o" \
+  ] \
+  [list \
+    "Build common-3c.o" \
+    "-r -z nocommon tmpdir/common-3x.o tmpdir/common-3y.o" "" "" \
+    {dummy.s} {{readelf {-s -W} common-3a.rd}} "common-3c.o" \
+  ] \
+  [list \
+    "Build common-3d.o" \
+    "-r -z common tmpdir/common-3x.o tmpdir/common-3y.o" "" "" \
+    {dummy.s} {{readelf {-s -W} common-3b.rd}} "common-3b.o" \
+  ] \
+  [list \
+    "Build common-3e.o" \
+    "-r -z common tmpdir/common-3y.o tmpdir/common-3x.o" "" "" \
+    {dummy.s} {{readelf {-s -W} common-3b.rd}} "common-3e.o" \
+  ] \
+  [list \
+    "Build common-3f.o" \
+    "-r -z nocommon tmpdir/common-3y.o tmpdir/common-3x.o" "" "" \
+    {dummy.s} {{readelf {-s -W} common-3a.rd}} "common-3f.o" \
+  ] \
+]
+
+set test_list [lsort [glob -nocomplain $srcdir/$subdir/*.d]]
+foreach t $test_list {
+    # We need to strip the ".d", but can leave the dirname.
+    verbose [file rootname $t]
+    run_dump_test [file rootname $t]
+}
index ab8f017c93746df2e137859564a9c5ed3d71239c..5ddf045a945b263cb090d12800829814bfb60f06 100644 (file)
@@ -349,6 +349,7 @@ run_dump_test "pr19636-4a"
 run_dump_test "pr19636-4b"
 run_dump_test "pr19636-4c"
 run_dump_test "pr19636-4d"
+run_dump_test "pr19645"
 
 if { !([istarget "i?86-*-linux*"]
        || [istarget "i?86-*-gnu*"]
diff --git a/ld/testsuite/ld-i386/pr19645.d b/ld/testsuite/ld-i386/pr19645.d
new file mode 100644 (file)
index 0000000..10b40b8
--- /dev/null
@@ -0,0 +1,13 @@
+#as: --32 --elf-stt-common=yes
+#ld: -shared -Bsymbolic-functions -melf_i386
+#readelf: -r --wide --dyn-syms
+
+Relocation section '.rel.dyn' at offset 0x[0-9a-f]+ contains 1 entries:
+ +Offset +Info +Type +Sym. Value +Symbol's Name
+[0-9a-f]+ +[0-9a-f]+ +R_386_GLOB_DAT +[0-9a-f]+ +foobar
+
+Symbol table '.dynsym' contains [0-9]+ entries:
+   Num:    Value  Size Type    Bind   Vis      Ndx Name
+#...
+ +[0-9]+: +[0-9a-f]+ +30 +OBJECT +GLOBAL +DEFAULT +[0-9]+ foobar
+#pass
diff --git a/ld/testsuite/ld-i386/pr19645.s b/ld/testsuite/ld-i386/pr19645.s
new file mode 100644 (file)
index 0000000..5dadebe
--- /dev/null
@@ -0,0 +1,6 @@
+       .text
+       .global bar
+       .type bar,"function"
+bar:
+       movl foobar@GOT(%ebx), %eax
+       .comm foobar,30,4
index afe5f6c03909bda311e38af121c19203022443b2..959ae9c2571291470b3f8adcdbf6ea00fe124a25 100644 (file)
@@ -41,18 +41,31 @@ if { !([istarget "x86_64-*-elf*"]
 }
 
 set build_tests_ld {
-  {"Build dwarfreloc1x.o"
-   "-r" "" ""
-   {dwarfreloc1.s} {} "dwarfreloc1x.o"}
-  {"Build dwarfreloc2.o"
-   "-r" "" ""
-   {dwarfreloc2.s} {} "dwarfreloc2x.o"}
+  {"Build dwarfreloc1xa.o"
+   "-r" "" "--elf-stt-common=no"
+   {dwarfreloc1.s} {} "dwarfreloc1xa.o"}
+  {"Build dwarfreloc1xb.o"
+   "-r" "" "--elf-stt-common=yes"
+   {dwarfreloc1.s} {} "dwarfreloc1xb.o"}
+  {"Build dwarfreloc2a.o"
+   "-r" "" "--elf-stt-common=no"
+   {dwarfreloc2.s} {} "dwarfreloc2xa.o"}
+  {"Build dwarfreloc2b.o"
+   "-r" "" "--elf-stt-common=yes"
+   {dwarfreloc2.s} {} "dwarfreloc2xb.o"}
 }
 
 run_ld_link_tests $build_tests_ld
 
-set testname "Link dwarfreloc1x.o and dwarfreloc2x.o to dwarfreloc.o"
-if [ld_simple_link $ld "tmpdir/dwarfreloc.o" "-r tmpdir/dwarfreloc1x.o tmpdir/dwarfreloc2x.o"] {
+set testname "Link dwarfreloc1xa.o and dwarfreloc2xa.o to dwarfreloca.o"
+if [ld_simple_link $ld "tmpdir/dwarfreloca.o" "-r tmpdir/dwarfreloc1xa.o tmpdir/dwarfreloc2xa.o"] {
+    pass $testname
+} else {
+    fail $testname
+}
+
+set testname "Link dwarfreloc1xb.o and dwarfreloc2xb.o to dwarfrelocb.o"
+if [ld_simple_link $ld "tmpdir/dwarfrelocb.o" "-r tmpdir/dwarfreloc1xb.o tmpdir/dwarfreloc2xb.o"] {
     pass $testname
 } else {
     fail $testname
@@ -61,9 +74,34 @@ if [ld_simple_link $ld "tmpdir/dwarfreloc.o" "-r tmpdir/dwarfreloc1x.o tmpdir/dw
 # The code is copied from `ld-lib.exp'.  We cannot use the functions there as
 # they expect source (.s or .c) files while we to check a `ld -r' output (.o).
 
-set testname "Check dwarfreloc.o readelf"
+set testname "Check dwarfreloca.o readelf"
+set dumpfile "dwarfreloc.rd"
+set cmd "$READELF --debug-dump=info tmpdir/dwarfreloca.o"
+set status [remote_exec host [concat sh -c [list "$cmd >dump.out 2>ld.stderr"]] "" "/dev/null"]
+send_log "$cmd\n"
+remote_upload host "ld.stderr"
+set comp_output [prune_warnings [file_contents "ld.stderr"]]
+remote_file host delete "ld.stderr"
+remote_file build delete "ld.stderr"
+
+if ![string match "" $comp_output] then {
+    send_log "$comp_output\n"
+    fail $testname
+} else {
+    remote_upload host "dump.out"
+    if { [regexp_diff "dump.out" "$srcdir/$subdir/$dumpfile"] } then {
+       verbose "output is [file_contents "dump.out"]" 2
+       fail $testname
+    } else {
+       pass $testname
+    }
+    remote_file build delete "dump.out"
+    remote_file host delete "dump.out"
+}
+
+set testname "Check dwarfrelocb.o readelf"
 set dumpfile "dwarfreloc.rd"
-set cmd "$READELF --debug-dump=info tmpdir/dwarfreloc.o"
+set cmd "$READELF --debug-dump=info tmpdir/dwarfrelocb.o"
 set status [remote_exec host [concat sh -c [list "$cmd >dump.out 2>ld.stderr"]] "" "/dev/null"]
 send_log "$cmd\n"
 remote_upload host "ld.stderr"
diff --git a/ld/testsuite/ld-x86-64/largecomm-1.s b/ld/testsuite/ld-x86-64/largecomm-1.s
new file mode 100644 (file)
index 0000000..cfadc4f
--- /dev/null
@@ -0,0 +1,3 @@
+       .data
+       .dc.a foobar
+       .largecomm foobar,30,4
diff --git a/ld/testsuite/ld-x86-64/largecomm-1a.d b/ld/testsuite/ld-x86-64/largecomm-1a.d
new file mode 100644 (file)
index 0000000..63462bf
--- /dev/null
@@ -0,0 +1,8 @@
+#source: largecomm-1.s
+#as: --elf-stt-common=yes
+#ld: -r
+#readelf: -s -W
+
+#...
+ +[0-9]+: +0+4 +30 +COMMON +GLOBAL +DEFAULT +LARGE_COM +foobar
+#pass
diff --git a/ld/testsuite/ld-x86-64/largecomm-1b.d b/ld/testsuite/ld-x86-64/largecomm-1b.d
new file mode 100644 (file)
index 0000000..8f62d0d
--- /dev/null
@@ -0,0 +1,8 @@
+#source: largecomm-1.s
+#as: --elf-stt-common=no
+#ld: -r
+#readelf: -s -W
+
+#...
+ +[0-9]+: +0+4 +30 +OBJECT +GLOBAL +DEFAULT +LARGE_COM +foobar
+#pass
diff --git a/ld/testsuite/ld-x86-64/largecomm-1c.d b/ld/testsuite/ld-x86-64/largecomm-1c.d
new file mode 100644 (file)
index 0000000..7e6a8cc
--- /dev/null
@@ -0,0 +1,8 @@
+#source: largecomm-1.s
+#as: --elf-stt-common=yes
+#ld: -r -z nocommon
+#readelf: -s -W
+
+#...
+ +[0-9]+: +0+4 +30 +OBJECT +GLOBAL +DEFAULT +LARGE_COM +foobar
+#pass
diff --git a/ld/testsuite/ld-x86-64/largecomm-1d.d b/ld/testsuite/ld-x86-64/largecomm-1d.d
new file mode 100644 (file)
index 0000000..4025e7b
--- /dev/null
@@ -0,0 +1,8 @@
+#source: largecomm-1.s
+#as: --elf-stt-common=yes
+#ld: -r -z common
+#readelf: -s -W
+
+#...
+ +[0-9]+: +0+4 +30 +COMMON +GLOBAL +DEFAULT +LARGE_COM +foobar
+#pass
diff --git a/ld/testsuite/ld-x86-64/largecomm-1e.d b/ld/testsuite/ld-x86-64/largecomm-1e.d
new file mode 100644 (file)
index 0000000..b1a3a03
--- /dev/null
@@ -0,0 +1,8 @@
+#source: largecomm-1.s
+#as: --elf-stt-common=no
+#ld: -r -z common
+#readelf: -s -W
+
+#...
+ +[0-9]+: +0+4 +30 +COMMON +GLOBAL +DEFAULT +LARGE_COM +foobar
+#pass
diff --git a/ld/testsuite/ld-x86-64/largecomm-1f.d b/ld/testsuite/ld-x86-64/largecomm-1f.d
new file mode 100644 (file)
index 0000000..3b5bd92
--- /dev/null
@@ -0,0 +1,8 @@
+#source: largecomm-1.s
+#as: --elf-stt-common=no
+#ld: -r -z nocommon
+#readelf: -s -W
+
+#...
+ +[0-9]+: +0+4 +30 +OBJECT +GLOBAL +DEFAULT +LARGE_COM +foobar
+#pass
diff --git a/ld/testsuite/ld-x86-64/pr19645.d b/ld/testsuite/ld-x86-64/pr19645.d
new file mode 100644 (file)
index 0000000..9445fda
--- /dev/null
@@ -0,0 +1,13 @@
+#as: --64 --elf-stt-common=yes
+#ld: -shared -Bsymbolic-functions -melf_x86_64
+#readelf: -r --wide --dyn-syms
+
+Relocation section '.rela.dyn' at offset 0x[0-9a-f]+ contains 1 entries:
+ +Offset +Info +Type +Symbol's Value +Symbol's Name \+ Addend
+[0-9a-f]+ +[0-9a-f]+ +R_X86_64_GLOB_DAT +[0-9a-f]+ +foobar \+ 0
+
+Symbol table '.dynsym' contains [0-9]+ entries:
+ +Num: +Value +Size +Type +Bind +Vis +Ndx +Name
+#...
+ +[0-9]+: +[0-9a-f]+ +30 +OBJECT +GLOBAL +DEFAULT +[0-9]+ foobar
+#pass
diff --git a/ld/testsuite/ld-x86-64/pr19645.s b/ld/testsuite/ld-x86-64/pr19645.s
new file mode 100644 (file)
index 0000000..88331ed
--- /dev/null
@@ -0,0 +1,6 @@
+       .text
+       .global bar
+       .type bar,"function"
+bar:
+       movq foobar@GOTPCREL(%rip), %rax
+       .comm foobar,30,4
index 214b08b05fde778f3acb730584aa16d34890562f..5a3b24f8b7d62d6d0e61efc0a14e67ab1511eaba 100644 (file)
@@ -239,6 +239,12 @@ run_dump_test "pr14215"
 run_dump_test "pr14207"
 run_dump_test "gotplt1"
 run_dump_test "pie1"
+run_dump_test "largecomm-1a"
+run_dump_test "largecomm-1b"
+run_dump_test "largecomm-1c"
+run_dump_test "largecomm-1d"
+run_dump_test "largecomm-1e"
+run_dump_test "largecomm-1f"
 
 if { ![istarget "x86_64-*-linux*"] && ![istarget "x86_64-*-nacl*"]} {
     return
@@ -375,6 +381,7 @@ run_dump_test "pr19636-2i"
 run_dump_test "pr19636-3a"
 run_dump_test "pr19636-3b"
 run_dump_test "pr19636-3c"
+run_dump_test "pr19645"
 
 proc undefined_weak {cflags ldflags} {
     set testname "Undefined weak symbol"