From b8871f357fdfa9c0c06d2d3e5600391d8c994f37 Mon Sep 17 00:00:00 2001 From: "H.J. Lu" Date: Mon, 22 Feb 2016 09:18:52 -0800 Subject: [PATCH] Properly implement STT_COMMON 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. --- bfd/bfd-in2.h | 17 +++-- bfd/bfd.c | 13 +++- bfd/config.in | 3 - bfd/configure | 29 +------- bfd/configure.ac | 20 ------ bfd/elf.c | 16 +++-- bfd/elfcode.h | 1 + bfd/elflink.c | 85 ++++++++++++++++++----- bfd/elfxx-target.h | 4 +- bfd/syms.c | 4 +- binutils/NEWS | 3 + binutils/doc/binutils.texi | 9 +++ binutils/objcopy.c | 51 ++++++++++++-- binutils/readelf.c | 1 + binutils/testsuite/binutils-all/common-1.s | 1 + binutils/testsuite/binutils-all/common-1a.d | 8 +++ binutils/testsuite/binutils-all/common-1b.d | 8 +++ binutils/testsuite/binutils-all/common-1c.d | 9 +++ binutils/testsuite/binutils-all/common-1d.d | 9 +++ binutils/testsuite/binutils-all/common-1e.d | 9 +++ binutils/testsuite/binutils-all/common-1f.d | 9 +++ binutils/testsuite/binutils-all/common-2.s | 1 + binutils/testsuite/binutils-all/common-2a.d | 8 +++ binutils/testsuite/binutils-all/common-2b.d | 8 +++ binutils/testsuite/binutils-all/common-2c.d | 9 +++ binutils/testsuite/binutils-all/common-2d.d | 9 +++ binutils/testsuite/binutils-all/common-2e.d | 9 +++ binutils/testsuite/binutils-all/common-2f.d | 9 +++ binutils/testsuite/binutils-all/objcopy.exp | 18 +++++ gas/NEWS | 7 ++ gas/as.c | 19 +++++ gas/as.h | 3 + gas/config.in | 4 ++ gas/configure | 27 +++++++- gas/configure.ac | 19 +++++ gas/doc/as.texinfo | 9 +++ gas/testsuite/gas/elf/common3.s | 1 + gas/testsuite/gas/elf/common3a.d | 7 ++ gas/testsuite/gas/elf/common3b.d | 7 ++ gas/testsuite/gas/elf/common4.s | 1 + gas/testsuite/gas/elf/common4a.d | 7 ++ gas/testsuite/gas/elf/common4b.d | 7 ++ gas/testsuite/gas/elf/elf.exp | 4 ++ gas/testsuite/gas/i386/dw2-compress-3.d | 103 --------------------------- gas/testsuite/gas/i386/dw2-compress-3a.d | 104 ++++++++++++++++++++++++++++ gas/testsuite/gas/i386/dw2-compress-3b.d | 104 ++++++++++++++++++++++++++++ gas/testsuite/gas/i386/dw2-compressed-3.d | 104 ---------------------------- gas/testsuite/gas/i386/dw2-compressed-3a.d | 104 ++++++++++++++++++++++++++++ gas/testsuite/gas/i386/dw2-compressed-3b.d | 104 ++++++++++++++++++++++++++++ gas/testsuite/gas/i386/i386.exp | 6 +- gas/write.c | 5 ++ include/bfdlink.h | 12 ++++ ld/NEWS | 3 + ld/emultempl/elf32.em | 4 ++ ld/ld.texinfo | 8 +++ ld/lexsup.c | 4 ++ ld/testsuite/ld-elf/tls_common.exp | 29 ++++++-- ld/testsuite/ld-elfcomm/common-1.s | 3 + ld/testsuite/ld-elfcomm/common-1a.d | 8 +++ ld/testsuite/ld-elfcomm/common-1b.d | 8 +++ ld/testsuite/ld-elfcomm/common-1c.d | 8 +++ ld/testsuite/ld-elfcomm/common-1d.d | 8 +++ ld/testsuite/ld-elfcomm/common-1e.d | 8 +++ ld/testsuite/ld-elfcomm/common-1f.d | 8 +++ ld/testsuite/ld-elfcomm/common-2.s | 3 + ld/testsuite/ld-elfcomm/common-2a.d | 8 +++ ld/testsuite/ld-elfcomm/common-2b.d | 8 +++ ld/testsuite/ld-elfcomm/common-2c.d | 8 +++ ld/testsuite/ld-elfcomm/common-2d.d | 8 +++ ld/testsuite/ld-elfcomm/common-2e.d | 8 +++ ld/testsuite/ld-elfcomm/common-2f.d | 8 +++ ld/testsuite/ld-elfcomm/common-3a.rd | 6 ++ ld/testsuite/ld-elfcomm/common-3b.rd | 6 ++ ld/testsuite/ld-elfcomm/dummy.s | 1 + ld/testsuite/ld-elfcomm/elfcomm.exp | 79 ++++++++++++++------- ld/testsuite/ld-i386/i386.exp | 1 + ld/testsuite/ld-i386/pr19645.d | 13 ++++ ld/testsuite/ld-i386/pr19645.s | 6 ++ ld/testsuite/ld-x86-64/dwarfreloc.exp | 58 +++++++++++++--- ld/testsuite/ld-x86-64/largecomm-1.s | 3 + ld/testsuite/ld-x86-64/largecomm-1a.d | 8 +++ ld/testsuite/ld-x86-64/largecomm-1b.d | 8 +++ ld/testsuite/ld-x86-64/largecomm-1c.d | 8 +++ ld/testsuite/ld-x86-64/largecomm-1d.d | 8 +++ ld/testsuite/ld-x86-64/largecomm-1e.d | 8 +++ ld/testsuite/ld-x86-64/largecomm-1f.d | 8 +++ ld/testsuite/ld-x86-64/pr19645.d | 13 ++++ ld/testsuite/ld-x86-64/pr19645.s | 6 ++ ld/testsuite/ld-x86-64/x86-64.exp | 7 ++ 89 files changed, 1204 insertions(+), 341 deletions(-) create mode 100644 binutils/testsuite/binutils-all/common-1.s create mode 100644 binutils/testsuite/binutils-all/common-1a.d create mode 100644 binutils/testsuite/binutils-all/common-1b.d create mode 100644 binutils/testsuite/binutils-all/common-1c.d create mode 100644 binutils/testsuite/binutils-all/common-1d.d create mode 100644 binutils/testsuite/binutils-all/common-1e.d create mode 100644 binutils/testsuite/binutils-all/common-1f.d create mode 100644 binutils/testsuite/binutils-all/common-2.s create mode 100644 binutils/testsuite/binutils-all/common-2a.d create mode 100644 binutils/testsuite/binutils-all/common-2b.d create mode 100644 binutils/testsuite/binutils-all/common-2c.d create mode 100644 binutils/testsuite/binutils-all/common-2d.d create mode 100644 binutils/testsuite/binutils-all/common-2e.d create mode 100644 binutils/testsuite/binutils-all/common-2f.d create mode 100644 gas/testsuite/gas/elf/common3.s create mode 100644 gas/testsuite/gas/elf/common3a.d create mode 100644 gas/testsuite/gas/elf/common3b.d create mode 100644 gas/testsuite/gas/elf/common4.s create mode 100644 gas/testsuite/gas/elf/common4a.d create mode 100644 gas/testsuite/gas/elf/common4b.d delete mode 100644 gas/testsuite/gas/i386/dw2-compress-3.d create mode 100644 gas/testsuite/gas/i386/dw2-compress-3a.d create mode 100644 gas/testsuite/gas/i386/dw2-compress-3b.d delete mode 100644 gas/testsuite/gas/i386/dw2-compressed-3.d create mode 100644 gas/testsuite/gas/i386/dw2-compressed-3a.d create mode 100644 gas/testsuite/gas/i386/dw2-compressed-3b.d create mode 100644 ld/testsuite/ld-elfcomm/common-1.s create mode 100644 ld/testsuite/ld-elfcomm/common-1a.d create mode 100644 ld/testsuite/ld-elfcomm/common-1b.d create mode 100644 ld/testsuite/ld-elfcomm/common-1c.d create mode 100644 ld/testsuite/ld-elfcomm/common-1d.d create mode 100644 ld/testsuite/ld-elfcomm/common-1e.d create mode 100644 ld/testsuite/ld-elfcomm/common-1f.d create mode 100644 ld/testsuite/ld-elfcomm/common-2.s create mode 100644 ld/testsuite/ld-elfcomm/common-2a.d create mode 100644 ld/testsuite/ld-elfcomm/common-2b.d create mode 100644 ld/testsuite/ld-elfcomm/common-2c.d create mode 100644 ld/testsuite/ld-elfcomm/common-2d.d create mode 100644 ld/testsuite/ld-elfcomm/common-2e.d create mode 100644 ld/testsuite/ld-elfcomm/common-2f.d create mode 100644 ld/testsuite/ld-elfcomm/common-3a.rd create mode 100644 ld/testsuite/ld-elfcomm/common-3b.rd create mode 100644 ld/testsuite/ld-elfcomm/dummy.s create mode 100644 ld/testsuite/ld-i386/pr19645.d create mode 100644 ld/testsuite/ld-i386/pr19645.s create mode 100644 ld/testsuite/ld-x86-64/largecomm-1.s create mode 100644 ld/testsuite/ld-x86-64/largecomm-1a.d create mode 100644 ld/testsuite/ld-x86-64/largecomm-1b.d create mode 100644 ld/testsuite/ld-x86-64/largecomm-1c.d create mode 100644 ld/testsuite/ld-x86-64/largecomm-1d.d create mode 100644 ld/testsuite/ld-x86-64/largecomm-1e.d create mode 100644 ld/testsuite/ld-x86-64/largecomm-1f.d create mode 100644 ld/testsuite/ld-x86-64/pr19645.d create mode 100644 ld/testsuite/ld-x86-64/pr19645.s diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h index 612ab4b..dd7fb1a 100644 --- a/bfd/bfd-in2.h +++ b/bfd/bfd-in2.h @@ -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? */ diff --git a/bfd/bfd.c b/bfd/bfd.c index 58c27c9..7400c4e 100644 --- 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? *} diff --git a/bfd/config.in b/bfd/config.in index 58248bd..cffadbb 100644 --- a/bfd/config.in +++ b/bfd/config.in @@ -349,9 +349,6 @@ /* 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 diff --git a/bfd/configure b/bfd/configure index c376644..1229323 100755 --- a/bfd/configure +++ b/bfd/configure @@ -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 @@ -12175,29 +12173,6 @@ fi -# 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. diff --git a/bfd/configure.ac b/bfd/configure.ac index b69891c..f57d4d7 100644 --- a/bfd/configure.ac +++ b/bfd/configure.ac @@ -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/]) diff --git a/bfd/elf.c b/bfd/elf.c index 30112ae..1013644 100644 --- 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) diff --git a/bfd/elfcode.h b/bfd/elfcode.h index 7223dd3..79a14f3 100644 --- a/bfd/elfcode.h +++ b/bfd/elfcode.h @@ -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; diff --git a/bfd/elflink.c b/bfd/elflink.c index 993e9b9..0e3abff 100644 --- a/bfd/elflink.c +++ b/bfd/elflink.c @@ -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) diff --git a/bfd/elfxx-target.h b/bfd/elfxx-target.h index b3227ed..ca30b1d 100644 --- a/bfd/elfxx-target.h +++ b/bfd/elfxx-target.h @@ -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 diff --git a/bfd/syms.c b/bfd/syms.c index 5e860f9..118595d 100644 --- a/bfd/syms.c +++ b/bfd/syms.c @@ -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. *} diff --git a/binutils/NEWS b/binutils/NEWS index 6d68ade..712604b 100644 --- a/binutils/NEWS +++ b/binutils/NEWS @@ -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: diff --git a/binutils/doc/binutils.texi b/binutils/doc/binutils.texi index 31ef8f2..a60ab66 100644 --- a/binutils/doc/binutils.texi +++ b/binutils/doc/binutils.texi @@ -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}. diff --git a/binutils/objcopy.c b/binutils/objcopy.c index 8185f28..198ba3a 100644 --- a/binutils/objcopy.c +++ b/binutils/objcopy.c @@ -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\ @ Read options from \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; diff --git a/binutils/readelf.c b/binutils/readelf.c index 7a755b4..a40453d 100644 --- a/binutils/readelf.c +++ b/binutils/readelf.c @@ -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 index 0000000..f684da4 --- /dev/null +++ b/binutils/testsuite/binutils-all/common-1.s @@ -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 index 0000000..f8c6fea --- /dev/null +++ b/binutils/testsuite/binutils-all/common-1a.d @@ -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 index 0000000..5a56c6e --- /dev/null +++ b/binutils/testsuite/binutils-all/common-1b.d @@ -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 index 0000000..bbdc49e --- /dev/null +++ b/binutils/testsuite/binutils-all/common-1c.d @@ -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 index 0000000..c0df029 --- /dev/null +++ b/binutils/testsuite/binutils-all/common-1d.d @@ -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 index 0000000..9f84955 --- /dev/null +++ b/binutils/testsuite/binutils-all/common-1e.d @@ -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 index 0000000..bdbdca5 --- /dev/null +++ b/binutils/testsuite/binutils-all/common-1f.d @@ -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 index 0000000..bf2c26c --- /dev/null +++ b/binutils/testsuite/binutils-all/common-2.s @@ -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 index 0000000..75e6217 --- /dev/null +++ b/binutils/testsuite/binutils-all/common-2a.d @@ -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 index 0000000..7c7a194 --- /dev/null +++ b/binutils/testsuite/binutils-all/common-2b.d @@ -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 index 0000000..c203dd2 --- /dev/null +++ b/binutils/testsuite/binutils-all/common-2c.d @@ -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 index 0000000..da221d6 --- /dev/null +++ b/binutils/testsuite/binutils-all/common-2d.d @@ -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 index 0000000..04b1faf --- /dev/null +++ b/binutils/testsuite/binutils-all/common-2e.d @@ -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 index 0000000..4748e5d --- /dev/null +++ b/binutils/testsuite/binutils-all/common-2f.d @@ -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 diff --git a/binutils/testsuite/binutils-all/objcopy.exp b/binutils/testsuite/binutils-all/objcopy.exp index b2c54ea..c348578 100644 --- a/binutils/testsuite/binutils-all/objcopy.exp +++ b/binutils/testsuite/binutils-all/objcopy.exp @@ -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 diff --git a/gas/NEWS b/gas/NEWS index dd34a9f..a627028 100644 --- 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. diff --git a/gas/as.c b/gas/as.c index 55214f4..14980b9 100644 --- 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; diff --git a/gas/as.h b/gas/as.h index bf1206f..4e5601b 100644 --- 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 diff --git a/gas/config.in b/gas/config.in index 8b040fc..e06f160 100644 --- a/gas/config.in +++ b/gas/config.in @@ -39,6 +39,10 @@ /* 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 diff --git a/gas/configure b/gas/configure index cd7182f..bc5a1ba 100755 --- a/gas/configure +++ b/gas/configure @@ -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 diff --git a/gas/configure.ac b/gas/configure.ac index 377526e..8f71825 100644 --- a/gas/configure.ac +++ b/gas/configure.ac @@ -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 diff --git a/gas/doc/as.texinfo b/gas/doc/as.texinfo index 055e2f7..a0584d3 100644 --- a/gas/doc/as.texinfo +++ b/gas/doc/as.texinfo @@ -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 index 0000000..f684da4 --- /dev/null +++ b/gas/testsuite/gas/elf/common3.s @@ -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 index 0000000..fa9d5ce --- /dev/null +++ b/gas/testsuite/gas/elf/common3a.d @@ -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 index 0000000..9481d13 --- /dev/null +++ b/gas/testsuite/gas/elf/common3b.d @@ -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 index 0000000..bf2c26c --- /dev/null +++ b/gas/testsuite/gas/elf/common4.s @@ -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 index 0000000..fceb01b --- /dev/null +++ b/gas/testsuite/gas/elf/common4a.d @@ -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 index 0000000..c18284e --- /dev/null +++ b/gas/testsuite/gas/elf/common4b.d @@ -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 diff --git a/gas/testsuite/gas/elf/elf.exp b/gas/testsuite/gas/elf/elf.exp index a2a86dd..fb5619d 100644 --- a/gas/testsuite/gas/elf/elf.exp +++ b/gas/testsuite/gas/elf/elf.exp @@ -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 index d2aa8ef..0000000 --- a/gas/testsuite/gas/i386/dw2-compress-3.d +++ /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>: Abbrev Number: 1 \(DW_TAG_compile_unit\) - 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 index 0000000..fe19884 --- /dev/null +++ b/gas/testsuite/gas/i386/dw2-compress-3a.d @@ -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>: Abbrev Number: 1 \(DW_TAG_compile_unit\) + 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 index 0000000..aa0651e --- /dev/null +++ b/gas/testsuite/gas/i386/dw2-compress-3b.d @@ -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>: Abbrev Number: 1 \(DW_TAG_compile_unit\) + 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 index bd2818b..0000000 --- a/gas/testsuite/gas/i386/dw2-compressed-3.d +++ /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>: Abbrev Number: 1 \(DW_TAG_compile_unit\) - 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 index 0000000..a0d16c7 --- /dev/null +++ b/gas/testsuite/gas/i386/dw2-compressed-3a.d @@ -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>: Abbrev Number: 1 \(DW_TAG_compile_unit\) + 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 index 0000000..6469ca9 --- /dev/null +++ b/gas/testsuite/gas/i386/dw2-compressed-3b.d @@ -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>: Abbrev Number: 1 \(DW_TAG_compile_unit\) + 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/i386.exp b/gas/testsuite/gas/i386/i386.exp index 22aca23..f1e7611 100644 --- a/gas/testsuite/gas/i386/i386.exp +++ b/gas/testsuite/gas/i386/i386.exp @@ -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" } } diff --git a/gas/write.c b/gas/write.c index f623b00..24cd6ca 100644 --- a/gas/write.c +++ b/gas/write.c @@ -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 diff --git a/include/bfdlink.h b/include/bfdlink.h index 860811c..eeea6ef 100644 --- a/include/bfdlink.h +++ b/include/bfdlink.h @@ -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 dce600d..4bf8091 100644 --- 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. diff --git a/ld/emultempl/elf32.em b/ld/emultempl/elf32.em index d9d3393..f3ec875 100644 --- a/ld/emultempl/elf32.em +++ b/ld/emultempl/elf32.em @@ -2421,6 +2421,10 @@ fragment <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 index 0000000..cfadc4f --- /dev/null +++ b/ld/testsuite/ld-x86-64/largecomm-1.s @@ -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 index 0000000..63462bf --- /dev/null +++ b/ld/testsuite/ld-x86-64/largecomm-1a.d @@ -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 index 0000000..8f62d0d --- /dev/null +++ b/ld/testsuite/ld-x86-64/largecomm-1b.d @@ -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 index 0000000..7e6a8cc --- /dev/null +++ b/ld/testsuite/ld-x86-64/largecomm-1c.d @@ -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 index 0000000..4025e7b --- /dev/null +++ b/ld/testsuite/ld-x86-64/largecomm-1d.d @@ -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 index 0000000..b1a3a03 --- /dev/null +++ b/ld/testsuite/ld-x86-64/largecomm-1e.d @@ -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 index 0000000..3b5bd92 --- /dev/null +++ b/ld/testsuite/ld-x86-64/largecomm-1f.d @@ -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 index 0000000..9445fda --- /dev/null +++ b/ld/testsuite/ld-x86-64/pr19645.d @@ -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 index 0000000..88331ed --- /dev/null +++ b/ld/testsuite/ld-x86-64/pr19645.s @@ -0,0 +1,6 @@ + .text + .global bar + .type bar,"function" +bar: + movq foobar@GOTPCREL(%rip), %rax + .comm foobar,30,4 diff --git a/ld/testsuite/ld-x86-64/x86-64.exp b/ld/testsuite/ld-x86-64/x86-64.exp index 214b08b..5a3b24f 100644 --- a/ld/testsuite/ld-x86-64/x86-64.exp +++ b/ld/testsuite/ld-x86-64/x86-64.exp @@ -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" -- 2.5.0