bfd/
authorDaniel Jacobowitz <drow@false.org>
Sat, 16 Oct 2004 18:13:54 +0000 (18:13 +0000)
committerDaniel Jacobowitz <drow@false.org>
Sat, 16 Oct 2004 18:13:54 +0000 (18:13 +0000)
* bfd-in2.h: Regenerate.
* bfd.c (struct bfd): Add no_export.
* elflink.c (elf_link_add_object_symbols): Handle no_export.
ld/
* ldlang.c (struct excluded_lib, excluded_libs, add_excluded_libs)
(check_excluded_libs): New.
(load_symbols): Call check_excluded_libs.
* ldlang.h (add_excluded_libs): New prototype.
* emultempl/elf32.em (OPTION_EXCLUDED_LIBS): Define.
(gld${EMULATION_NAME}_add_options): Add --exclude-libs.
(gld${EMULATION_NAME}_handle_option): Handle --exclude-libs.
* ld.texinfo (Command Line Variables): Document --exclude-libs.
(Options Specific to i386 PE Targets): Remove --exclude-libs.
ld/testsuite/
* ld-elf/exclude1.s, ld-elf/exclude2.s, ld-elf/exclude.exp: New.

13 files changed:
bfd/ChangeLog
bfd/bfd-in2.h
bfd/bfd.c
bfd/elflink.c
ld/ChangeLog
ld/emultempl/elf32.em
ld/ld.texinfo
ld/ldlang.c
ld/ldlang.h
ld/testsuite/ChangeLog
ld/testsuite/ld-elf/exclude.exp [new file with mode: 0644]
ld/testsuite/ld-elf/exclude1.s [new file with mode: 0644]
ld/testsuite/ld-elf/exclude2.s [new file with mode: 0644]

index 2b1905a0d137284c56af6eb4a9eb29809b5fa536..888c92025554bb4fdc4193f53a6e0c141a0fb6d4 100644 (file)
@@ -1,3 +1,9 @@
+2004-10-16  Daniel Jacobowitz  <dan@debian.org>
+
+       * bfd-in2.h: Regenerate.
+       * bfd.c (struct bfd): Add no_export.
+       * elflink.c (elf_link_add_object_symbols): Handle no_export.
+
 2004-10-15  Alan Modra  <amodra@bigpond.net.au>
 
        * config.bfd: Whitespace cleanup.
index 2e137043d6bcf077264a7416157f913708eb0aed..a25bef34f61706a589e104828c693819dce6ef39 100644 (file)
@@ -3962,6 +3962,9 @@ struct bfd
   /* Pointer to structure which contains architecture information.  */
   const struct bfd_arch_info *arch_info;
 
+  /* Flag set if symbols from this BFD should not be exported.  */
+  bfd_boolean no_export;
+
   /* Stuff only useful for archives.  */
   void *arelt_data;
   struct bfd *my_archive;      /* The containing archive BFD.  */
index 8ebc81a9953d33f30d24fdeede90874eeb04167f..0126a9f3e3abf6ff51dae827c14e4e9d8879239f 100644 (file)
--- a/bfd/bfd.c
+++ b/bfd/bfd.c
@@ -133,6 +133,9 @@ CODE_FRAGMENT
 .  {* Pointer to structure which contains architecture information.  *}
 .  const struct bfd_arch_info *arch_info;
 .
+.  {* Flag set if symbols from this BFD should not be exported.  *}
+.  bfd_boolean no_export;
+.
 .  {* Stuff only useful for archives.  *}
 .  void *arelt_data;
 .  struct bfd *my_archive;      {* The containing archive BFD.  *}
index 75b8c9699b6501719aa5679395df36927a76776a..68435bb23382acc268527dc201a3d48fae25ff27 100644 (file)
@@ -3778,6 +3778,14 @@ elf_link_add_object_symbols (bfd *abfd, struct bfd_link_info *info)
            (*bed->elf_backend_merge_symbol_attribute) (h, isym, definition,
                                                        dynamic);
 
