summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Jacobowitz <drow@false.org>2004-10-16 18:13:54 +0000
committerDaniel Jacobowitz <drow@false.org>2004-10-16 18:13:54 +0000
commitb58f81aef6a84930bcb58db39f2bad0c45383a6d (patch)
tree3898cd356f0d9f0d894b447a4fdb46915a7bfac0
parentfd5008162e2dc522e4fea16de38a355f7e1a43be (diff)
downloadbinutils-gdb-b58f81aef6a84930bcb58db39f2bad0c45383a6d.tar.gz
bfd/
* 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.
-rw-r--r--bfd/ChangeLog6
-rw-r--r--bfd/bfd-in2.h3
-rw-r--r--bfd/bfd.c3
-rw-r--r--bfd/elflink.c8
-rw-r--r--ld/ChangeLog12
-rw-r--r--ld/emultempl/elf32.em8
-rw-r--r--ld/ld.texinfo20
-rw-r--r--ld/ldlang.c63
-rw-r--r--ld/ldlang.h2
-rw-r--r--ld/testsuite/ChangeLog4
-rw-r--r--ld/testsuite/ld-elf/exclude.exp137
-rw-r--r--ld/testsuite/ld-elf/exclude1.s3
-rw-r--r--ld/testsuite/ld-elf/exclude2.s3
13 files changed, 262 insertions, 10 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 2b1905a0d13..888c9202555 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -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.
diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h
index 2e137043d6b..a25bef34f61 100644
--- a/bfd/bfd-in2.h
+++ b/bfd/bfd-in2.h
@@ -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. */
diff --git a/bfd/bfd.c b/bfd/bfd.c
index 8ebc81a9953..0126a9f3e3a 100644
--- 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. *}
diff --git a/bfd/elflink.c b/bfd/elflink.c
index 75b8c9699b6..68435bb2338 100644
--- a/bfd/elflink.c
+++ b/bfd/elflink.c
@@ -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;
diff --git a/ld/ChangeLog b/ld/ChangeLog
index c8541d56668..26d47e70e6e 100644
--- a/ld/ChangeLog
+++ b/ld/ChangeLog
@@ -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
diff --git a/ld/emultempl/elf32.em b/ld/emultempl/elf32.em
index f9e2cf96255..c6bc7c2ea4e 100644
--- a/ld/emultempl/elf32.em
+++ b/ld/emultempl/elf32.em
@@ -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;
diff --git a/ld/ld.texinfo b/ld/ld.texinfo
index bfd346478cc..5a494c236f5 100644
--- a/ld/ld.texinfo
+++ b/ld/ld.texinfo
@@ -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
diff --git a/ld/ldlang.c b/ld/ldlang.c
index fee5950b6f1..4cc5927609f 100644
--- a/ld/ldlang.c
+++ b/ld/ldlang.c
@@ -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;
diff --git a/ld/ldlang.h b/ld/ldlang.h
index 9b0f9eff181..d6b9a797f8e 100644
--- a/ld/ldlang.h
+++ b/ld/ldlang.h
@@ -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
diff --git a/ld/testsuite/ChangeLog b/ld/testsuite/ChangeLog
index 03ba805642e..dfe0e7a5d26 100644
--- a/ld/testsuite/ChangeLog
+++ b/ld/testsuite/ChangeLog
@@ -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
index 00000000000..ffe6b028e7e
--- /dev/null
+++ b/ld/testsuite/ld-elf/exclude.exp
@@ -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
index 00000000000..45583a35fdf
--- /dev/null
+++ b/ld/testsuite/ld-elf/exclude1.s
@@ -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
index 00000000000..401aa22a522
--- /dev/null
+++ b/ld/testsuite/ld-elf/exclude2.s
@@ -0,0 +1,3 @@
+ .globl exclude_sym
+exclude_sym:
+ .long 0