|| h->root.type == bfd_link_hash_undefweak))
return true;
- /* If H is currently undefined, LDSYM defines it. */
+ /* If H is currently undefined, LDSYM defines it.
+ However, if H has a hidden visibility, LDSYM must not
+ define it. */
if ((h->flags & XCOFF_DEF_DYNAMIC) == 0
&& (h->root.type == bfd_link_hash_undefined
- || h->root.type == bfd_link_hash_undefweak))
+ || h->root.type == bfd_link_hash_undefweak)
+ && (h->visibility != SYM_V_HIDDEN
+ && h->visibility != SYM_V_INTERNAL))
return true;
return false;
bfd_byte *linenos;
} *reloc_info = NULL;
bfd_size_type amt;
+ unsigned short visibility;
keep_syms = obj_coff_keep_syms (abfd);
}
}
+ /* Record visibility. */
+ visibility = sym.n_type & SYM_V_MASK;
+
/* Pick up the csect auxiliary information. */
if (sym.n_numaux == 0)
{
/* Try not to give this error too many times. */
(*sym_hash)->flags &= ~XCOFF_MULTIPLY_DEFINED;
}
+
+
+ /* If the symbol is hidden or internal, completely undo
+ any dynamic link state. */
+ if ((*sym_hash)->flags & XCOFF_DEF_DYNAMIC
+ && (visibility == SYM_V_HIDDEN
+ || visibility == SYM_V_INTERNAL))
+ (*sym_hash)->flags &= ~XCOFF_DEF_DYNAMIC;
+ else
+ {
+ /* Keep the most constraining visibility. */
+ unsigned short hvis = (*sym_hash)->visibility;
+ if (visibility && ( !hvis || visibility < hvis))
+ (*sym_hash)->visibility = visibility;
+ }
+
}
/* _bfd_generic_link_add_one_symbol may call the linker to
if (h->root.root.string[0] == '.')
return false;
+ /* Don't export hidden or internal symbols. */
+ if (h->visibility == SYM_V_HIDDEN
+ || h->visibility == SYM_V_INTERNAL)
+ return false;
+
/* We don't export a symbol which is being defined by an object
included from an archive which contains a shared object. The
rationale is that if an archive contains both an unshared and
if (bfd_get_flavour (output_bfd) != bfd_target_xcoff_flavour)
return true;
+ /* As AIX linker, symbols exported with hidden visibility are
+ silently ignored. */
+ if (h->visibility == SYM_V_HIDDEN)
+ return true;
+
+ if (h->visibility == SYM_V_INTERNAL)
+ {
+ _bfd_error_handler (_("%pB: cannot export internal symbol `%s`."),
+ output_bfd, h->root.root.string);
+ bfd_set_error (bfd_error_bad_value);
+ return false;
+ }
+
h->flags |= XCOFF_EXPORT;
/* FIXME: I'm not at all sure what syscall is supposed to mean, so
- (*csectpp)->vma);
}
+ /* Update visibility. */
+ isym.n_type &= ~SYM_V_MASK;
+ isym.n_type |= (*sym_hash)->visibility;
+
/* Output the symbol. */
bfd_coff_swap_sym_out (output_bfd, (void *) &isym, (void *) outsym);
printf ("mainvar == %d\n", mainvar);
printf ("overriddenvar == %d\n", overriddenvar);
printf ("shlibvar1 == %d\n", shlibvar1);
-#ifndef XCOFF_TEST
printf ("shlib_mainvar () == %d\n", shlib_mainvar ());
+#ifndef XCOFF_TEST
printf ("shlib_overriddenvar () == %d\n", shlib_overriddenvar ());
#endif
printf ("shlib_shlibvar1 () == %d\n", shlib_shlibvar1 ());
printf ("shlib_shlibcall () == %d\n", shlib_shlibcall ());
#ifndef XCOFF_TEST
printf ("shlib_shlibcall2 () == %d\n", shlib_shlibcall2 ());
- printf ("shlib_maincall () == %d\n", shlib_maincall ());
#endif
+ printf ("shlib_maincall () == %d\n", shlib_maincall ());
printf ("main_called () == %d\n", main_called ());
printf ("shlib_checkfunptr1 (shlib_shlibvar1) == %d\n",
shlib_checkfunptr1 (shlib_shlibvar1));
-#ifndef XCOFF_TEST
printf ("shlib_checkfunptr2 (main_called) == %d\n",
shlib_checkfunptr2 (main_called));
-#endif
p = shlib_getfunptr1 ();
printf ("shlib_getfunptr1 () ");
if (p == shlib_shlibvar1)
else
printf ("!=");
printf (" shlib_shlibvar1\n");
-#ifndef XCOFF_TEST
p = shlib_getfunptr2 ();
printf ("shlib_getfunptr2 () ");
if (p == main_called)
else
printf ("!=");
printf (" main_called\n");
-#endif
printf ("shlib_check () == %d\n", shlib_check ());
printf ("visibility_check () == %d\n", visibility_check ());
printf ("visibility_checkfunptr () == %d\n",
return
}
-# This test can only be run on a couple of ELF platforms.
+# This test can only be run on a couple of ELF platforms or with
+# XCOFF formats.
# Square bracket expressions seem to confuse istarget.
if { ![istarget hppa*64*-*-hpux*] \
&& ![istarget hppa*-*-linux*] \
&& ![istarget sparc*-*-linux*] \
&& ![istarget s390*-*-linux*] \
&& ![istarget sh\[34\]*-*-linux*] \
- && ![istarget x86_64-*-linux*] } {
+ && ![istarget x86_64-*-linux*] \
+ && ![is_xcoff_format] } {
return
}
-set test_list [lsort [glob -nocomplain $srcdir/$subdir/*-elf.d]]
+if [is_xcoff_format] {
+ set test_list [lsort [glob -nocomplain $srcdir/$subdir/*-xcoff*.d]]
+} else {
+ set test_list [lsort [glob -nocomplain $srcdir/$subdir/*-elf.d]]
+}
+
foreach t $test_list {
# We need to strip the ".d", but can leave the dirname.
verbose [file rootname $t]
set shared_needs_pic "no"
set COMPRESS_LDFLAG "-Wl,--compress-debug-sections=zlib-gabi"
+if { [is_xcoff_format] } {
+ # Not all the useful features are available with AIX shared
+ # libraries by default.
+ # We can manage to simulate some of them with export/import
+ # files but the overriding of shared library functions or
+ # variables by the main program doesn't seem possible.
+ # We avoid testing those features.
+ set SHCFLAG "-DXCOFF_TEST"
+
+ # In order to avoid listing every symbols in an export file,
+ # the export will be done with -bexpall flag.
+ # However for imports, we must create the import file.
+ set file [open $tmpdir/xcoff-shared.imp w]
+ puts $file "#! ."
+ puts $file mainvar
+ puts $file main_called
+ close $file
+
+ # XCOFF doesn't yet support debug sections compresion.
+ set COMPRESS_LDFLAG ""
+}
+
if [istarget arm*-*-linux*] {
# On ARM section anchors can change the symbol pre-emptability for
# non-PIC shared libraries, causing these tests to fail. Turn section
# Build the shared library.
set shared -shared
+ if { [is_xcoff_format] } {
+ # On AIX, setup imports and exports.
+ append shared " -Wl,-bexpall -Wl,-bI:$tmpdir/xcoff-shared.imp"
+ }
if { [is_elf_format] && [check_shared_lib_support] } {
append shared " -Wl,-z,notext"
}
# Link against the shared library. Use -rpath so that the
# dynamic linker can locate the shared library at runtime.
+ # On AIX, we must include /lib in -rpath, as otherwise the loader
+ # can not find -lc.
set rpath $tmpdir
- if ![ld_link $CC_FOR_TARGET $tmpdir/$progname "-Wl,-rpath,$rpath $tmpdir/$main $tmpdir/$progname.so"] {
+ set exportflag ""
+ if { [is_xcoff_format] } {
+ set rpath /lib:$tmpdir
+ set exportflag " -Wl,-bexpall"
+ }
+ if ![ld_link $CC_FOR_TARGET $tmpdir/$progname "-Wl,-rpath,$rpath $tmpdir/$main $tmpdir/$progname.so $exportflag"] {
if { [ string match $visibility "hidden" ]
&& [regexp "undefined reference to \`\.?visibility\'" $link_output]
&& [regexp "undefined reference to \`visibility_var\'" $link_output] } {
# tests below.
remote_file host delete $tmpdir/sh1p.o $tmpdir/sh2p.o $tmpdir/sh1np.o $tmpdir/sh2np.o
+ set datfile elfvsb
+ if { [is_xcoff_format] } {
+ # As explained above, XCOFF shared libraries doesn't support
+ # all the ELF features. Thus, the output of the tests are
+ # a bit different.
+ set datfile xcoffvsb
+ }
+
if { [istarget powerpc*-*-linux*] \
|| ( [istarget mips*-*-linux*] && [at_least_gcc_version 4 3] )} {
# Testing non-PIC libraries is a waste of effort on any target.
setup_xfail "arm*-*-linux*"
}
- visibility_test $visibility vnp "visibility ($visibility) (non PIC)" mainnp.o sh1np.o sh2np.o elfvsb
+ # XCOFF format doesn't know how to handle weak undefined symbols
+ # in shared objects.
+ if { [ string match $visibility "hidden_weak" ]
+ || [ string match $visibility "protected_weak" ] } {
+ setup_xfail "*-*-aix*"
+ setup_xfail "*-*-beos*"
+ }
+
+ visibility_test $visibility vnp "visibility ($visibility) (non PIC)" mainnp.o sh1np.o sh2np.o $datfile
# Test ELF shared library relocations with a non-zero load
# address for the library. Near as I can tell, the R_*_RELATIVE
setup_xfail "arm*-*-linux*"
}
- visibility_test $visibility vnp "visibility ($visibility) (non PIC, load offset)" \
- mainnp.o sh1np.o sh2np.o elfvsb \
- "-Wl,-T,$srcdir/$subdir/elf-offset.ld,--hash-style=sysv"
+ # XCOFF format doesn't know how to handle weak undefined symbols
+ # in shared objects.
+ if { [ string match $visibility "hidden_weak" ]
+ || [ string match $visibility "protected_weak" ] } {
+ setup_xfail "*-*-aix*"
+ setup_xfail "*-*-beos*"
+ }
+
+ if { ![is_xcoff_format] } {
+ visibility_test $visibility vnp "visibility ($visibility) (non PIC, load offset)" \
+ mainnp.o sh1np.o sh2np.o $datfile \
+ "-Wl,-T,$srcdir/$subdir/elf-offset.ld,--hash-style=sysv"
+ }
}
# Now compile the code using -fpic.
setup_xfail $target_triplet
}
}
- visibility_test $visibility vp "visibility ($visibility)" mainnp.o sh1p.o sh2p.o elfvsb $COMPRESS_LDFLAG
+ visibility_test $visibility vp "visibility ($visibility)" mainnp.o sh1p.o sh2p.o $datfile $COMPRESS_LDFLAG
}
}}
setup_xfail "arm*-*-linux*"
}
- visibility_test $visibility vmpnp "visibility ($visibility) (PIC main, non PIC so)" mainp.o sh1np.o sh2np.o elfvsb
+ # XCOFF format doesn't know how to handle weak undefined symbols
+ # in shared objects.
+ if { [ string match $visibility "hidden_weak" ]
+ || [ string match $visibility "protected_weak" ] } {
+ setup_xfail "*-*-aix*"
+ setup_xfail "*-*-beos*"
+ }
+
+ visibility_test $visibility vmpnp "visibility ($visibility) (PIC main, non PIC so)" mainp.o sh1np.o sh2np.o $datfile
} else {
unsupported "visibility (PIC main, non PIC so)"
}
setup_xfail $target_triplet
}
}
- visibility_test $visibility vmpp "visibility ($visibility) (PIC main)" mainp.o sh1p.o sh2p.o elfvsb
+
+ # XCOFF format doesn't know how to handle weak undefined symbols
+ # in shared objects.
+ if { [ string match $visibility "hidden_weak" ]
+ || [ string match $visibility "protected_weak" ] } {
+ setup_xfail "*-*-aix*"
+ setup_xfail "*-*-beos*"
+ }
+
+ visibility_test $visibility vmpp "visibility ($visibility) (PIC main)" mainp.o sh1p.o sh2p.o $datfile
} else {
unsupported "visibility ($visibility) (PIC main)"
}
if { ![ld_compile "$CC_FOR_TARGET -g $NOSANITIZE_CFLAGS $NOLTO_CFLAGS -DSHARED $picflag" $srcdir/$subdir/sh3.c tmpdir/sh3.o] } {
unsupported "weak hidden symbol"
} else {
- if ![ld_link $ld tmpdir/sh3.so "-shared tmpdir/sh3.o"] {
+ set shared "-shared"
+ if { [is_xcoff_format] } {
+ # On AIX, setup imports and exports.
+ append shared " -bexpall"
+ }
+ if ![ld_link $ld tmpdir/sh3.so "$shared tmpdir/sh3.o"] {
fail "weak hidden symbol"
} else {
if ![ld_link $ld tmpdir/weak "tmpdir/test.o tmpdir/sh3.so"] {