| From c7beb33d82923479aab9638145e23b26f4c68e2d Mon Sep 17 00:00:00 2001 |
| From: "H.J. Lu" <hjl.tools@gmail.com> |
| Date: Mon, 4 Nov 2013 09:35:07 -0800 |
| Subject: [PATCH] Add STB_SECONDARY support to gas and ld |
| |
| STB_SECONDARY is similar to STB_WEAK. But a STB_SECONDARY definition |
| can be overridden by STB_GLOBAL or STB_WEAK definition at link-time |
| as well as run-time. Linker also search archive library and extract |
| archive members to resolve defined and undefined STB_SECONDARY symbol. |
| --- |
| ChangeLog.secondary | 221 +++++++++++++++++++++++++++++++++++ |
| bfd/archive.c | 1 + |
| bfd/bfd-in2.h | 4 + |
| bfd/elf.c | 10 +- |
| bfd/elf32-mips.c | 5 +- |
| bfd/elf64-ia64-vms.c | 4 + |
| bfd/elfcode.h | 3 + |
| bfd/elflink.c | 171 ++++++++++++++++++++------- |
| bfd/elfn32-mips.c | 5 +- |
| bfd/linker.c | 44 ++++++- |
| bfd/syms.c | 14 +++ |
| binutils/nm.c | 1 + |
| binutils/readelf.c | 1 + |
| gas/config/obj-elf.c | 42 ++++++- |
| gas/doc/as.texinfo | 9 ++ |
| gas/symbols.c | 39 +++++-- |
| gas/symbols.h | 2 + |
| gas/testsuite/gas/elf/common3.d | 2 + |
| gas/testsuite/gas/elf/common3.l | 2 + |
| gas/testsuite/gas/elf/common3.s | 2 + |
| gas/testsuite/gas/elf/common4.d | 2 + |
| gas/testsuite/gas/elf/common4.l | 2 + |
| gas/testsuite/gas/elf/common4.s | 2 + |
| gas/testsuite/gas/elf/elf.exp | 5 + |
| gas/testsuite/gas/elf/secondary1.e | 4 + |
| gas/testsuite/gas/elf/secondary1.s | 33 ++++++ |
| gas/testsuite/gas/elf/secondary2.e | 1 + |
| gas/testsuite/gas/elf/secondary2.s | 5 + |
| gas/testsuite/gas/elf/type.e | 2 + |
| gas/testsuite/gas/elf/type.s | 13 ++- |
| include/bfdlink.h | 6 + |
| include/elf/common.h | 1 + |
| ld/emultempl/elf32.em | 4 + |
| ld/ld.texinfo | 4 + |
| ld/ldmain.c | 1 + |
| ld/testsuite/ld-elf/library1.c | 11 ++ |
| ld/testsuite/ld-elf/library1.out | 1 + |
| ld/testsuite/ld-elf/library2.c | 12 ++ |
| ld/testsuite/ld-elf/library2.out | 1 + |
| ld/testsuite/ld-elf/library3.out | 1 + |
| ld/testsuite/ld-elf/library4.out | 1 + |
| ld/testsuite/ld-elf/library5a.c | 16 +++ |
| ld/testsuite/ld-elf/library5b.c | 10 ++ |
| ld/testsuite/ld-elf/library6a.c | 4 + |
| ld/testsuite/ld-elf/library6b.c | 7 ++ |
| ld/testsuite/ld-elf/library6c.c | 9 ++ |
| ld/testsuite/ld-elf/library7a.c | 1 + |
| ld/testsuite/ld-elf/library7b.c | 7 ++ |
| ld/testsuite/ld-elf/library7c.c | 3 + |
| ld/testsuite/ld-elf/library8.map | 4 + |
| ld/testsuite/ld-elf/library8a.c | 10 ++ |
| ld/testsuite/ld-elf/library8a.rd | 5 + |
| ld/testsuite/ld-elf/library8b.c | 4 + |
| ld/testsuite/ld-elf/library8b.rd | 5 + |
| ld/testsuite/ld-elf/library8c.c | 7 ++ |
| ld/testsuite/ld-elf/library8c.rd | 5 + |
| ld/testsuite/ld-elf/secondary-foo.c | 7 ++ |
| ld/testsuite/ld-elf/secondary-main.c | 8 ++ |
| ld/testsuite/ld-elf/secondary.c | 9 ++ |
| ld/testsuite/ld-elf/secondary.exp | 176 ++++++++++++++++++++++++++++ |
| ld/testsuite/ld-elf/secondary.rd | 5 + |
| ld/testsuite/ld-elf/secondary1.out | 1 + |
| ld/testsuite/ld-elf/secondary1.rd | 5 + |
| ld/testsuite/ld-elf/secondary2.rd | 5 + |
| ld/testsuite/ld-elf/secondary3.rd | 5 + |
| ld/testsuite/ld-elf/secondary3a.s | 4 + |
| ld/testsuite/ld-elf/secondary3b.s | 20 ++++ |
| ld/testsuite/ld-elf/secondary4.rd | 5 + |
| ld/testsuite/ld-elf/secondary4.s | 9 ++ |
| ld/testsuite/ld-elf/secondary5.c | 10 ++ |
| ld/testsuite/ld-elf/secondary5.out | 3 + |
| ld/testsuite/ld-elf/secondary6.c | 11 ++ |
| ld/testsuite/ld-elf/secondary6.out | 1 + |
| ld/testsuite/ld-elf/secondary7.c | 13 +++ |
| ld/testsuite/ld-elf/secondary7.out | 1 + |
| 75 files changed, 1026 insertions(+), 63 deletions(-) |
| create mode 100644 ChangeLog.secondary |
| create mode 100644 gas/testsuite/gas/elf/common3.d |
| create mode 100644 gas/testsuite/gas/elf/common3.l |
| create mode 100644 gas/testsuite/gas/elf/common3.s |
| create mode 100644 gas/testsuite/gas/elf/common4.d |
| create mode 100644 gas/testsuite/gas/elf/common4.l |
| create mode 100644 gas/testsuite/gas/elf/common4.s |
| create mode 100644 gas/testsuite/gas/elf/secondary1.e |
| create mode 100644 gas/testsuite/gas/elf/secondary1.s |
| create mode 100644 gas/testsuite/gas/elf/secondary2.e |
| create mode 100644 gas/testsuite/gas/elf/secondary2.s |
| create mode 100644 ld/testsuite/ld-elf/library1.c |
| create mode 100644 ld/testsuite/ld-elf/library1.out |
| create mode 100644 ld/testsuite/ld-elf/library2.c |
| create mode 100644 ld/testsuite/ld-elf/library2.out |
| create mode 100644 ld/testsuite/ld-elf/library3.out |
| create mode 100644 ld/testsuite/ld-elf/library4.out |
| create mode 100644 ld/testsuite/ld-elf/library5a.c |
| create mode 100644 ld/testsuite/ld-elf/library5b.c |
| create mode 100644 ld/testsuite/ld-elf/library6a.c |
| create mode 100644 ld/testsuite/ld-elf/library6b.c |
| create mode 100644 ld/testsuite/ld-elf/library6c.c |
| create mode 100644 ld/testsuite/ld-elf/library7a.c |
| create mode 100644 ld/testsuite/ld-elf/library7b.c |
| create mode 100644 ld/testsuite/ld-elf/library7c.c |
| create mode 100644 ld/testsuite/ld-elf/library8.map |
| create mode 100644 ld/testsuite/ld-elf/library8a.c |
| create mode 100644 ld/testsuite/ld-elf/library8a.rd |
| create mode 100644 ld/testsuite/ld-elf/library8b.c |
| create mode 100644 ld/testsuite/ld-elf/library8b.rd |
| create mode 100644 ld/testsuite/ld-elf/library8c.c |
| create mode 100644 ld/testsuite/ld-elf/library8c.rd |
| create mode 100644 ld/testsuite/ld-elf/secondary-foo.c |
| create mode 100644 ld/testsuite/ld-elf/secondary-main.c |
| create mode 100644 ld/testsuite/ld-elf/secondary.c |
| create mode 100644 ld/testsuite/ld-elf/secondary.exp |
| create mode 100644 ld/testsuite/ld-elf/secondary.rd |
| create mode 100644 ld/testsuite/ld-elf/secondary1.out |
| create mode 100644 ld/testsuite/ld-elf/secondary1.rd |
| create mode 100644 ld/testsuite/ld-elf/secondary2.rd |
| create mode 100644 ld/testsuite/ld-elf/secondary3.rd |
| create mode 100644 ld/testsuite/ld-elf/secondary3a.s |
| create mode 100644 ld/testsuite/ld-elf/secondary3b.s |
| create mode 100644 ld/testsuite/ld-elf/secondary4.rd |
| create mode 100644 ld/testsuite/ld-elf/secondary4.s |
| create mode 100644 ld/testsuite/ld-elf/secondary5.c |
| create mode 100644 ld/testsuite/ld-elf/secondary5.out |
| create mode 100644 ld/testsuite/ld-elf/secondary6.c |
| create mode 100644 ld/testsuite/ld-elf/secondary6.out |
| create mode 100644 ld/testsuite/ld-elf/secondary7.c |
| create mode 100644 ld/testsuite/ld-elf/secondary7.out |
| |
| diff --git a/ChangeLog.secondary b/ChangeLog.secondary |
| new file mode 100644 |
| index 0000000..f3bb59d |
| --- /dev/null |
| +++ b/ChangeLog.secondary |
| @@ -0,0 +1,221 @@ |
| +bfd/ |
| + |
| +2012-09-11 H.J. Lu <hongjiu.lu@intel.com> |
| + |
| + * elf-bfd.h (_bfd_elf_merge_symbol): Add a boolean argument to |
| + indicate if the old definition is secondary. |
| + |
| + * elf32-sh-symbian.c (sh_symbian_relocate_section): Pass FALSE |
| + to _bfd_elf_merge_symbol. |
| + |
| + * elflink.c (_bfd_elf_merge_symbol): Add a boolean argument to |
| + indicate if the old definition is secondary. Set OLDSECONADRY if |
| + it isn't TRUE. Treat old secondary symbol as weak. |
| + (_bfd_elf_add_default_symbol): Add a boolean argument to if the |
| + old definition is secondary. |
| + (elf_link_add_object_symbols): Pass oldsecondary to |
| + _bfd_elf_merge_symbol and _bfd_elf_add_default_symbol. |
| + |
| +2012-09-06 H.J. Lu <hongjiu.lu@intel.com> |
| + |
| + * elflink.c (is_global_data_symbol_definition): Renamed to ... |
| + (is_global_symbol_definition): This. If secondary symbols are |
| + ignored, count function and common symbols as global definition. |
| + (elf_link_is_defined_archive_symbol): Updated. |
| + |
| +2012-09-06 H.J. Lu <hongjiu.lu@intel.com> |
| + |
| + * elflink.c (is_global_data_symbol_definition): Add an argument |
| + to ignore secondary symbols. |
| + (elf_link_is_defined_archive_symbol): Likewise and pass it to |
| + is_global_data_symbol_definition. |
| + (elf_link_add_archive_symbols): Ignore another secondary |
| + definition. |
| + |
| +2012-06-30 H.J. Lu <hongjiu.lu@intel.com> |
| + |
| + * elflink.c (elf_link_output_extsym): Generate STB_SECONDARY |
| + symbols if needed. |
| + |
| +2012-06-30 H.J. Lu <hongjiu.lu@intel.com> |
| + |
| + * elf.c (swap_out_syms): Output undefined secondary symbols |
| + as weak. |
| + |
| +2012-06-30 H.J. Lu <hongjiu.lu@intel.com> |
| + |
| + * elflink.c (_bfd_elf_merge_symbol): Allow overriding secondary |
| + symbols. |
| + (elf_link_add_object_symbols): Treat secondary symbols as weak |
| + symbols. Allow overriding secondary symbols. |
| + (elf_link_add_archive_symbols): Keep searching if a definition |
| + is secondary. |
| + (elf_link_output_extsym): Treat secondary symbols as weak |
| + symbols. |
| + * linker.c (_bfd_generic_link_add_one_symbol): Treat secondary |
| + symbol as weak symbol. Mark secondary symbol. |
| + |
| +2012-06-30 H.J. Lu <hongjiu.lu@intel.com> |
| + |
| + * archive.c (_bfd_compute_and_write_armap): Treat BSF_SECONDARY |
| + symbol as global. |
| + * elf32-mips.c (mips_elf_sym_is_global): Likewise. |
| + * elfn32-mips.c (mips_elf_sym_is_global): Likewise. |
| + * elf.c (sym_is_global): Likewise. |
| + (swap_out_syms): Handle SECONDARY symbol. |
| + * elf64-ia64-vms.c (elf64_vms_link_add_object_symbols): Likewise. |
| + * elfcode.h (elf_slurp_symbol_table): Likewise. |
| + * elflink.c (elf_link_add_object_symbols): Likewise. |
| + |
| + * syms.c (BSF_SECONDARY): New. |
| + (bfd_print_symbol_vandf): Handle SECONDARY symbol. |
| + (bfd_decode_symclass): Likewise. |
| + |
| + * bfd-in2.h: Regenerated. |
| + |
| +binutils/ |
| + |
| +2012-06-30 H.J. Lu <hongjiu.lu@intel.com> |
| + |
| + * nm.c (filter_symbols): Treat BSF_SECONDARY symbol as global. |
| + |
| + * readelf.c (get_symbol_binding): Handle STB_SECONDARY. |
| + |
| +gas/ |
| + |
| +2012-09-05 H.J. Lu <hongjiu.lu@intel.com> |
| + |
| + * config/obj-elf.c (obj_elf_weak): Don't set symbol weak on |
| + secondary symbol. |
| + |
| +2012-06-30 H.J. Lu <hongjiu.lu@intel.com> |
| + |
| + * config/obj-elf.c (elf_frob_symbol): Handle secondary symbol |
| + for .symver. Also remove the unused secondary symbol. |
| + |
| +2012-06-30 H.J. Lu <hongjiu.lu@intel.com> |
| + |
| + * symbols.c (S_IS_SECONDARY): New. |
| + (S_SET_SECONDARY): Likewise. |
| + (S_FORCE_RELOC): Handle BSF_SECONDARY like BSF_WEAK. |
| + (S_SET_EXTERNAL): Likewise. |
| + (S_CLEAR_EXTERNAL): Likewise. |
| + (S_CLEAR_WEAKREFD): Likewise. |
| + (S_SET_WEAK): Also clear BSF_SECONDARY. |
| + |
| + * symbols.h (S_IS_SECONDARY): New. |
| + (S_SET_SECONDARY): Likewise. |
| + |
| + * config/obj-elf.c (obj_elf_secondary): New. |
| + (elf_pseudo_table): Add "secondary". |
| + (elf_frob_symbol): Also check secondary symbols. |
| + |
| + * doc/as.texinfo: Document .secondary directive. |
| + |
| +gas/testsuite/ |
| + |
| +2012-09-05 H.J. Lu <hongjiu.lu@intel.com> |
| + |
| + * gas/elf/common3.d: New file. |
| + * gas/elf/common3.l: Likewise. |
| + * gas/elf/common3.s: Likewise. |
| + * gas/elf/common4.d: Likewise. |
| + * gas/elf/common4.l: Likewise. |
| + * gas/elf/common4.s: Likewise. |
| + * gas/elf/secondary1.e: Likewise. |
| + * gas/elf/secondary1.s: Likewise. |
| + * gas/elf/secondary2.e: Likewise. |
| + * gas/elf/secondary2.s: Likewise. |
| + |
| + * gas/elf/elf.exp: Run common3, common4, secondary1 and |
| + secondary2. |
| + |
| + * gas/elf/type.s: Add .secondary tests. |
| + * gas/elf/type.e: Updated. |
| + |
| +include/ |
| + |
| +2012-06-30 H.J. Lu <hongjiu.lu@intel.com> |
| + |
| + * bfdlink.h (bfd_link_info): Add emit_secondary. |
| + |
| +2012-06-30 H.J. Lu <hongjiu.lu@intel.com> |
| + |
| + * bfdlink.h (bfd_link_hash_entry): Add secondary. |
| + |
| +include/elf/ |
| + |
| +2012-06-30 H.J. Lu <hongjiu.lu@intel.com> |
| + |
| + * common.h (STB_SECONDARY): New. |
| + |
| +ld/ |
| + |
| +2012-09-08 H.J. Lu <hongjiu.lu@intel.com> |
| + |
| + * ld.texinfo: Change "-z secondary" to "-z nosecondary". |
| + |
| + * ldmain.c (main): Initialize link_info.emit_secondary to TRUE. |
| + |
| + * emultempl/elf32.em (gld${EMULATION_NAME}_handle_option): Set |
| + to link_info.emit_secondary to FALSE for "-z nosecondary". |
| + (gld${EMULATION_NAME}_list_options): Replace "-z secondary" with |
| + "-z nosecondary". |
| + |
| +2012-06-30 H.J. Lu <hongjiu.lu@intel.com> |
| + |
| + * ld.texinfo: Document "-z secondary". |
| + |
| + * emultempl/elf32.em (gld${EMULATION_NAME}_handle_option): Set |
| + to link_info.emit_secondary to TRUE for "-z secondary". |
| + (gld${EMULATION_NAME}_list_options): Add "-z secondary". |
| + |
| +ld/testsuite/ |
| + |
| +2012-09-08 H.J. Lu <hongjiu.lu@intel.com> |
| + |
| + * ld-elf/secondary.exp: Update -Wl,-z,secondary with |
| + -Wl,-z,nosecondary. |
| + |
| +2012-09-06 H.J. Lu <hongjiu.lu@intel.com> |
| + |
| + * ld-elf/library1.c: New file. |
| + * ld-elf/library1.out: Likewise. |
| + * ld-elf/library2.c: Likewise. |
| + * ld-elf/library2.out: Likewise. |
| + * ld-elf/library3.out: Likewise. |
| + * ld-elf/library4.out: Likewise. |
| + * ld-elf/library5a.c: Likewise. |
| + * ld-elf/library5b.c: Likewise. |
| + * ld-elf/library6a.c: Likewise. |
| + * ld-elf/library6b.c: Likewise. |
| + * ld-elf/library6c.c: Likewise. |
| + * ld-elf/library7a.c: Likewise. |
| + * ld-elf/library7b.c: Likewise. |
| + * ld-elf/library7c.c: Likewise. |
| + * ld-elf/secondary-foo.c: Likewise. |
| + * ld-elf/secondary-main.c: Likewise. |
| + * ld-elf/secondary.c: Likewise. |
| + * ld-elf/secondary.exp: Likewise. |
| + * ld-elf/secondary.rd: Likewise. |
| + * ld-elf/secondary1.out: Likewise. |
| + * ld-elf/secondary1.rd: Likewise. |
| + * ld-elf/secondary2.rd: Likewise. |
| + * ld-elf/secondary3.rd: Likewise. |
| + * ld-elf/secondary3a.s: Likewise. |
| + * ld-elf/secondary3b.s: Likewise. |
| + * ld-elf/secondary4.rd: Likewise. |
| + * ld-elf/secondary4.s: Likewise. |
| + * ld-elf/secondary5.c: Likewise. |
| + * ld-elf/secondary5.out: Likewise. |
| + * ld-elf/secondary6.c: Likewise. |
| + * ld-elf/secondary6.out: Likewise. |
| + * ld-elf/secondary7.c: Likewise. |
| + * ld-elf/secondary7.out: Likewise. |
| + * ld-elf/library8.map: Likewise. |
| + * ld-elf/library8a.c: Likewise. |
| + * ld-elf/library8a.rd: Likewise. |
| + * ld-elf/library8b.c: Likewise. |
| + * ld-elf/library8b.rd: Likewise. |
| + * ld-elf/library8c.c: Likewise. |
| + * ld-elf/library8c.rd: Likewise. |
| diff --git a/bfd/archive.c b/bfd/archive.c |
| index 40a3395..0d80fc5 100644 |
| --- a/bfd/archive.c |
| +++ b/bfd/archive.c |
| @@ -2337,6 +2337,7 @@ _bfd_compute_and_write_armap (bfd *arch, unsigned int elength) |
| |
| if (((flags & (BSF_GLOBAL |
| | BSF_WEAK |
| + | BSF_SECONDARY |
| | BSF_INDIRECT |
| | BSF_GNU_UNIQUE)) != 0 |
| || bfd_is_com_section (sec)) |
| diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h |
| index 27fc3fe..fdc1138 100644 |
| --- a/bfd/bfd-in2.h |
| +++ b/bfd/bfd-in2.h |
| @@ -6168,6 +6168,10 @@ typedef struct bfd_symbol |
| with this name and type in use. BSF_OBJECT must also be set. */ |
| #define BSF_GNU_UNIQUE (1 << 23) |
| |
| + /* A secondary global symbol, overridable without warnings by |
| + a regular or weak global symbol of the same name. */ |
| +#define BSF_SECONDARY (1 << 24) |
| + |
| flagword flags; |
| |
| /* A pointer to the section to which this symbol is |
| diff --git a/bfd/elf.c b/bfd/elf.c |
| index 9dc6b6d..97816f4 100644 |
| --- a/bfd/elf.c |
| +++ b/bfd/elf.c |
| @@ -3259,7 +3259,10 @@ sym_is_global (bfd *abfd, asymbol *sym) |
| if (bed->elf_backend_sym_is_global) |
| return (*bed->elf_backend_sym_is_global) (abfd, sym); |
| |
| - return ((sym->flags & (BSF_GLOBAL | BSF_WEAK | BSF_GNU_UNIQUE)) != 0 |
| + return ((sym->flags & (BSF_GLOBAL |
| + | BSF_WEAK |
| + | BSF_SECONDARY |
| + | BSF_GNU_UNIQUE)) != 0 |
| || bfd_is_und_section (bfd_get_section (sym)) |
| || bfd_is_com_section (bfd_get_section (sym))); |
| } |
| @@ -6922,8 +6925,9 @@ Unable to find equivalent output section for symbol '%s' from section '%s'"), |
| #endif |
| sym.st_info = ELF_ST_INFO (STB_GLOBAL, type); |
| } |
| + /* Output undefined secondary symbols as weak. */ |
| else if (bfd_is_und_section (syms[idx]->section)) |
| - sym.st_info = ELF_ST_INFO (((flags & BSF_WEAK) |
| + sym.st_info = ELF_ST_INFO (((flags & (BSF_WEAK | BSF_SECONDARY)) |
| ? STB_WEAK |
| : STB_GLOBAL), |
| type); |
| @@ -6937,6 +6941,8 @@ Unable to find equivalent output section for symbol '%s' from section '%s'"), |
| bind = STB_LOCAL; |
| else if (flags & BSF_GNU_UNIQUE) |
| bind = STB_GNU_UNIQUE; |
| + else if (flags & BSF_SECONDARY) |
| + bind = STB_SECONDARY; |
| else if (flags & BSF_WEAK) |
| bind = STB_WEAK; |
| else if (flags & BSF_GLOBAL) |
| diff --git a/bfd/elf32-mips.c b/bfd/elf32-mips.c |
| index af405bc..e84efad 100644 |
| --- a/bfd/elf32-mips.c |
| +++ b/bfd/elf32-mips.c |
| @@ -2154,7 +2154,10 @@ mips_elf_sym_is_global (bfd *abfd ATTRIBUTE_UNUSED, asymbol *sym) |
| if (SGI_COMPAT (abfd)) |
| return (sym->flags & BSF_SECTION_SYM) == 0; |
| else |
| - return ((sym->flags & (BSF_GLOBAL | BSF_WEAK | BSF_GNU_UNIQUE)) != 0 |
| + return ((sym->flags & (BSF_GLOBAL |
| + | BSF_WEAK |
| + | BSF_SECONDARY |
| + | BSF_GNU_UNIQUE)) != 0 |
| || bfd_is_und_section (bfd_get_section (sym)) |
| || bfd_is_com_section (bfd_get_section (sym))); |
| } |
| diff --git a/bfd/elf64-ia64-vms.c b/bfd/elf64-ia64-vms.c |
| index dd86e3c..0ff1798 100644 |
| --- a/bfd/elf64-ia64-vms.c |
| +++ b/bfd/elf64-ia64-vms.c |
| @@ -4926,6 +4926,10 @@ error_free_dyn: |
| flags = BSF_WEAK; |
| break; |
| |
| + case STB_SECONDARY: |
| + flags = BSF_SECONDARY; |
| + break; |
| + |
| case STB_GNU_UNIQUE: |
| flags = BSF_GNU_UNIQUE; |
| break; |
| diff --git a/bfd/elfcode.h b/bfd/elfcode.h |
| index a49a708..b09ab77 100644 |
| --- a/bfd/elfcode.h |
| +++ b/bfd/elfcode.h |
| @@ -1281,6 +1281,9 @@ elf_slurp_symbol_table (bfd *abfd, asymbol **symptrs, bfd_boolean dynamic) |
| case STB_WEAK: |
| sym->symbol.flags |= BSF_WEAK; |
| break; |
| + case STB_SECONDARY: |
| + sym->symbol.flags |= BSF_SECONDARY; |
| + break; |
| case STB_GNU_UNIQUE: |
| sym->symbol.flags |= BSF_GNU_UNIQUE; |
| break; |
| diff --git a/bfd/elflink.c b/bfd/elflink.c |
| index c1e7948..984cee6 100644 |
| --- a/bfd/elflink.c |
| +++ b/bfd/elflink.c |
| @@ -885,7 +885,8 @@ elf_merge_st_other (bfd *abfd, struct elf_link_hash_entry *h, |
| overriding a new definition. We set TYPE_CHANGE_OK if it is OK for |
| the type to change. We set SIZE_CHANGE_OK if it is OK for the size |
| to change. By OK to change, we mean that we shouldn't warn if the |
| - type or size does change. */ |
| + type or size does change. If OLDSECONARY is TRUE, the old definion |
| + is a secondary symbol. */ |
| |
| static bfd_boolean |
| _bfd_elf_merge_symbol (bfd *abfd, |
| @@ -895,6 +896,7 @@ _bfd_elf_merge_symbol (bfd *abfd, |
| asection **psec, |
| bfd_vma *pvalue, |
| struct elf_link_hash_entry **sym_hash, |
| + bfd_boolean oldsecondary, |
| bfd **poldbfd, |
| bfd_boolean *pold_weak, |
| unsigned int *pold_alignment, |
| @@ -910,7 +912,7 @@ _bfd_elf_merge_symbol (bfd *abfd, |
| int bind; |
| bfd *oldbfd; |
| bfd_boolean newdyn, olddyn, olddef, newdef, newdyncommon, olddyncommon; |
| - bfd_boolean newweak, oldweak, newfunc, oldfunc; |
| + bfd_boolean newweak, oldweak, newfunc, oldfunc, weakbind; |
| const struct elf_backend_data *bed; |
| |
| *skip = FALSE; |
| @@ -968,9 +970,17 @@ _bfd_elf_merge_symbol (bfd *abfd, |
| if (poldbfd && *poldbfd == NULL) |
| *poldbfd = oldbfd; |
| |
| + /* Set OLDSECONADRY if it isn't TRUE. */ |
| + if (!oldsecondary) |
| + oldsecondary = h->root.secondary != 0; |
| + |
| + /* Treat secondary symbols as weak symbols. */ |
| + weakbind = bind == STB_WEAK || bind == STB_SECONDARY; |
| + |
| /* Differentiate strong and weak symbols. */ |
| - newweak = bind == STB_WEAK; |
| - oldweak = (h->root.type == bfd_link_hash_defweak |
| + newweak = weakbind; |
| + oldweak = (oldsecondary |
| + || h->root.type == bfd_link_hash_defweak |
| || h->root.type == bfd_link_hash_undefweak); |
| if (pold_weak) |
| *pold_weak = oldweak; |
| @@ -1001,7 +1011,7 @@ _bfd_elf_merge_symbol (bfd *abfd, |
| { |
| if (bfd_is_und_section (sec)) |
| { |
| - if (bind != STB_WEAK) |
| + if (!weakbind) |
| { |
| h->ref_dynamic_nonweak = 1; |
| hi->ref_dynamic_nonweak = 1; |
| @@ -1250,7 +1260,7 @@ _bfd_elf_merge_symbol (bfd *abfd, |
| |
| if (newdef && !newdyn && olddyn) |
| newweak = FALSE; |
| - if (olddef && newdyn) |
| + if (olddef && newdyn && !oldsecondary) |
| oldweak = FALSE; |
| |
| /* Allow changes between different types of function symbol. */ |
| @@ -1365,10 +1375,14 @@ _bfd_elf_merge_symbol (bfd *abfd, |
| represent variables; this can cause confusion in principle, but |
| any such confusion would seem to indicate an erroneous program or |
| shared library. We also permit a common symbol in a regular |
| - object to override a weak symbol in a shared object. */ |
| + object to override a weak symbol in a shared object. |
| + |
| + We let a definition in a dynamic object override the old secondary |
| + symbol. */ |
| |
| if (newdyn |
| && newdef |
| + && !oldsecondary |
| && (olddef |
| || (h->root.type == bfd_link_hash_common |
| && (newweak || newfunc)))) |
| @@ -1407,8 +1421,9 @@ _bfd_elf_merge_symbol (bfd *abfd, |
| *size_change_ok = TRUE; |
| } |
| |
| - /* Skip weak definitions of symbols that are already defined. */ |
| - if (newdef && olddef && newweak) |
| + /* Skip weak definitions of symbols that are already defined unless |
| + the old definition is secondary. */ |
| + if (newdef && olddef && newweak && !oldsecondary) |
| { |
| /* Don't skip new non-IR weak syms. */ |
| if (!(oldbfd != NULL |
| @@ -1439,18 +1454,20 @@ _bfd_elf_merge_symbol (bfd *abfd, |
| always take precedence over symbols from dynamic objects, even if |
| they are defined after the dynamic object in the link. |
| |
| + The new non-secondary definition overrides the old secondary |
| + definition. |
| + |
| As above, we again permit a common symbol in a regular object to |
| override a definition in a shared object if the shared object |
| symbol is a function or is weak. */ |
| |
| flip = NULL; |
| - if (!newdyn |
| + if (((!newdyn && olddyn && h->def_dynamic) || oldsecondary) |
| + && bind != STB_SECONDARY |
| && (newdef |
| || (bfd_is_com_section (sec) |
| && (oldweak || oldfunc))) |
| - && olddyn |
| - && olddef |
| - && h->def_dynamic) |
| + && olddef) |
| { |
| /* Change the hash table entry to undefined, and let |
| _bfd_generic_link_add_one_symbol do the right thing with the |
| @@ -1553,8 +1570,8 @@ _bfd_elf_merge_symbol (bfd *abfd, |
| |
| /* This function is called to create an indirect symbol from the |
| default for the symbol with the default version if needed. The |
| - symbol is described by H, NAME, SYM, SEC, and VALUE. We |
| - set DYNSYM if the new indirect symbol is dynamic. */ |
| + symbol is described by H, NAME, SYM, SEC, VALUE, and OLDSECONDARY. |
| + We set DYNSYM if the new indirect symbol is dynamic. */ |
| |
| static bfd_boolean |
| _bfd_elf_add_default_symbol (bfd *abfd, |
| @@ -1564,6 +1581,7 @@ _bfd_elf_add_default_symbol (bfd *abfd, |
| Elf_Internal_Sym *sym, |
| asection *sec, |
| bfd_vma value, |
| + bfd_boolean oldsecondary, |
| bfd **poldbfd, |
| bfd_boolean *dynsym) |
| { |
| @@ -1608,8 +1626,9 @@ _bfd_elf_add_default_symbol (bfd *abfd, |
| size_change_ok = FALSE; |
| tmp_sec = sec; |
| if (!_bfd_elf_merge_symbol (abfd, info, shortname, sym, &tmp_sec, &value, |
| - &hi, poldbfd, NULL, NULL, &skip, &override, |
| - &type_change_ok, &size_change_ok)) |
| + &hi, oldsecondary, poldbfd, NULL, NULL, |
| + &skip, &override, &type_change_ok |
| + , &size_change_ok)) |
| return FALSE; |
| |
| if (skip) |
| @@ -1723,8 +1742,8 @@ nondefault: |
| size_change_ok = FALSE; |
| tmp_sec = sec; |
| if (!_bfd_elf_merge_symbol (abfd, info, shortname, sym, &tmp_sec, &value, |
| - &hi, poldbfd, NULL, NULL, &skip, &override, |
| - &type_change_ok, &size_change_ok)) |
| + &hi, oldsecondary, poldbfd, NULL, NULL, &skip, |
| + &override, &type_change_ok, &size_change_ok)) |
| return FALSE; |
| |
| if (skip) |
| @@ -2868,31 +2887,41 @@ _bfd_elf_tls_setup (bfd *obfd, struct bfd_link_info *info) |
| return tls; |
| } |
| |
| -/* Return TRUE iff this is a non-common, definition of a non-function symbol. */ |
| +/* Return TRUE iff this is a non-common, definition of a |
| + non-function symbol, unless IGNORE_SECONDARY is TRUE. */ |
| + |
| static bfd_boolean |
| -is_global_data_symbol_definition (bfd *abfd ATTRIBUTE_UNUSED, |
| - Elf_Internal_Sym *sym) |
| +is_global_symbol_definition (bfd *abfd, Elf_Internal_Sym *sym, |
| + bfd_boolean ignore_secondary) |
| { |
| - const struct elf_backend_data *bed; |
| + /* Ignore secondary symbols. */ |
| + if (ignore_secondary && ELF_ST_BIND (sym->st_info) == STB_SECONDARY) |
| + return FALSE; |
| |
| /* Local symbols do not count, but target specific ones might. */ |
| if (ELF_ST_BIND (sym->st_info) != STB_GLOBAL |
| && ELF_ST_BIND (sym->st_info) < STB_LOOS) |
| return FALSE; |
| |
| - bed = get_elf_backend_data (abfd); |
| - /* Function symbols do not count. */ |
| - if (bed->is_function_type (ELF_ST_TYPE (sym->st_info))) |
| - return FALSE; |
| - |
| /* If the section is undefined, then so is the symbol. */ |
| if (sym->st_shndx == SHN_UNDEF) |
| return FALSE; |
| |
| - /* If the symbol is defined in the common section, then |
| - it is a common definition and so does not count. */ |
| - if (bed->common_definition (sym)) |
| - return FALSE; |
| + /* If secondary symbols are ignored, count function and common |
| + symbols as global definition. */ |
| + if (!ignore_secondary) |
| + { |
| + const struct elf_backend_data *bed = get_elf_backend_data (abfd); |
| + |
| + /* Function symbols do not count. */ |
| + if (bed->is_function_type (ELF_ST_TYPE (sym->st_info))) |
| + return FALSE; |
| + |
| + /* If the symbol is defined in the common section, then |
| + it is a common definition and so does not count. */ |
| + if (bed->common_definition (sym)) |
| + return FALSE; |
| + } |
| |
| /* If the symbol is in a target specific section then we |
| must rely upon the backend to tell us what it is. */ |
| @@ -2911,9 +2940,12 @@ is_global_data_symbol_definition (bfd *abfd ATTRIBUTE_UNUSED, |
| |
| /* Search the symbol table of the archive element of the archive ABFD |
| whose archive map contains a mention of SYMDEF, and determine if |
| - the symbol is defined in this element. */ |
| + the symbol is defined in this element. Igore seconday defintion, |
| + it IGNORE_SECONDARY is TRUE. */ |
| + |
| static bfd_boolean |
| -elf_link_is_defined_archive_symbol (bfd * abfd, carsym * symdef) |
| +elf_link_is_defined_archive_symbol (bfd * abfd, carsym * symdef, |
| + bfd_boolean ignore_secondary) |
| { |
| Elf_Internal_Shdr * hdr; |
| bfd_size_type symcount; |
| @@ -2974,7 +3006,8 @@ elf_link_is_defined_archive_symbol (bfd * abfd, carsym * symdef) |
| |
| if (strcmp (name, symdef->name) == 0) |
| { |
| - result = is_global_data_symbol_definition (abfd, isym); |
| + result = is_global_symbol_definition (abfd, isym, |
| + ignore_secondary); |
| break; |
| } |
| } |
| @@ -3822,6 +3855,7 @@ error_free_dyn: |
| bfd_boolean common; |
| unsigned int old_alignment; |
| bfd *old_bfd; |
| + bfd_boolean oldsecondary; |
| |
| override = FALSE; |
| |
| @@ -3849,6 +3883,10 @@ error_free_dyn: |
| flags = BSF_WEAK; |
| break; |
| |
| + case STB_SECONDARY: |
| + flags = BSF_SECONDARY; |
| + break; |
| + |
| case STB_GNU_UNIQUE: |
| flags = BSF_GNU_UNIQUE; |
| break; |
| @@ -4084,7 +4122,7 @@ error_free_dyn: |
| | (isym->st_other & ~ELF_ST_VISIBILITY (-1))); |
| |
| if (!_bfd_elf_merge_symbol (abfd, info, name, isym, &sec, &value, |
| - sym_hash, &old_bfd, &old_weak, |
| + sym_hash, FALSE, &old_bfd, &old_weak, |
| &old_alignment, &skip, &override, |
| &type_change_ok, &size_change_ok)) |
| goto error_free_vers; |
| @@ -4104,7 +4142,12 @@ error_free_dyn: |
| && vernum > 1 |
| && definition) |
| h->verinfo.verdef = &elf_tdata (abfd)->verdef[vernum - 1]; |
| + |
| + /* Remember if the old definition is secondary. */ |
| + oldsecondary = h->root.secondary != 0; |
| } |
| + else |
| + oldsecondary = FALSE; |
| |
| if (! (_bfd_generic_link_add_one_symbol |
| (info, abfd, name, flags, sec, value, NULL, FALSE, bed->collect, |
| @@ -4184,10 +4227,14 @@ error_free_dyn: |
| if (! definition) |
| { |
| h->ref_regular = 1; |
| - if (bind != STB_WEAK) |
| + /* Treat secondary symbols as weak symbols. */ |
| + if (bind != STB_WEAK && bind != STB_SECONDARY) |
| h->ref_regular_nonweak = 1; |
| } |
| - else |
| + /* Mark it defined in a regular object if it is a |
| + non-secondary definition or it hasn't been defined |
| + in a dynamic object. */ |
| + else if (!h->def_dynamic || bind != STB_SECONDARY) |
| { |
| h->def_regular = 1; |
| if (h->def_dynamic) |
| @@ -4216,6 +4263,13 @@ error_free_dyn: |
| { |
| h->def_dynamic = 1; |
| hi->def_dynamic = 1; |
| + /* Dynamic definition overrides regular old secondary |
| + definition. */ |
| + if (oldsecondary) |
| + { |
| + h->def_regular = 0; |
| + hi->def_regular = 0; |
| + } |
| } |
| |
| /* If the indirect symbol has been forced local, don't |
| @@ -4234,7 +4288,8 @@ error_free_dyn: |
| if (definition |
| || (!override && h->root.type == bfd_link_hash_common)) |
| if (!_bfd_elf_add_default_symbol (abfd, info, h, name, isym, |
| - sec, value, &old_bfd, &dynsym)) |
| + sec, value, oldsecondary, |
| + &old_bfd, &dynsym)) |
| goto error_free_vers; |
| |
| /* Check the alignment when a common symbol is involved. This |
| @@ -5024,16 +5079,27 @@ elf_link_add_archive_symbols (bfd *abfd, struct bfd_link_info *info) |
| map alone. Instead we must read in the element's symbol |
| table and check that to see what kind of symbol definition |
| this is. */ |
| - if (! elf_link_is_defined_archive_symbol (abfd, symdef)) |
| + if (! elf_link_is_defined_archive_symbol (abfd, symdef, |
| + FALSE)) |
| continue; |
| } |
| - else if (h->root.type != bfd_link_hash_undefined) |
| + /* Keep searching if a definition is secondary. */ |
| + else if (h->root.type != bfd_link_hash_undefined |
| + && !h->root.secondary) |
| { |
| if (h->root.type != bfd_link_hash_undefweak) |
| /* Symbol must be defined. Don't check it again. */ |
| included[i] = TRUE; |
| continue; |
| } |
| + else if (h->root.secondary |
| + && h->root.type == bfd_link_hash_defweak) |
| + { |
| + /* Ignore another secondary definition. */ |
| + if (! elf_link_is_defined_archive_symbol (abfd, symdef, |
| + TRUE)) |
| + continue; |
| + } |
| |
| /* We need to include this archive member. */ |
| element = _bfd_get_elt_at_filepos (abfd, symdef->file_offset); |
| @@ -8807,7 +8873,21 @@ elf_link_output_extsym (struct bfd_hash_entry *bh, void *data) |
| 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); |
| + { |
| + /* Generate defined secondary symbols for "ld -shared -z secondary" |
| + and "ld -r". For undefined secondary symbols, we convert them |
| + to weak symbols. We also convert defined secondary symbols in |
| + executables to weak symbols since their bindings in executables |
| + are final and can't be changed. */ |
| + if ((flinfo->info->relocatable |
| + || (!flinfo->info->executable |
| + && flinfo->info->emit_secondary)) |
| + && h->root.type == bfd_link_hash_defweak |
| + && h->root.secondary) |
| + sym.st_info = ELF_ST_INFO (STB_SECONDARY, h->type); |
| + else |
| + 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; |
| @@ -8938,7 +9018,8 @@ elf_link_output_extsym (struct bfd_hash_entry *bh, void *data) |
| if (sym.st_shndx == SHN_UNDEF |
| && h->ref_regular |
| && (ELF_ST_BIND (sym.st_info) == STB_GLOBAL |
| - || ELF_ST_BIND (sym.st_info) == STB_WEAK)) |
| + || ELF_ST_BIND (sym.st_info) == STB_WEAK |
| + || ELF_ST_BIND (sym.st_info) == STB_SECONDARY)) |
| { |
| int bindtype; |
| unsigned int type = ELF_ST_TYPE (sym.st_info); |
| @@ -8964,10 +9045,12 @@ elf_link_output_extsym (struct bfd_hash_entry *bh, void *data) |
| sym.st_size = 0; |
| |
| /* If a non-weak symbol with non-default visibility is not defined |
| - locally, it is a fatal error. */ |
| + locally, it is a fatal error. Treat secondary symbols as weak |
| + symbols. */ |
| if (!flinfo->info->relocatable |
| && ELF_ST_VISIBILITY (sym.st_other) != STV_DEFAULT |
| && ELF_ST_BIND (sym.st_info) != STB_WEAK |
| + && ELF_ST_BIND (sym.st_info) != STB_SECONDARY |
| && h->root.type == bfd_link_hash_undefined |
| && !h->def_regular) |
| { |
| diff --git a/bfd/elfn32-mips.c b/bfd/elfn32-mips.c |
| index 1286cc1..b5c5fa2 100644 |
| --- a/bfd/elfn32-mips.c |
| +++ b/bfd/elfn32-mips.c |
| @@ -3262,7 +3262,10 @@ mips_elf_sym_is_global (bfd *abfd ATTRIBUTE_UNUSED, asymbol *sym) |
| if (SGI_COMPAT (abfd)) |
| return (sym->flags & BSF_SECTION_SYM) == 0; |
| else |
| - return ((sym->flags & (BSF_GLOBAL | BSF_WEAK | BSF_GNU_UNIQUE)) != 0 |
| + return ((sym->flags & (BSF_GLOBAL |
| + | BSF_WEAK |
| + | BSF_SECONDARY |
| + | BSF_GNU_UNIQUE)) != 0 |
| || bfd_is_und_section (bfd_get_section (sym)) |
| || bfd_is_com_section (bfd_get_section (sym))); |
| } |
| diff --git a/bfd/linker.c b/bfd/linker.c |
| index abdf5b0..9cb5cc4 100644 |
| --- a/bfd/linker.c |
| +++ b/bfd/linker.c |
| @@ -1444,6 +1444,7 @@ _bfd_generic_link_add_one_symbol (struct bfd_link_info *info, |
| struct bfd_link_hash_entry *h; |
| struct bfd_link_hash_entry *inh = NULL; |
| bfd_boolean cycle; |
| + unsigned int secondary; |
| |
| BFD_ASSERT (section != NULL); |
| |
| @@ -1508,15 +1509,53 @@ _bfd_generic_link_add_one_symbol (struct bfd_link_info *info, |
| return FALSE; |
| } |
| |
| + /* Since secondary symbols have lower precedence than weak symbols, |
| + we treat them as weak symbols here. */ |
| + secondary = (flags & BSF_SECONDARY) != 0; |
| + if (secondary) |
| + switch (row) |
| + { |
| + default: |
| + break; |
| + |
| + case UNDEF_ROW: |
| + row = UNDEFW_ROW; |
| + break; |
| + |
| + case DEF_ROW: |
| + row = DEFW_ROW; |
| + break; |
| + } |
| + |
| if (hashp != NULL) |
| *hashp = h; |
| |
| do |
| { |
| enum link_action action; |
| + enum bfd_link_hash_type type; |
| + |
| + type = h->type; |
| + /* Convert a secondary symbol to a weak symbol. Backend is |
| + responsible to let a weak symbol override a secondary |
| + symbol. */ |
| + if (h->secondary) |
| + switch (type) |
| + { |
| + default: |
| + break; |
| + |
| + case bfd_link_hash_undefined: |
| + type = bfd_link_hash_undefweak; |
| + break; |
| + |
| + case bfd_link_hash_defined: |
| + type = bfd_link_hash_defweak; |
| + break; |
| + } |
| |
| cycle = FALSE; |
| - action = link_action[(int) row][(int) h->type]; |
| + action = link_action[(int) row][(int) type]; |
| switch (action) |
| { |
| case FAIL: |
| @@ -1561,6 +1600,9 @@ _bfd_generic_link_add_one_symbol (struct bfd_link_info *info, |
| h->u.def.section = section; |
| h->u.def.value = value; |
| |
| + /* Mark if this is a secondary symbol. */ |
| + h->secondary = secondary; |
| + |
| /* If we have been asked to, we act like collect2 and |
| identify all functions that might be global |
| constructors and destructors and pass them up in a |
| diff --git a/bfd/syms.c b/bfd/syms.c |
| index a1d1d77..6077121 100644 |
| --- a/bfd/syms.c |
| +++ b/bfd/syms.c |
| @@ -306,6 +306,10 @@ CODE_FRAGMENT |
| . with this name and type in use. BSF_OBJECT must also be set. *} |
| .#define BSF_GNU_UNIQUE (1 << 23) |
| . |
| +. {* A secondary global symbol, overridable without warnings by |
| +. a regular or weak global symbol of the same name. *} |
| +.#define BSF_SECONDARY (1 << 24) |
| +. |
| . flagword flags; |
| . |
| . {* A pointer to the section to which this symbol is |
| @@ -489,6 +493,7 @@ bfd_print_symbol_vandf (bfd *abfd, void *arg, asymbol *symbol) |
| ((type & BSF_LOCAL) |
| ? (type & BSF_GLOBAL) ? '!' : 'l' |
| : (type & BSF_GLOBAL) ? 'g' |
| + : (type & BSF_SECONDARY) ? 's' |
| : (type & BSF_GNU_UNIQUE) ? 'u' : ' '), |
| (type & BSF_WEAK) ? 'w' : ' ', |
| (type & BSF_CONSTRUCTOR) ? 'C' : ' ', |
| @@ -692,6 +697,15 @@ bfd_decode_symclass (asymbol *symbol) |
| } |
| if (symbol->flags & BSF_GNU_UNIQUE) |
| return 'u'; |
| + if (symbol->flags & BSF_SECONDARY) |
| + { |
| + /* If secondary, determine if it's specifically an object |
| + or non-object weak. */ |
| + if (symbol->flags & BSF_OBJECT) |
| + return 'Y'; |
| + else |
| + return 'S'; |
| + } |
| if (!(symbol->flags & (BSF_GLOBAL | BSF_LOCAL))) |
| return '?'; |
| |
| diff --git a/binutils/nm.c b/binutils/nm.c |
| index ecd147e..300fd13 100644 |
| --- a/binutils/nm.c |
| +++ b/binutils/nm.c |
| @@ -444,6 +444,7 @@ filter_symbols (bfd *abfd, bfd_boolean is_dynamic, void *minisyms, |
| /* PR binutls/12753: Unique symbols are global too. */ |
| keep = ((sym->flags & (BSF_GLOBAL |
| | BSF_WEAK |
| + | BSF_SECONDARY |
| | BSF_GNU_UNIQUE)) != 0 |
| || bfd_is_und_section (sym->section) |
| || bfd_is_com_section (sym->section)); |
| diff --git a/binutils/readelf.c b/binutils/readelf.c |
| index 7463c55..6596a21 100644 |
| --- a/binutils/readelf.c |
| +++ b/binutils/readelf.c |
| @@ -9262,6 +9262,7 @@ get_symbol_binding (unsigned int binding) |
| case STB_LOCAL: return "LOCAL"; |
| case STB_GLOBAL: return "GLOBAL"; |
| case STB_WEAK: return "WEAK"; |
| + case STB_SECONDARY: return "SECOND"; |
| default: |
| if (binding >= STB_LOPROC && binding <= STB_HIPROC) |
| snprintf (buff, sizeof (buff), _("<processor specific>: %d"), |
| diff --git a/gas/config/obj-elf.c b/gas/config/obj-elf.c |
| index e2ef99e..ab61461 100644 |
| --- a/gas/config/obj-elf.c |
| +++ b/gas/config/obj-elf.c |
| @@ -68,6 +68,7 @@ static void obj_elf_line (int); |
| static void obj_elf_size (int); |
| static void obj_elf_type (int); |
| static void obj_elf_ident (int); |
| +static void obj_elf_secondary (int); |
| static void obj_elf_weak (int); |
| static void obj_elf_local (int); |
| static void obj_elf_visibility (int); |
| @@ -97,6 +98,7 @@ static const pseudo_typeS elf_pseudo_table[] = |
| {"type", obj_elf_type, 0}, |
| {"version", obj_elf_version, 0}, |
| {"weak", obj_elf_weak, 0}, |
| + {"secondary", obj_elf_secondary, 0}, |
| |
| /* These define symbol visibility. */ |
| {"internal", obj_elf_visibility, STV_INTERNAL}, |
| @@ -443,6 +445,29 @@ obj_elf_local (int ignore ATTRIBUTE_UNUSED) |
| } |
| |
| static void |
| +obj_elf_secondary (int ignore ATTRIBUTE_UNUSED) |
| +{ |
| + int c; |
| + symbolS *symbolP; |
| + |
| + do |
| + { |
| + symbolP = get_sym_from_input_line_and_check (); |
| + c = *input_line_pointer; |
| + S_SET_SECONDARY (symbolP); |
| + if (c == ',') |
| + { |
| + input_line_pointer++; |
| + SKIP_WHITESPACE (); |
| + if (*input_line_pointer == '\n') |
| + c = '\n'; |
| + } |
| + } |
| + while (c == ','); |
| + demand_empty_rest_of_line (); |
| +} |
| + |
| +static void |
| obj_elf_weak (int ignore ATTRIBUTE_UNUSED) |
| { |
| int c; |
| @@ -452,7 +477,8 @@ obj_elf_weak (int ignore ATTRIBUTE_UNUSED) |
| { |
| symbolP = get_sym_from_input_line_and_check (); |
| c = *input_line_pointer; |
| - S_SET_WEAK (symbolP); |
| + if (!S_IS_SECONDARY (symbolP)) |
| + S_SET_WEAK (symbolP); |
| if (c == ',') |
| { |
| input_line_pointer++; |
| @@ -2194,18 +2220,24 @@ elf_frob_symbol (symbolS *symp, int *puntp) |
| if (S_IS_WEAK (symp)) |
| S_SET_WEAK (symp2); |
| |
| + if (S_IS_SECONDARY (symp)) |
| + S_SET_SECONDARY (symp2); |
| + |
| if (S_IS_EXTERNAL (symp)) |
| S_SET_EXTERNAL (symp2); |
| } |
| } |
| } |
| |
| - /* Double check weak symbols. */ |
| - if (S_IS_WEAK (symp)) |
| + /* Double check weak and secondary symbols. */ |
| + if (S_IS_COMMON (symp)) |
| { |
| - if (S_IS_COMMON (symp)) |
| + if (S_IS_WEAK (symp)) |
| as_bad (_("symbol `%s' can not be both weak and common"), |
| S_GET_NAME (symp)); |
| + else if (S_IS_SECONDARY (symp)) |
| + as_bad (_("symbol `%s' can not be both secondary and common"), |
| + S_GET_NAME (symp)); |
| } |
| |
| #ifdef TC_MIPS |
| @@ -2419,7 +2451,7 @@ elf_frob_file_before_adjust (void) |
| /* If there was .weak foo, but foo was neither defined nor |
| used anywhere, remove it. */ |
| |
| - else if (S_IS_WEAK (symp) |
| + else if ((S_IS_WEAK (symp) || S_IS_SECONDARY (symp)) |
| && symbol_used_p (symp) == 0 |
| && symbol_used_in_reloc_p (symp) == 0) |
| symbol_remove (symp, &symbol_rootP, &symbol_lastP); |
| diff --git a/gas/doc/as.texinfo b/gas/doc/as.texinfo |
| index 251b6d5..0cf993d 100644 |
| --- a/gas/doc/as.texinfo |
| +++ b/gas/doc/as.texinfo |
| @@ -4270,6 +4270,7 @@ Some machine configurations provide additional directives. |
| * Print:: @code{.print @var{string}} |
| @ifset ELF |
| * Protected:: @code{.protected @var{names}} |
| +* Secondary:: @code{.secondary @var{names}} |
| @end ifset |
| |
| * Psize:: @code{.psize @var{lines}, @var{columns}} |
| @@ -5952,6 +5953,14 @@ their binding: local, global or weak). The directive sets the visibility to |
| components that defines them must be resolved to the definition in that |
| component, even if a definition in another component would normally preempt |
| this. |
| + |
| +@node Secondary |
| +@section @code{.secondary @var{names}} |
| + |
| +@cindex @code{secondary} directive |
| +This directive sets the secondary attribute on the comma separated list |
| +of symbol @code{names}. If the symbols do not already exist, they will |
| +be created. |
| @end ifset |
| |
| @node Psize |
| diff --git a/gas/symbols.c b/gas/symbols.c |
| index 6af8604..87f22d6 100644 |
| --- a/gas/symbols.c |
| +++ b/gas/symbols.c |
| @@ -2033,6 +2033,14 @@ S_IS_WEAK (symbolS *s) |
| } |
| |
| int |
| +S_IS_SECONDARY (symbolS *s) |
| +{ |
| + if (LOCAL_SYMBOL_CHECK (s)) |
| + return 0; |
| + return (s->bsym->flags & BSF_SECONDARY) != 0; |
| +} |
| + |
| +int |
| S_IS_WEAKREFR (symbolS *s) |
| { |
| if (LOCAL_SYMBOL_CHECK (s)) |
| @@ -2079,7 +2087,7 @@ S_FORCE_RELOC (symbolS *s, int strict) |
| return ((struct local_symbol *) s)->lsy_section == undefined_section; |
| |
| return ((strict |
| - && ((s->bsym->flags & BSF_WEAK) != 0 |
| + && ((s->bsym->flags & (BSF_WEAK | BSF_SECONDARY)) != 0 |
| || (EXTERN_FORCE_RELOC |
| && (s->bsym->flags & BSF_GLOBAL) != 0))) |
| || (s->bsym->flags & BSF_GNU_INDIRECT_FUNCTION) != 0 |
| @@ -2215,9 +2223,9 @@ S_SET_EXTERNAL (symbolS *s) |
| { |
| if (LOCAL_SYMBOL_CHECK (s)) |
| s = local_symbol_convert ((struct local_symbol *) s); |
| - if ((s->bsym->flags & BSF_WEAK) != 0) |
| + if ((s->bsym->flags & (BSF_WEAK | BSF_SECONDARY)) != 0) |
| { |
| - /* Let .weak override .global. */ |
| + /* Let .weak/.secondary override .global. */ |
| return; |
| } |
| if (s->bsym->flags & BSF_SECTION_SYM) |
| @@ -2240,7 +2248,7 @@ S_SET_EXTERNAL (symbolS *s) |
| } |
| #endif |
| s->bsym->flags |= BSF_GLOBAL; |
| - s->bsym->flags &= ~(BSF_LOCAL | BSF_WEAK); |
| + s->bsym->flags &= ~(BSF_LOCAL | BSF_WEAK | BSF_SECONDARY); |
| |
| #ifdef TE_PE |
| if (! an_external_name && S_GET_NAME(s)[0] != '.') |
| @@ -2253,13 +2261,13 @@ S_CLEAR_EXTERNAL (symbolS *s) |
| { |
| if (LOCAL_SYMBOL_CHECK (s)) |
| return; |
| - if ((s->bsym->flags & BSF_WEAK) != 0) |
| + if ((s->bsym->flags & (BSF_WEAK | BSF_SECONDARY)) != 0) |
| { |
| - /* Let .weak override. */ |
| + /* Let .weak/.secondary override. */ |
| return; |
| } |
| s->bsym->flags |= BSF_LOCAL; |
| - s->bsym->flags &= ~(BSF_GLOBAL | BSF_WEAK); |
| + s->bsym->flags &= ~(BSF_GLOBAL | BSF_WEAK | BSF_SECONDARY); |
| } |
| |
| void |
| @@ -2271,7 +2279,16 @@ S_SET_WEAK (symbolS *s) |
| obj_set_weak_hook (s); |
| #endif |
| s->bsym->flags |= BSF_WEAK; |
| - s->bsym->flags &= ~(BSF_GLOBAL | BSF_LOCAL); |
| + s->bsym->flags &= ~(BSF_GLOBAL | BSF_SECONDARY | BSF_LOCAL); |
| +} |
| + |
| +void |
| +S_SET_SECONDARY (symbolS *s) |
| +{ |
| + if (LOCAL_SYMBOL_CHECK (s)) |
| + s = local_symbol_convert ((struct local_symbol *) s); |
| + s->bsym->flags |= BSF_SECONDARY; |
| + s->bsym->flags &= ~(BSF_GLOBAL | BSF_WEAK | BSF_LOCAL); |
| } |
| |
| void |
| @@ -2328,6 +2345,12 @@ S_CLEAR_WEAKREFD (symbolS *s) |
| s->bsym->flags &= ~BSF_WEAK; |
| s->bsym->flags |= BSF_LOCAL; |
| } |
| + /* The same applies to secondary symbol. */ |
| + else if (s->bsym->flags & BSF_SECONDARY) |
| + { |
| + s->bsym->flags &= ~BSF_SECONDARY; |
| + s->bsym->flags |= BSF_LOCAL; |
| + } |
| } |
| } |
| |
| diff --git a/gas/symbols.h b/gas/symbols.h |
| index 4c83033..f765aec 100644 |
| --- a/gas/symbols.h |
| +++ b/gas/symbols.h |
| @@ -91,6 +91,7 @@ extern void S_SET_VALUE (symbolS *, valueT); |
| extern int S_IS_FUNCTION (symbolS *); |
| extern int S_IS_EXTERNAL (symbolS *); |
| extern int S_IS_WEAK (symbolS *); |
| +extern int S_IS_SECONDARY (symbolS *); |
| extern int S_IS_WEAKREFR (symbolS *); |
| extern int S_IS_WEAKREFD (symbolS *); |
| extern int S_IS_COMMON (symbolS *); |
| @@ -109,6 +110,7 @@ extern void S_SET_EXTERNAL (symbolS *); |
| extern void S_SET_NAME (symbolS *, const char *); |
| extern void S_CLEAR_EXTERNAL (symbolS *); |
| extern void S_SET_WEAK (symbolS *); |
| +extern void S_SET_SECONDARY (symbolS *); |
| extern void S_SET_WEAKREFR (symbolS *); |
| extern void S_CLEAR_WEAKREFR (symbolS *); |
| extern void S_SET_WEAKREFD (symbolS *); |
| diff --git a/gas/testsuite/gas/elf/common3.d b/gas/testsuite/gas/elf/common3.d |
| new file mode 100644 |
| index 0000000..e73f6c5 |
| --- /dev/null |
| +++ b/gas/testsuite/gas/elf/common3.d |
| @@ -0,0 +1,2 @@ |
| +#name: secondary and common directives |
| +#error-output: common3.l |
| diff --git a/gas/testsuite/gas/elf/common3.l b/gas/testsuite/gas/elf/common3.l |
| new file mode 100644 |
| index 0000000..58d5142 |
| --- /dev/null |
| +++ b/gas/testsuite/gas/elf/common3.l |
| @@ -0,0 +1,2 @@ |
| +[^:]*: Assembler messages: |
| +[^:]*: Error: symbol `foobar' can not be both secondary and common |
| diff --git a/gas/testsuite/gas/elf/common3.s b/gas/testsuite/gas/elf/common3.s |
| new file mode 100644 |
| index 0000000..df8b7ed |
| --- /dev/null |
| +++ b/gas/testsuite/gas/elf/common3.s |
| @@ -0,0 +1,2 @@ |
| + .secondary foobar |
| + .comm foobar,30 |
| diff --git a/gas/testsuite/gas/elf/common4.d b/gas/testsuite/gas/elf/common4.d |
| new file mode 100644 |
| index 0000000..aca59c0 |
| --- /dev/null |
| +++ b/gas/testsuite/gas/elf/common4.d |
| @@ -0,0 +1,2 @@ |
| +#name: common and secondary directives |
| +#error-output: common4.l |
| diff --git a/gas/testsuite/gas/elf/common4.l b/gas/testsuite/gas/elf/common4.l |
| new file mode 100644 |
| index 0000000..58d5142 |
| --- /dev/null |
| +++ b/gas/testsuite/gas/elf/common4.l |
| @@ -0,0 +1,2 @@ |
| +[^:]*: Assembler messages: |
| +[^:]*: Error: symbol `foobar' can not be both secondary and common |
| diff --git a/gas/testsuite/gas/elf/common4.s b/gas/testsuite/gas/elf/common4.s |
| new file mode 100644 |
| index 0000000..37bd0ce |
| --- /dev/null |
| +++ b/gas/testsuite/gas/elf/common4.s |
| @@ -0,0 +1,2 @@ |
| + .comm foobar,30 |
| + .secondary foobar |
| diff --git a/gas/testsuite/gas/elf/elf.exp b/gas/testsuite/gas/elf/elf.exp |
| index f17f7e0..65bb3c5 100644 |
| --- a/gas/testsuite/gas/elf/elf.exp |
| +++ b/gas/testsuite/gas/elf/elf.exp |
| @@ -203,6 +203,11 @@ if { [is_elf_format] } then { |
| |
| run_dump_test "common1" |
| run_dump_test "common2" |
| + run_dump_test "common3" |
| + run_dump_test "common4" |
| + |
| + run_elf_list_test "secondary1" "" "" "-s" "| grep \"secondary_\"" |
| + run_elf_list_test "secondary2" "" "" "-s" "| grep \"secondary_\"" |
| |
| load_lib gas-dg.exp |
| dg-init |
| diff --git a/gas/testsuite/gas/elf/secondary1.e b/gas/testsuite/gas/elf/secondary1.e |
| new file mode 100644 |
| index 0000000..da00dfb |
| --- /dev/null |
| +++ b/gas/testsuite/gas/elf/secondary1.e |
| @@ -0,0 +1,4 @@ |
| + +.: 0+0 +1 +FUNC +SECOND +DEFAULT +. secondary_function1 |
| + +.: 0+1 +1 +FUNC +SECOND +DEFAULT +. secondary_function2 |
| + +.: 0+0 +1 +OBJECT +SECOND +DEFAULT +. secondary_object1 |
| + +.: 0+1 +1 +OBJECT +SECOND +DEFAULT +. secondary_object2 |
| diff --git a/gas/testsuite/gas/elf/secondary1.s b/gas/testsuite/gas/elf/secondary1.s |
| new file mode 100644 |
| index 0000000..6a3032d |
| --- /dev/null |
| +++ b/gas/testsuite/gas/elf/secondary1.s |
| @@ -0,0 +1,33 @@ |
| + .text |
| + |
| + .size secondary_function1,1 |
| + .secondary secondary_function1 |
| + .weak secondary_function1 |
| + .type secondary_function1,%function |
| +secondary_function1: |
| + .byte 0x0 |
| + .size secondary_function1,1 |
| + |
| + .size secondary_function2,1 |
| + .weak secondary_function2 |
| + .secondary secondary_function2 |
| + .type secondary_function2,%function |
| +secondary_function2: |
| + .byte 0x0 |
| + .size secondary_function2,1 |
| + |
| + |
| + .data |
| + .type secondary_object1,%object |
| + .weak secondary_object1 |
| + .secondary secondary_object1 |
| +secondary_object1: |
| + .byte 0x0 |
| + .size secondary_object1,1 |
| + |
| + .type secondary_object2,%object |
| + .weak secondary_object2 |
| + .secondary secondary_object2 |
| +secondary_object2: |
| + .byte 0x0 |
| + .size secondary_object2,1 |
| diff --git a/gas/testsuite/gas/elf/secondary2.e b/gas/testsuite/gas/elf/secondary2.e |
| new file mode 100644 |
| index 0000000..0470eb8 |
| --- /dev/null |
| +++ b/gas/testsuite/gas/elf/secondary2.e |
| @@ -0,0 +1 @@ |
| + +.: 0+ +0 +[A-Z]+ +WEAK +DEFAULT +UND secondary_function |
| diff --git a/gas/testsuite/gas/elf/secondary2.s b/gas/testsuite/gas/elf/secondary2.s |
| new file mode 100644 |
| index 0000000..234330a |
| --- /dev/null |
| +++ b/gas/testsuite/gas/elf/secondary2.s |
| @@ -0,0 +1,5 @@ |
| + .text |
| + .secondary secondary_function |
| + .dc.a secondary_function |
| + .data |
| + .secondary secondary_object |
| diff --git a/gas/testsuite/gas/elf/type.e b/gas/testsuite/gas/elf/type.e |
| index a1159bf..d4c0548 100644 |
| --- a/gas/testsuite/gas/elf/type.e |
| +++ b/gas/testsuite/gas/elf/type.e |
| @@ -3,5 +3,7 @@ |
| +.+: 0+0 +1 +OBJECT +LOCAL +DEFAULT +. object |
| +.+: 0+1 +1 +TLS +LOCAL +DEFAULT +. tls_object |
| +.+: 0+2 +1 +NOTYPE +LOCAL +DEFAULT +. notype |
| + +.+: 0+2 +1 +FUNC +SECOND +DEFAULT +. secondary_function |
| +.+: 0+3 +1 +OBJECT +UNIQUE +DEFAULT +. unique_global |
| + +.+: 0+4 +1 +OBJECT +SECOND +DEFAULT +. secondary_object |
| +.+: 0+1 +1 +(COMMON|OBJECT) +GLOBAL +DEFAULT +COM common |
| diff --git a/gas/testsuite/gas/elf/type.s b/gas/testsuite/gas/elf/type.s |
| index d0a1afd..bd7df2c 100644 |
| --- a/gas/testsuite/gas/elf/type.s |
| +++ b/gas/testsuite/gas/elf/type.s |
| @@ -10,6 +10,12 @@ function: |
| indirect_function: |
| .byte 0x0 |
| |
| + .size secondary_function,1 |
| + .secondary secondary_function |
| + .type secondary_function,%function |
| +secondary_function: |
| + .byte 0x0 |
| + |
| .data |
| |
| .type object,%object |
| @@ -32,6 +38,11 @@ unique_global: |
| .byte 0x0 |
| .size unique_global,1 |
| |
| + .type secondary_object,%object |
| + .secondary secondary_object |
| +secondary_object: |
| + .byte 0x0 |
| + .size secondary_object,1 |
| + |
| .comm common, 1 |
| .type common,STT_COMMON |
| - |
| \ No newline at end of file |
| diff --git a/include/bfdlink.h b/include/bfdlink.h |
| index 125683d..5565050 100644 |
| --- a/include/bfdlink.h |
| +++ b/include/bfdlink.h |
| @@ -93,6 +93,9 @@ struct bfd_link_hash_entry |
| |
| unsigned int non_ir_ref : 1; |
| |
| + /* Set if it is a secondary symbol. */ |
| + unsigned int secondary : 1; |
| + |
| /* A union of information depending upon the type. */ |
| union |
| { |
| @@ -355,6 +358,9 @@ struct bfd_link_info |
| /* TRUE if .gnu.hash section should be created. */ |
| unsigned int emit_gnu_hash: 1; |
| |
| + /* TRUE if secondary symbols should be generated. */ |
| + unsigned int emit_secondary: 1; |
| + |
| /* If TRUE reduce memory overheads, at the expense of speed. This will |
| cause map file generation to use an O(N^2) algorithm and disable |
| caching ELF symbol buffer. */ |
| diff --git a/include/elf/common.h b/include/elf/common.h |
| index e8ae3ac..b1e66d4 100644 |
| --- a/include/elf/common.h |
| +++ b/include/elf/common.h |
| @@ -664,6 +664,7 @@ |
| #define STB_LOCAL 0 /* Symbol not visible outside obj */ |
| #define STB_GLOBAL 1 /* Symbol visible outside obj */ |
| #define STB_WEAK 2 /* Like globals, lower precedence */ |
| +#define STB_SECONDARY 3 /* Like weaks, lower precedence */ |
| #define STB_LOOS 10 /* OS-specific semantics */ |
| #define STB_GNU_UNIQUE 10 /* Symbol is unique in namespace */ |
| #define STB_HIOS 12 /* OS-specific semantics */ |
| diff --git a/ld/emultempl/elf32.em b/ld/emultempl/elf32.em |
| index 67c437d..d842c5d 100644 |
| --- a/ld/emultempl/elf32.em |
| +++ b/ld/emultempl/elf32.em |
| @@ -2326,6 +2326,8 @@ fragment <<EOF |
| link_info.error_textrel = FALSE; |
| else if (strcmp (optarg, "textoff") == 0) |
| link_info.error_textrel = FALSE; |
| + else if (strcmp (optarg, "nosecondary") == 0) |
| + link_info.emit_secondary = FALSE; |
| EOF |
| fi |
| |
| @@ -2453,6 +2455,8 @@ fragment <<EOF |
| -z relro Create RELRO program header\n")); |
| fprintf (file, _("\ |
| -z stacksize=SIZE Set size of stack segment\n")); |
| + fprintf (file, _("\ |
| + -z nosecondary Convert secondary symbols to weak symbols\n")); |
| EOF |
| fi |
| |
| diff --git a/ld/ld.texinfo b/ld/ld.texinfo |
| index e71be5e..30dddd4 100644 |
| --- a/ld/ld.texinfo |
| +++ b/ld/ld.texinfo |
| @@ -1121,6 +1121,10 @@ Marks the object may contain $ORIGIN. |
| @item relro |
| Create an ELF @code{PT_GNU_RELRO} segment header in the object. |
| |
| +@item nosecondary |
| +Convert secondary symbols to weak symbols when generating a shared |
| +library. |
| + |
| @item max-page-size=@var{value} |
| Set the emulation maximum page size to @var{value}. |
| |
| diff --git a/ld/ldmain.c b/ld/ldmain.c |
| index 77235d5..096ce2e 100644 |
| --- a/ld/ldmain.c |
| +++ b/ld/ldmain.c |
| @@ -279,6 +279,7 @@ main (int argc, char **argv) |
| link_info.combreloc = TRUE; |
| link_info.strip_discarded = TRUE; |
| link_info.emit_hash = TRUE; |
| + link_info.emit_secondary = TRUE; |
| link_info.callbacks = &link_callbacks; |
| link_info.input_bfds_tail = &link_info.input_bfds; |
| /* SVR4 linkers seem to set DT_INIT and DT_FINI based on magic _init |
| diff --git a/ld/testsuite/ld-elf/library1.c b/ld/testsuite/ld-elf/library1.c |
| new file mode 100644 |
| index 0000000..28e255d |
| --- /dev/null |
| +++ b/ld/testsuite/ld-elf/library1.c |
| @@ -0,0 +1,11 @@ |
| +#include <stdio.h> |
| + |
| +void |
| +bar (void) |
| +{ |
| +#ifdef SHARED |
| + printf ("library bar (SHARED)\n"); |
| +#else |
| + printf ("library bar\n"); |
| +#endif |
| +} |
| diff --git a/ld/testsuite/ld-elf/library1.out b/ld/testsuite/ld-elf/library1.out |
| new file mode 100644 |
| index 0000000..2050e74 |
| --- /dev/null |
| +++ b/ld/testsuite/ld-elf/library1.out |
| @@ -0,0 +1 @@ |
| +library bar |
| diff --git a/ld/testsuite/ld-elf/library2.c b/ld/testsuite/ld-elf/library2.c |
| new file mode 100644 |
| index 0000000..271ebd6 |
| --- /dev/null |
| +++ b/ld/testsuite/ld-elf/library2.c |
| @@ -0,0 +1,12 @@ |
| +#include <stdio.h> |
| + |
| +void |
| +__attribute__((weak)) |
| +bar (void) |
| +{ |
| +#ifdef SHARED |
| + printf ("weak library bar (SHARED)\n"); |
| +#else |
| + printf ("weak library bar\n"); |
| +#endif |
| +} |
| diff --git a/ld/testsuite/ld-elf/library2.out b/ld/testsuite/ld-elf/library2.out |
| new file mode 100644 |
| index 0000000..ddd3d10 |
| --- /dev/null |
| +++ b/ld/testsuite/ld-elf/library2.out |
| @@ -0,0 +1 @@ |
| +weak library bar |
| diff --git a/ld/testsuite/ld-elf/library3.out b/ld/testsuite/ld-elf/library3.out |
| new file mode 100644 |
| index 0000000..881856e |
| --- /dev/null |
| +++ b/ld/testsuite/ld-elf/library3.out |
| @@ -0,0 +1 @@ |
| +library bar (SHARED) |
| diff --git a/ld/testsuite/ld-elf/library4.out b/ld/testsuite/ld-elf/library4.out |
| new file mode 100644 |
| index 0000000..1ff1840 |
| --- /dev/null |
| +++ b/ld/testsuite/ld-elf/library4.out |
| @@ -0,0 +1 @@ |
| +weak library bar (SHARED) |
| diff --git a/ld/testsuite/ld-elf/library5a.c b/ld/testsuite/ld-elf/library5a.c |
| new file mode 100644 |
| index 0000000..7e44bb4 |
| --- /dev/null |
| +++ b/ld/testsuite/ld-elf/library5a.c |
| @@ -0,0 +1,16 @@ |
| +#include <stdio.h> |
| + |
| +asm (".secondary bar"); |
| +asm (".weak bar"); |
| + |
| +void |
| +bar (void) |
| +{ |
| + printf ("secondary bar\n"); |
| +} |
| + |
| +void |
| +xxx (void) |
| +{ |
| + printf ("xxx\n"); |
| +} |
| diff --git a/ld/testsuite/ld-elf/library5b.c b/ld/testsuite/ld-elf/library5b.c |
| new file mode 100644 |
| index 0000000..f44d97c |
| --- /dev/null |
| +++ b/ld/testsuite/ld-elf/library5b.c |
| @@ -0,0 +1,10 @@ |
| +#include <stdio.h> |
| + |
| +extern void bar (void); |
| + |
| +void |
| +foo (void) |
| +{ |
| + printf ("foo\n"); |
| + bar (); |
| +} |
| diff --git a/ld/testsuite/ld-elf/library6a.c b/ld/testsuite/ld-elf/library6a.c |
| new file mode 100644 |
| index 0000000..7de81b3 |
| --- /dev/null |
| +++ b/ld/testsuite/ld-elf/library6a.c |
| @@ -0,0 +1,4 @@ |
| +void |
| +bar (void) |
| +{ |
| +} |
| diff --git a/ld/testsuite/ld-elf/library6b.c b/ld/testsuite/ld-elf/library6b.c |
| new file mode 100644 |
| index 0000000..528fd89 |
| --- /dev/null |
| +++ b/ld/testsuite/ld-elf/library6b.c |
| @@ -0,0 +1,7 @@ |
| +extern void bar (void); |
| + |
| +void |
| +xxx (void) |
| +{ |
| + bar (); |
| +} |
| diff --git a/ld/testsuite/ld-elf/library6c.c b/ld/testsuite/ld-elf/library6c.c |
| new file mode 100644 |
| index 0000000..60f4b92 |
| --- /dev/null |
| +++ b/ld/testsuite/ld-elf/library6c.c |
| @@ -0,0 +1,9 @@ |
| +extern void abort (void); |
| + |
| +asm (".secondary bar"); |
| + |
| +void |
| +bar (void) |
| +{ |
| + abort (); |
| +} |
| diff --git a/ld/testsuite/ld-elf/library7a.c b/ld/testsuite/ld-elf/library7a.c |
| new file mode 100644 |
| index 0000000..10cd8bf |
| --- /dev/null |
| +++ b/ld/testsuite/ld-elf/library7a.c |
| @@ -0,0 +1 @@ |
| +int bar; |
| diff --git a/ld/testsuite/ld-elf/library7b.c b/ld/testsuite/ld-elf/library7b.c |
| new file mode 100644 |
| index 0000000..5f67848 |
| --- /dev/null |
| +++ b/ld/testsuite/ld-elf/library7b.c |
| @@ -0,0 +1,7 @@ |
| +extern int bar; |
| + |
| +int |
| +xxx (void) |
| +{ |
| + return bar; |
| +} |
| diff --git a/ld/testsuite/ld-elf/library7c.c b/ld/testsuite/ld-elf/library7c.c |
| new file mode 100644 |
| index 0000000..aa57fde |
| --- /dev/null |
| +++ b/ld/testsuite/ld-elf/library7c.c |
| @@ -0,0 +1,3 @@ |
| +asm (".secondary bar"); |
| + |
| +int bar = 3; |
| diff --git a/ld/testsuite/ld-elf/library8.map b/ld/testsuite/ld-elf/library8.map |
| new file mode 100644 |
| index 0000000..bcbb4de |
| --- /dev/null |
| +++ b/ld/testsuite/ld-elf/library8.map |
| @@ -0,0 +1,4 @@ |
| +VERS_1 { |
| + global: bar; _bar; |
| + local: *; |
| +}; |
| diff --git a/ld/testsuite/ld-elf/library8a.c b/ld/testsuite/ld-elf/library8a.c |
| new file mode 100644 |
| index 0000000..29a7508 |
| --- /dev/null |
| +++ b/ld/testsuite/ld-elf/library8a.c |
| @@ -0,0 +1,10 @@ |
| +#if 1 |
| +asm (".secondary bar"); |
| +#else |
| +asm (".weak bar"); |
| +#endif |
| + |
| +void |
| +bar (void) |
| +{ |
| +} |
| diff --git a/ld/testsuite/ld-elf/library8a.rd b/ld/testsuite/ld-elf/library8a.rd |
| new file mode 100644 |
| index 0000000..a593fbd |
| --- /dev/null |
| +++ b/ld/testsuite/ld-elf/library8a.rd |
| @@ -0,0 +1,5 @@ |
| +Symbol table '\.dynsym' contains [0-9]+ entries: |
| + +Num: +Value +Size Type +Bind +Vis +Ndx Name |
| +#... |
| + +[0-9]+: +[0-9a-f]+ +[0-9a-f]+ +FUNC +SECOND +DEFAULT +[0-9]+ +_?bar@@VERS_1 |
| +#... |
| diff --git a/ld/testsuite/ld-elf/library8b.c b/ld/testsuite/ld-elf/library8b.c |
| new file mode 100644 |
| index 0000000..7de81b3 |
| --- /dev/null |
| +++ b/ld/testsuite/ld-elf/library8b.c |
| @@ -0,0 +1,4 @@ |
| +void |
| +bar (void) |
| +{ |
| +} |
| diff --git a/ld/testsuite/ld-elf/library8b.rd b/ld/testsuite/ld-elf/library8b.rd |
| new file mode 100644 |
| index 0000000..fc18d1a |
| --- /dev/null |
| +++ b/ld/testsuite/ld-elf/library8b.rd |
| @@ -0,0 +1,5 @@ |
| +Symbol table '\.dynsym' contains [0-9]+ entries: |
| + +Num: +Value +Size Type +Bind +Vis +Ndx Name |
| +#... |
| + +[0-9]+: +[0-9a-f]+ +[0-9a-f]+ +FUNC +GLOBAL +DEFAULT +[0-9]+ +_?bar@@VERS_1 |
| +#... |
| diff --git a/ld/testsuite/ld-elf/library8c.c b/ld/testsuite/ld-elf/library8c.c |
| new file mode 100644 |
| index 0000000..dfb6a22 |
| --- /dev/null |
| +++ b/ld/testsuite/ld-elf/library8c.c |
| @@ -0,0 +1,7 @@ |
| +extern void bar (); |
| + |
| +void |
| +foo (void) |
| +{ |
| + bar (); |
| +} |
| diff --git a/ld/testsuite/ld-elf/library8c.rd b/ld/testsuite/ld-elf/library8c.rd |
| new file mode 100644 |
| index 0000000..317631f |
| --- /dev/null |
| +++ b/ld/testsuite/ld-elf/library8c.rd |
| @@ -0,0 +1,5 @@ |
| +Symbol table '\.dynsym' contains [0-9]+ entries: |
| + +Num: +Value +Size Type +Bind +Vis +Ndx Name |
| +#... |
| + +[0-9]+: +0+ +0+ +FUNC +GLOBAL +DEFAULT +UND +_?bar@@VERS_1 |
| +#... |
| diff --git a/ld/testsuite/ld-elf/secondary-foo.c b/ld/testsuite/ld-elf/secondary-foo.c |
| new file mode 100644 |
| index 0000000..8b23ec8 |
| --- /dev/null |
| +++ b/ld/testsuite/ld-elf/secondary-foo.c |
| @@ -0,0 +1,7 @@ |
| +extern void bar (void); |
| + |
| +void |
| +foo (void) |
| +{ |
| + bar (); |
| +} |
| diff --git a/ld/testsuite/ld-elf/secondary-main.c b/ld/testsuite/ld-elf/secondary-main.c |
| new file mode 100644 |
| index 0000000..f1cb6b4 |
| --- /dev/null |
| +++ b/ld/testsuite/ld-elf/secondary-main.c |
| @@ -0,0 +1,8 @@ |
| +extern void foo (void); |
| + |
| +int |
| +main (void) |
| +{ |
| + foo (); |
| + return 0; |
| +} |
| diff --git a/ld/testsuite/ld-elf/secondary.c b/ld/testsuite/ld-elf/secondary.c |
| new file mode 100644 |
| index 0000000..6d64ed7 |
| --- /dev/null |
| +++ b/ld/testsuite/ld-elf/secondary.c |
| @@ -0,0 +1,9 @@ |
| +#include <stdio.h> |
| + |
| +asm (".secondary bar"); |
| + |
| +void |
| +bar (void) |
| +{ |
| + printf ("secondary bar\n"); |
| +} |
| diff --git a/ld/testsuite/ld-elf/secondary.exp b/ld/testsuite/ld-elf/secondary.exp |
| new file mode 100644 |
| index 0000000..5143262 |
| --- /dev/null |
| +++ b/ld/testsuite/ld-elf/secondary.exp |
| @@ -0,0 +1,176 @@ |
| +# Expect script for ELF secondary symbol tests. |
| +# Copyright 2012 |
| +# Free Software Foundation, Inc. |
| +# |
| +# This file is part of the GNU Binutils. |
| +# |
| +# This program is free software; you can redistribute it and/or modify |
| +# it under the terms of the GNU General Public License as published by |
| +# the Free Software Foundation; either version 3 of the License, or |
| +# (at your option) any later version. |
| +# |
| +# This program is distributed in the hope that it will be useful, |
| +# but WITHOUT ANY WARRANTY; without even the implied warranty of |
| +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| +# GNU General Public License for more details. |
| +# |
| +# You should have received a copy of the GNU General Public License |
| +# along with this program; if not, write to the Free Software |
| +# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, |
| +# MA 02110-1301, USA. |
| +# |
| + |
| +# Exclude non-ELF targets. |
| + |
| +# The following tests require running the executable generated by ld, |
| +# or enough of a build environment to create a fully linked executable. |
| +# This is not commonly available when testing a cross-built linker. |
| +if ![isnative] { |
| + return |
| +} |
| + |
| +if ![is_elf_format] { |
| + return |
| +} |
| + |
| +# Check to see if the C compiler works |
| +if { [which $CC] == 0 } { |
| + return |
| +} |
| + |
| +set build_tests { |
| + {"Build secondary1.o" |
| + "-r -nostdlib" "" |
| + {secondary.c} {{readelf {-s} secondary.rd}} "secondary1.o"} |
| + {"Build secondary1.so" |
| + "-Wl,-z,nosecondary -shared" "-fPIC" |
| + {secondary.c} {{readelf {--dyn-syms} secondary1.rd}} "secondary1.so"} |
| + {"Build secondary2.so" |
| + "-shared" "-fPIC" |
| + {secondary.c} {{readelf {--dyn-syms} secondary2.rd}} "secondary2.so"} |
| + {"Build libfoo.so" |
| + "-shared" "-fPIC" |
| + {secondary-foo.c} {} "libfoo.so"} |
| + {"Build secondary-main with secondary.o" |
| + "tmpdir/secondary.o tmpdir/libfoo.so" "" |
| + {secondary-main.c} {{readelf {--dyn-syms} secondary1.rd}} "secondary"} |
| + {"Build library1.so" |
| + "-shared" "-fPIC -DSHARED" |
| + {library1.c} {} "library1.so"} |
| + {"Build library2.so" |
| + "-shared" "-fPIC -DSHARED" |
| + {library2.c} {} "library2.so"} |
| + {"Build library1.a" |
| + "" "" |
| + {library1.c} {} "library1.a"} |
| + {"Build library2.a" |
| + "" "" |
| + {library2.c} {} "library2.a"} |
| + {"Build secondary3a.o" |
| + "" "" |
| + {secondary3a.s} {} "secondary3a.a"} |
| + {"Build secondary3" |
| + "-nostdlib tmpdir/secondary3a.o" "" |
| + {secondary3b.s} {{readelf {-s} secondary3.rd}} "secondary3"} |
| + {"Build secondary4.so" |
| + "-nostdlib -shared tmpdir/secondary3a.o" "" |
| + {secondary4.s} {{readelf {--dyn-syms} secondary4.rd}} "secondary4.so"} |
| + {"Build library5a.a" |
| + "" "" |
| + {library5a.c} {} "library5a.a"} |
| + {"Build library5b.a" |
| + "" "" |
| + {library5b.c} {} "library5b.a"} |
| + {"Build secondary5.a" |
| + "" "" |
| + {secondary5.c} {} "secondary5.a"} |
| + {"Build library6a.a" |
| + "" "" |
| + {library6a.c} {} "library6a.a"} |
| + {"Build library6b.a" |
| + "" "" |
| + {library6b.c} {} "library6b.a"} |
| + {"Build library6c.a" |
| + "" "" |
| + {library6c.c} {} "library6c.a"} |
| + {"Build secondary6.a" |
| + "" "" |
| + {secondary6.c} {} "secondary6.a"} |
| + {"Build library7a.a" |
| + "" "" |
| + {library7a.c} {} "library7a.a"} |
| + {"Build library7b.a" |
| + "" "" |
| + {library7b.c} {} "library7b.a"} |
| + {"Build library7c.a" |
| + "" "" |
| + {library7c.c} {} "library7c.a"} |
| + {"Build secondary7.a" |
| + "" "" |
| + {secondary7.c} {} "secondary7.a"} |
| + {"Build library8a.so" |
| + "-shared -Wl,--version-script=library8.map" "-fPIC" |
| + {library8a.c} {{readelf {-s} library8a.rd}} "library8a.so"} |
| + {"Build library8b.so" |
| + "-shared -Wl,--version-script=library8.map" "-fPIC" |
| + {library8b.c} {{readelf {-s} library8b.rd}} "library8b.so"} |
| + {"Build library8c.a" |
| + "" "-fPIC" |
| + {library8c.c} {} "library8c.a"} |
| + {"Build library8c.so" |
| + "-shared -Wl,--version-script=library8.map tmpdir/library8c.o tmpdir/library8a.so tmpdir/library8b.so" |
| + "-fPIC" |
| + {dummy.c} {{readelf {-s} library8c.rd}} "library8c.so"} |
| +} |
| + |
| +run_cc_link_tests $build_tests |
| + |
| +set run_tests { |
| + {"Run secondary-main with secondary.o" |
| + "tmpdir/secondary.o tmpdir/libfoo.so" "" |
| + {secondary-main.c} "secondary1" "secondary1.out"} |
| + {"Run secondary-main with secondary1.so" |
| + "tmpdir/secondary1.so tmpdir/libfoo.so" "" |
| + {secondary-main.c} "secondary2" "secondary1.out"} |
| + {"Run secondary-main with secondary.o library1.o" |
| + "tmpdir/secondary.o tmpdir/secondary.o tmpdir/library1.o tmpdir/libfoo.so" "" |
| + {secondary-main.c} "secondary3" "library1.out"} |
| + {"Run secondary-main with library1.o secondary.o" |
| + "tmpdir/library1.o tmpdir/secondary.o tmpdir/secondary.o tmpdir/libfoo.so" "" |
| + {secondary-main.c} "secondary4" "library1.out"} |
| + {"Run secondary-main with secondary.o library2.o" |
| + "tmpdir/secondary.o tmpdir/library2.o tmpdir/libfoo.so" "" |
| + {secondary-main.c} "secondary5" "library2.out"} |
| + {"Run secondary-main with library2.o secondary.o" |
| + "tmpdir/library2.o tmpdir/secondary.o tmpdir/libfoo.so" "" |
| + {secondary-main.c} "secondary6" "library2.out"} |
| + {"Run secondary-main with secondary.o library1.so" |
| + "tmpdir/secondary.o tmpdir/library1.so tmpdir/libfoo.so" "" |
| + {secondary-main.c} "secondary7" "library3.out"} |
| + {"Run secondary-main with library1.so secondary.o" |
| + "tmpdir/library1.so tmpdir/secondary.o tmpdir/libfoo.so" "" |
| + {secondary-main.c} "secondary8" "library3.out"} |
| + {"Run secondary-main with secondary.o library2.so" |
| + "tmpdir/secondary.o tmpdir/library2.so tmpdir/libfoo.so" "" |
| + {secondary-main.c} "secondary9" "library4.out"} |
| + {"Run secondary-main with library2.so secondary.o" |
| + "tmpdir/library2.so tmpdir/secondary.o tmpdir/libfoo.so" "" |
| + {secondary-main.c} "secondary10" "library4.out"} |
| + {"Run secondary5 with library5a.a library5b.a" |
| + "tmpdir/secondary5.o tmpdir/library5a.a tmpdir/library5b.a" "" |
| + {dummy.c} "secondary5a" "secondary5.out"} |
| + {"Run secondary5 with -( library5a.a library5b.a -)" |
| + "tmpdir/secondary5.o -\\( tmpdir/library5a.a tmpdir/library5b.a -\\)" "" |
| + {dummy.c} "secondary5b" "secondary5.out"} |
| + {"Run secondary5 with -( library5a.a library5b.a -) -( library5a.a library5b.a -)" |
| + "tmpdir/secondary5.o -\\( tmpdir/library5a.a tmpdir/library5b.a -\\) -\\( tmpdir/library5a.a tmpdir/library5b.a -\\)" "" |
| + {dummy.c} "secondary5c" "secondary5.out"} |
| + {"Run secondary6 with -( library6a.a library6b.a library6c.a -)" |
| + "tmpdir/secondary6.o -\\( tmpdir/library6a.a tmpdir/library6b.a tmpdir/library6c.a -\\)" "" |
| + {dummy.c} "secondary6" "secondary6.out"} |
| + {"Run secondary7 with -( library7a.a library7b.a library7c.a -)" |
| + "tmpdir/secondary7.o -\\( tmpdir/library7a.a tmpdir/library7b.a tmpdir/library7c.a -\\)" "" |
| + {dummy.c} "secondary7" "secondary7.out"} |
| +} |
| + |
| +run_ld_link_exec_tests [] $run_tests |
| diff --git a/ld/testsuite/ld-elf/secondary.rd b/ld/testsuite/ld-elf/secondary.rd |
| new file mode 100644 |
| index 0000000..9931c04 |
| --- /dev/null |
| +++ b/ld/testsuite/ld-elf/secondary.rd |
| @@ -0,0 +1,5 @@ |
| +Symbol table '\.symtab' contains [0-9]+ entries: |
| + +Num: +Value +Size Type +Bind +Vis +Ndx Name |
| +#... |
| + +[0-9]+: +[0-9a-f]+ +[0-9a-f]+ +FUNC +SECOND +DEFAULT +[0-9]+ +_?bar |
| +#... |
| diff --git a/ld/testsuite/ld-elf/secondary1.out b/ld/testsuite/ld-elf/secondary1.out |
| new file mode 100644 |
| index 0000000..8d9378f |
| --- /dev/null |
| +++ b/ld/testsuite/ld-elf/secondary1.out |
| @@ -0,0 +1 @@ |
| +secondary bar |
| diff --git a/ld/testsuite/ld-elf/secondary1.rd b/ld/testsuite/ld-elf/secondary1.rd |
| new file mode 100644 |
| index 0000000..89d6d76 |
| --- /dev/null |
| +++ b/ld/testsuite/ld-elf/secondary1.rd |
| @@ -0,0 +1,5 @@ |
| +Symbol table '\.dynsym' contains [0-9]+ entries: |
| + +Num: +Value +Size Type +Bind +Vis +Ndx Name |
| +#... |
| + +[0-9]+: +[0-9a-f]+ +[0-9a-f]+ +FUNC +WEAK +DEFAULT +[0-9]+ +_?bar |
| +#... |
| diff --git a/ld/testsuite/ld-elf/secondary2.rd b/ld/testsuite/ld-elf/secondary2.rd |
| new file mode 100644 |
| index 0000000..ff618a0 |
| --- /dev/null |
| +++ b/ld/testsuite/ld-elf/secondary2.rd |
| @@ -0,0 +1,5 @@ |
| +Symbol table '\.dynsym' contains [0-9]+ entries: |
| + +Num: +Value +Size Type +Bind +Vis +Ndx Name |
| +#... |
| + +[0-9]+: +[0-9a-f]+ +[0-9a-f]+ +FUNC +SECOND +DEFAULT +[0-9]+ +_?bar |
| +#... |
| diff --git a/ld/testsuite/ld-elf/secondary3.rd b/ld/testsuite/ld-elf/secondary3.rd |
| new file mode 100644 |
| index 0000000..93c3469 |
| --- /dev/null |
| +++ b/ld/testsuite/ld-elf/secondary3.rd |
| @@ -0,0 +1,5 @@ |
| +Symbol table '\.symtab' contains [0-9]+ entries: |
| + +Num: +Value +Size Type +Bind +Vis +Ndx Name |
| +#... |
| + +[0-9]+: +0+ +0+ +[A-Z]+ +WEAK +DEFAULT +UND +_?foo |
| +#... |
| diff --git a/ld/testsuite/ld-elf/secondary3a.s b/ld/testsuite/ld-elf/secondary3a.s |
| new file mode 100644 |
| index 0000000..16a1300 |
| --- /dev/null |
| +++ b/ld/testsuite/ld-elf/secondary3a.s |
| @@ -0,0 +1,4 @@ |
| + .section .text,"axG",%progbits,foo_group,comdat |
| + .global bar |
| +bar: |
| + .byte 0 |
| diff --git a/ld/testsuite/ld-elf/secondary3b.s b/ld/testsuite/ld-elf/secondary3b.s |
| new file mode 100644 |
| index 0000000..cc6f37b |
| --- /dev/null |
| +++ b/ld/testsuite/ld-elf/secondary3b.s |
| @@ -0,0 +1,20 @@ |
| + .section .text,"axG",%progbits,foo_group,comdat |
| + .secondary foo |
| + .global bar |
| +foo: |
| + .byte 0 |
| +bar: |
| + .byte 0 |
| + .data |
| + .dc.a foo |
| + |
| + .text |
| + .global start /* Used by SH targets. */ |
| +start: |
| + .global _start |
| +_start: |
| + .global __start |
| +__start: |
| + .global main /* Used by HPPA targets. */ |
| +main: |
| + .dc.a bar |
| diff --git a/ld/testsuite/ld-elf/secondary4.rd b/ld/testsuite/ld-elf/secondary4.rd |
| new file mode 100644 |
| index 0000000..e84b1a6 |
| --- /dev/null |
| +++ b/ld/testsuite/ld-elf/secondary4.rd |
| @@ -0,0 +1,5 @@ |
| +Symbol table '\.dynsym' contains [0-9]+ entries: |
| + +Num: +Value +Size Type +Bind +Vis +Ndx Name |
| +#... |
| + +[0-9]+: +0+ +0+ +[A-Z]+ +WEAK +DEFAULT +UND +_?foo |
| +#... |
| diff --git a/ld/testsuite/ld-elf/secondary4.s b/ld/testsuite/ld-elf/secondary4.s |
| new file mode 100644 |
| index 0000000..a2acf21 |
| --- /dev/null |
| +++ b/ld/testsuite/ld-elf/secondary4.s |
| @@ -0,0 +1,9 @@ |
| + .section .text,"axG",%progbits,foo_group,comdat |
| + .secondary foo |
| + .global bar |
| +foo: |
| + .byte 0 |
| +bar: |
| + .byte 0 |
| + .data |
| + .dc.a foo |
| diff --git a/ld/testsuite/ld-elf/secondary5.c b/ld/testsuite/ld-elf/secondary5.c |
| new file mode 100644 |
| index 0000000..a2b2f20 |
| --- /dev/null |
| +++ b/ld/testsuite/ld-elf/secondary5.c |
| @@ -0,0 +1,10 @@ |
| +extern void foo (void); |
| +extern void xxx (void); |
| + |
| +int |
| +main (void) |
| +{ |
| + foo (); |
| + xxx (); |
| + return 0; |
| +} |
| diff --git a/ld/testsuite/ld-elf/secondary5.out b/ld/testsuite/ld-elf/secondary5.out |
| new file mode 100644 |
| index 0000000..730c35d |
| --- /dev/null |
| +++ b/ld/testsuite/ld-elf/secondary5.out |
| @@ -0,0 +1,3 @@ |
| +foo |
| +secondary bar |
| +xxx |
| diff --git a/ld/testsuite/ld-elf/secondary6.c b/ld/testsuite/ld-elf/secondary6.c |
| new file mode 100644 |
| index 0000000..2a7e17b |
| --- /dev/null |
| +++ b/ld/testsuite/ld-elf/secondary6.c |
| @@ -0,0 +1,11 @@ |
| +#include <stdio.h> |
| + |
| +extern void xxx (void); |
| + |
| +int |
| +main (void) |
| +{ |
| + xxx (); |
| + printf ("OK\n"); |
| + return 0; |
| +} |
| diff --git a/ld/testsuite/ld-elf/secondary6.out b/ld/testsuite/ld-elf/secondary6.out |
| new file mode 100644 |
| index 0000000..d86bac9 |
| --- /dev/null |
| +++ b/ld/testsuite/ld-elf/secondary6.out |
| @@ -0,0 +1 @@ |
| +OK |
| diff --git a/ld/testsuite/ld-elf/secondary7.c b/ld/testsuite/ld-elf/secondary7.c |
| new file mode 100644 |
| index 0000000..9a67352 |
| --- /dev/null |
| +++ b/ld/testsuite/ld-elf/secondary7.c |
| @@ -0,0 +1,13 @@ |
| +#include <stdio.h> |
| + |
| +extern void abort (void); |
| +extern int xxx (void); |
| + |
| +int |
| +main (void) |
| +{ |
| + if (xxx () != 0) |
| + abort (); |
| + printf ("OK\n"); |
| + return 0; |
| +} |
| diff --git a/ld/testsuite/ld-elf/secondary7.out b/ld/testsuite/ld-elf/secondary7.out |
| new file mode 100644 |
| index 0000000..d86bac9 |
| --- /dev/null |
| +++ b/ld/testsuite/ld-elf/secondary7.out |
| @@ -0,0 +1 @@ |
| +OK |
| -- |
| 1.9.3 |
| |