+         /* If this symbol has default visibility and the user has requested
+            we not re-export it, then mark it as hidden.  */
+         if (definition && !dynamic
+             && (abfd->no_export
+                 || (abfd->my_archive && abfd->my_archive->no_export))
+             && ELF_ST_VISIBILITY (isym->st_other) != STV_INTERNAL)
+           isym->st_other = STV_HIDDEN | (isym->st_other & ~ ELF_ST_VISIBILITY (-1));
+
          if (isym->st_other != 0 && !dynamic)
            {
              unsigned char hvis, symvis, other, nvis;
index c8541d56668600d0512d724de6921ef916be29ab..26d47e70e6edb983ba3fad8ce34194bb48fbaeea 100644 (file)
@@ -1,3 +1,15 @@
+2004-10-16  Daniel Jacobowitz  <dan@debian.org>
+
+       * ldlang.c (struct excluded_lib, excluded_libs, add_excluded_libs)
+       (check_excluded_libs): New.
+       (load_symbols): Call check_excluded_libs.
+       * ldlang.h (add_excluded_libs): New prototype.
+       * emultempl/elf32.em (OPTION_EXCLUDED_LIBS): Define.
+       (gld${EMULATION_NAME}_add_options): Add --exclude-libs.
+       (gld${EMULATION_NAME}_handle_option): Handle --exclude-libs.
+       * ld.texinfo (Command Line Variables): Document --exclude-libs.
+       (Options Specific to i386 PE Targets): Remove --exclude-libs.
+
 2004-10-15  Alan Modra  <amodra@bigpond.net.au>
 
        * ldexp.c (exp_fold_tree): Don't immediately exit ld on a
index f9e2cf962553715c4c6c09afeaf9b9d448fe3a13..c6bc7c2ea4edbe68572f0d7d90dc8da38ec00464 100644 (file)
@@ -1571,7 +1571,8 @@ cat >>e${EMULATION_NAME}.c <<EOF
 #define OPTION_ENABLE_NEW_DTAGS                (OPTION_DISABLE_NEW_DTAGS + 1)
 #define OPTION_GROUP                   (OPTION_ENABLE_NEW_DTAGS + 1)
 #define OPTION_EH_FRAME_HDR            (OPTION_GROUP + 1)
-
+#define OPTION_EXCLUDE_LIBS            (OPTION_EH_FRAME_HDR + 1)
+  
 static void
 gld${EMULATION_NAME}_add_options
   (int ns, char **shortopts, int nl, struct option **longopts,
@@ -1586,6 +1587,7 @@ cat >>e${EMULATION_NAME}.c <<EOF
     {"disable-new-dtags", no_argument, NULL, OPTION_DISABLE_NEW_DTAGS},
     {"enable-new-dtags", no_argument, NULL, OPTION_ENABLE_NEW_DTAGS},
     {"eh-frame-hdr", no_argument, NULL, OPTION_EH_FRAME_HDR},
+    {"exclude-libs", required_argument, NULL, OPTION_EXCLUDE_LIBS},
     {"Bgroup", no_argument, NULL, OPTION_GROUP},
 EOF
 fi
@@ -1638,6 +1640,10 @@ cat >>e${EMULATION_NAME}.c <<EOF
       link_info.unresolved_syms_in_shared_libs = RM_GENERATE_ERROR;
       break;
 
+    case OPTION_EXCLUDE_LIBS:
+      add_excluded_libs (optarg);
+      break;
+
     case 'z':
       if (strcmp (optarg, "initfirst") == 0)
        link_info.flags_1 |= (bfd_vma) DF_1_INITFIRST;
index bfd346478cc5d1d64be5fcce34df226db1b99203..5a494c236f5a688ca1450abd9b6b1c609665c8b4 100644 (file)
@@ -449,6 +449,17 @@ base 10; you may use a leading @samp{0x} for base 16, or a leading
 @samp{0} for base 8).  @xref{Entry Point}, for a discussion of defaults
 and other ways of specifying the entry point.
 
+@kindex --exclude-libs
+@item --exclude-libs @var{lib},@var{lib},...
+Specifies a list of archive libraries from which symbols should not be automatically
+exported. The library names may be delimited by commas or colons.  Specifying
+@code{--exclude-libs ALL} excludes symbols in all archive libraries from
+automatic export.  This option is available only for the i386 PE targeted
+port of the linker and for ELF targeted ports.  For i386 PE, symbols
+explicitly listed in a .def file are still exported, regardless of this
+option.  For ELF targeted ports, symbols affected by this option will
+be treated as hidden.
+
 @cindex dynamic symbol table
 @kindex -E
 @kindex --export-dynamic
@@ -1884,15 +1895,6 @@ Specifies a list of symbols which should not be automatically
 exported.  The symbol names may be delimited by commas or colons.
 [This option is specific to the i386 PE targeted port of the linker]
 
-@kindex --exclude-libs
-@item --exclude-libs @var{lib},@var{lib},...
-Specifies a list of archive libraries from which symbols should not be automatically
-exported. The library names may be delimited by commas or colons.  Specifying
-@code{--exclude-libs ALL} excludes symbols in all archive libraries from
-automatic export. Symbols explicitly listed in a .def file are still exported,
-regardless of this option. 
-[This option is specific to the i386 PE targeted port of the linker]
-
 @kindex --file-alignment
 @item --file-alignment
 Specify the file alignment.  Sections in the file will always begin at
index fee5950b6f17a8995e8e8337f3dfc92bbe8a5645..4cc5927609f2adc3785a49a10af05c77ca44d96b 100644 (file)
@@ -1692,6 +1692,67 @@ lookup_name (const char *name)
   return search;
 }
 
+/* Save LIST as a list of libraries whose symbols should not be exported.  */
+
+struct excluded_lib
+{
+  char *name;
+  struct excluded_lib *next;
+};
+static struct excluded_lib *excluded_libs;
+
+void
+add_excluded_libs (const char *list)
+{
+  const char *p = list, *end;
+
+  while (*p != '\0')
+    {
+      struct excluded_lib *entry;
+      end = strpbrk (p, ",:");
+      if (end == NULL)
+       end = p + strlen (p);
+      entry = xmalloc (sizeof (*entry));
+      entry->next = excluded_libs;
+      entry->name = xmalloc (end - p + 1);
+      memcpy (entry->name, p, end - p);
+      entry->name[end - p] = '\0';
+      excluded_libs = entry;
+      if (*end == '\0')
+        break;
+      p = end + 1;
+    }
+}
+
+static void
+check_excluded_libs (bfd *abfd)
+{
+  struct excluded_lib *lib = excluded_libs;
+
+  while (lib)
+    {
+      int len = strlen (lib->name);
+      const char *filename = lbasename (abfd->filename);
+
+      if (strcmp (lib->name, "ALL") == 0)
+       {
+         abfd->no_export = TRUE;
+         return;
+       }
+
+      if (strncmp (lib->name, filename, len) == 0
+         && (filename[len] == '\0'
+             || (filename[len] == '.' && filename[len + 1] == 'a'
+                 && filename[len + 2] == '\0')))
+       {
+         abfd->no_export = TRUE;
+         return;
+       }
+
+      lib = lib->next;
+    }
+}
+
 /* Get the symbols for an input file.  */
 
 static bfd_boolean
@@ -1776,6 +1837,8 @@ load_symbols (lang_input_statement_type *entry,
       break;
 
     case bfd_archive:
+      check_excluded_libs (entry->the_bfd);
+
       if (entry->whole_archive)
        {
          bfd *member = NULL;
index 9b0f9eff18181d7b1170ee79660925a5fb2c8e26..d6b9a797f8ef61a7a6b24d8226cf068f5cd10d39 100644 (file)
@@ -589,4 +589,6 @@ extern int lang_symbol_definition_iteration (const char *);
 extern void lang_update_definedness
   (const char *, struct bfd_link_hash_entry *);
 
+extern void add_excluded_libs (const char *);
+
 #endif
index 03ba805642e801bbce7c42809cfe219e1b791b26..dfe0e7a5d267512571d5375a422105a065544920 100644 (file)
@@ -1,3 +1,7 @@
+2004-10-16  Daniel Jacobowitz  <dan@debian.org>
+
+       * ld-elf/exclude1.s, ld-elf/exclude2.s, ld-elf/exclude.exp: New.
+
 2004-10-15  Alan Modra  <amodra@bigpond.net.au>
 
        * ld-crx/reloc-num8.d: Adjust for changed orphan placement.
diff --git a/ld/testsuite/ld-elf/exclude.exp b/ld/testsuite/ld-elf/exclude.exp
new file mode 100644 (file)
index 0000000..ffe6b02
--- /dev/null
@@ -0,0 +1,137 @@
+# Expect script for --exclude-libs tests
+#   Copyright 2004 Free Software Foundation, Inc.
+#
+# This file 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 2 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+# Make sure that ld can hide symbols from libraries when building a shared
+# library.
+
+# This test can only be run on ELF platforms.
+if ![is_elf_format] {
+    return
+}
+
+# No shared lib support on this target.
+if { [istarget "mcore-*-*"] } {
+    return
+}
+
+global ar
+global as
+global ld
+global nm
+global nm_output
+
+set test1 "ld link shared library"
+set test2 "ld export symbols from archive"
+set test3 "ld link shared library with --exclude-libs"
+set test4 "ld exclude symbols from archive - --exclude-libs libexclude"
+set test5 "ld exclude symbols from archive - --exclude-libs libexclude.a"
+set test6 "ld exclude symbols from archive - --exclude-libs ALL"
+set test7 "ld exclude symbols from archive - --exclude-libs foo:libexclude.a"
+set test8 "ld exclude symbols from archive - --exclude-libs foo,libexclude.a"
+set test9 "ld don't exclude symbols from archive - --exclude-libs foo:bar"
+
+if { ![ld_assemble $as $srcdir/$subdir/exclude1.s tmpdir/exclude1.o ]
+     || ![ld_assemble $as $srcdir/$subdir/exclude2.s tmpdir/exclude2.o] } {
+    unresolved $test1
+    return
+}
+
+catch "exec rm -f tmpdir/libexclude.a" catch_output
+catch "exec $ar cq tmpdir/libexclude.a tmpdir/exclude2.o" catch_output
+if {![string match "" $catch_output]} {
+    unresolved $test1
+    return
+}
+
+# Test that the symbol is normally exported.
+
+if { [ld_simple_link $ld tmpdir/exclude.so "--shared tmpdir/exclude1.o -Ltmpdir -lexclude"] } {
+    pass $test1
+} else {
+    if [string match "*shared not supported*" $link_output] {
+       unsupported "$test1 - -shared is not supported by this target"
+    } else {
+       fail $test1
+    }
+    return
+}
+
+if ![ld_nm $nm "-D" tmpdir/exclude.so] {
+    unresolved $test2
+} elseif { [info exists nm_output(exclude_sym)] } {
+    pass $test2
+} else {
+    fail $test2
+}
+
+# Test --exclude-libs libexclude
+
+if { [ld_simple_link $ld tmpdir/exclude.so "--exclude-libs libexclude --shared tmpdir/exclude1.o -Ltmpdir -lexclude"] } {
+    pass $test3
+} else {
+    fail $test3
+}
+
+if ![ld_nm $nm "-D" tmpdir/exclude.so] {
+    unresolved $test4
+} elseif { ! [info exists nm_output(exclude_sym)] } {
+    pass $test4
+} else {
+    fail $test4
+}
+
+# Test alternate spellings of --exclude-libs
+
+if { [ld_simple_link $ld tmpdir/exclude.so "--exclude-libs libexclude.a --shared tmpdir/exclude1.o -Ltmpdir -lexclude"]
+     && [ld_nm $nm "-D" tmpdir/exclude.so]
+     && ! [info exists nm_output(exclude_sym)] } {
+    pass $test5
+} else {
+    fail $test5
+}
+
+if { [ld_simple_link $ld tmpdir/exclude.so "--exclude-libs ALL --shared tmpdir/exclude1.o -Ltmpdir -lexclude"]
+     && [ld_nm $nm "-D" tmpdir/exclude.so]
+     && ! [info exists nm_output(exclude_sym)] } {
+    pass $test6
+} else {
+    fail $test6
+}
+
+if { [ld_simple_link $ld tmpdir/exclude.so "--exclude-libs foo:libexclude.a --shared tmpdir/exclude1.o -Ltmpdir -lexclude"]
+     && [ld_nm $nm "-D" tmpdir/exclude.so]
+     && ! [info exists nm_output(exclude_sym)] } {
+    pass $test7
+} else {
+    fail $test7
+}
+
+if { [ld_simple_link $ld tmpdir/exclude.so "--exclude-libs foo,libexclude.a --shared tmpdir/exclude1.o -Ltmpdir -lexclude"]
+     && [ld_nm $nm "-D" tmpdir/exclude.so]
+     && ! [info exists nm_output(exclude_sym)] } {
+    pass $test8
+} else {
+    fail $test8
+}
+
+if { [ld_simple_link $ld tmpdir/exclude.so "--exclude-libs foo:bar --shared tmpdir/exclude1.o -Ltmpdir -lexclude"]
+     && [ld_nm $nm "-D" tmpdir/exclude.so]
+     && [info exists nm_output(exclude_sym)] } {
+    pass $test9
+} else {
+    fail $test9
+}
diff --git a/ld/testsuite/ld-elf/exclude1.s b/ld/testsuite/ld-elf/exclude1.s
new file mode 100644 (file)
index 0000000..45583a3
--- /dev/null
@@ -0,0 +1,3 @@
+       .globl include_sym
+include_sym:
+       .long   exclude_sym - include_sym
diff --git a/ld/testsuite/ld-elf/exclude2.s b/ld/testsuite/ld-elf/exclude2.s
new file mode 100644 (file)
index 0000000..401aa22
--- /dev/null
@@ -0,0 +1,3 @@
+       .globl exclude_sym
+exclude_sym:
+       .long   0