aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorClément Chigot <clement.chigot@atos.net>2021-11-23 15:45:28 +0100
committerClément Chigot <clement.chigot@atos.net>2022-01-12 09:08:25 +0100
commita8bc481f352d61bb2962e983a1c1c1fdad0230b7 (patch)
tree0571c01cecab210414116d89f49e005de17a0404
parent59e31fd742a53e8404039e1c4be4ba192672287c (diff)
downloadgdb-a8bc481f352d61bb2962e983a1c1c1fdad0230b7.zip
gdb-a8bc481f352d61bb2962e983a1c1c1fdad0230b7.tar.gz
gdb-a8bc481f352d61bb2962e983a1c1c1fdad0230b7.tar.bz2
ld: add hidden and internal visibility support for XCOFF
This patch adds a primary support for hidden and internal visibility in GNU linker for XCOFF format. The protected visibility isn't yet supported. PR 22085 bfd/ChangeLog: * xcofflink.c (xcoff_dynamic_definition_p): Add hidden and internal visibility support. (xcoff_link_add_symbols): Likewise. (xcoff_auto_export_p): Likewise. (bfd_xcoff_export_symbol): Likewise. (xcoff_link_input_bfd): Likewise. ld/ChangeLog: * testsuite/ld-vsb/main.c: Adapt for XCOFF. * testsuite/ld-vsb/sh1.c: Likewse. * testsuite/ld-vsb/vsb.exp: Likewise. * testsuite/ld-vsb/visibility-1-xcoff-32.d: New test. * testsuite/ld-vsb/visibility-1-xcoff-64.d: New test. * testsuite/ld-vsb/visibility-2-xcoff-32.d: New test. * testsuite/ld-vsb/visibility-2-xcoff-64.d: New test. * testsuite/ld-vsb/xcoffvsb.dat: New test.
-rw-r--r--bfd/xcofflink.c50
-rw-r--r--ld/testsuite/ld-vsb/define.s6
-rw-r--r--ld/testsuite/ld-vsb/main.c8
-rw-r--r--ld/testsuite/ld-vsb/sh1.c10
-rw-r--r--ld/testsuite/ld-vsb/visibility-1-xcoff-32.d21
-rw-r--r--ld/testsuite/ld-vsb/visibility-1-xcoff-64.d21
-rw-r--r--ld/testsuite/ld-vsb/visibility-2-xcoff-32.d16
-rw-r--r--ld/testsuite/ld-vsb/visibility-2-xcoff-64.d16
-rw-r--r--ld/testsuite/ld-vsb/vsb.exp112
-rw-r--r--ld/testsuite/ld-vsb/xcoffvsb.dat24
10 files changed, 254 insertions, 30 deletions
diff --git a/bfd/xcofflink.c b/bfd/xcofflink.c
index ba07ba7..6e99472 100644
--- a/bfd/xcofflink.c
+++ b/bfd/xcofflink.c
@@ -798,10 +798,14 @@ xcoff_dynamic_definition_p (struct xcoff_link_hash_entry *h,
|| 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;
@@ -1243,6 +1247,7 @@ xcoff_link_add_symbols (bfd *abfd, struct bfd_link_info *info)
bfd_byte *linenos;
} *reloc_info = NULL;
bfd_size_type amt;
+ unsigned short visibility;
keep_syms = obj_coff_keep_syms (abfd);
@@ -1480,6 +1485,9 @@ xcoff_link_add_symbols (bfd *abfd, struct bfd_link_info *info)
}
}
+ /* Record visibility. */
+ visibility = sym.n_type & SYM_V_MASK;
+
/* Pick up the csect auxiliary information. */
if (sym.n_numaux == 0)
{
@@ -2058,6 +2066,22 @@ xcoff_link_add_symbols (bfd *abfd, struct bfd_link_info *info)
/* 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
@@ -2650,6 +2674,11 @@ xcoff_auto_export_p (struct bfd_link_info *info,
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
@@ -3248,6 +3277,19 @@ bfd_xcoff_export_symbol (bfd *output_bfd,
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
@@ -4572,6 +4614,10 @@ xcoff_link_input_bfd (struct xcoff_final_link_info *flinfo,
- (*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);
diff --git a/ld/testsuite/ld-vsb/define.s b/ld/testsuite/ld-vsb/define.s
index b38e3e0..3dc25ed 100644
--- a/ld/testsuite/ld-vsb/define.s
+++ b/ld/testsuite/ld-vsb/define.s
@@ -1,10 +1,16 @@
.data
.globl protected
+ .ifndef XCOFF_TEST
.type protected,"object"
+ .endif
protected:
.globl hidden
+ .ifndef XCOFF_TEST
.type hidden,"object"
+ .endif
hidden:
.globl internal
+ .ifndef XCOFF_TEST
.type internal,"object"
+ .endif
internal:
diff --git a/ld/testsuite/ld-vsb/main.c b/ld/testsuite/ld-vsb/main.c
index c2c9291..b0359c0 100644
--- a/ld/testsuite/ld-vsb/main.c
+++ b/ld/testsuite/ld-vsb/main.c
@@ -236,8 +236,8 @@ main (void)
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 ());
@@ -245,15 +245,13 @@ main (void)
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)
@@ -261,7 +259,6 @@ main (void)
else
printf ("!=");
printf (" shlib_shlibvar1\n");
-#ifndef XCOFF_TEST
p = shlib_getfunptr2 ();
printf ("shlib_getfunptr2 () ");
if (p == main_called)
@@ -269,7 +266,6 @@ main (void)
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",
diff --git a/ld/testsuite/ld-vsb/sh1.c b/ld/testsuite/ld-vsb/sh1.c
index 1aba63c..193eca2 100644
--- a/ld/testsuite/ld-vsb/sh1.c
+++ b/ld/testsuite/ld-vsb/sh1.c
@@ -6,9 +6,7 @@
of a shared library. */
/* This variable is supplied by the main program. */
-#ifndef XCOFF_TEST
extern int mainvar;
-#endif
/* This variable is defined in the shared library, and overridden by
the main program. */
@@ -33,13 +31,11 @@ extern int shlibvar2;
/* These functions return the values of the above variables as seen in
the shared library. */
-#ifndef XCOFF_TEST
int
shlib_mainvar ()
{
return mainvar;
}
-#endif
#ifndef XCOFF_TEST
int
@@ -95,7 +91,6 @@ shlib_overriddencall2 ()
/* This function calls a function defined by the main program. */
-#ifndef XCOFF_TEST
extern int main_called ();
int
@@ -103,7 +98,6 @@ shlib_maincall ()
{
return main_called ();
}
-#endif
/* This function is passed a function pointer to shlib_mainvar. It
confirms that the pointer compares equally. */
@@ -118,14 +112,12 @@ shlib_checkfunptr1 (p)
/* This function is passed a function pointer to main_called. It
confirms that the pointer compares equally. */
-#ifndef XCOFF_TEST
int
shlib_checkfunptr2 (p)
int (*p) ();
{
return p == main_called;
}
-#endif
/* This function returns a pointer to shlib_mainvar. */
@@ -137,13 +129,11 @@ int
/* This function returns a pointer to main_called. */
-#ifndef XCOFF_TEST
int
(*shlib_getfunptr2 ()) ()
{
return main_called;
}
-#endif
/* This function makes sure that constant data and local functions
work. */
diff --git a/ld/testsuite/ld-vsb/visibility-1-xcoff-32.d b/ld/testsuite/ld-vsb/visibility-1-xcoff-32.d
new file mode 100644
index 0000000..19cff64
--- /dev/null
+++ b/ld/testsuite/ld-vsb/visibility-1-xcoff-32.d
@@ -0,0 +1,21 @@
+#source: define.s
+#source: undef.s
+#as: -a32 --defsym XCOFF_TEST=1
+#ld: -b32 -r
+#objdump: -t
+
+.*
+
+SYMBOL TABLE:
+.*
+.*
+.*
+.*
+\[ 4\]\(sec 2\).*\(ty 3000\).*protected
+.*
+\[ 6\]\(sec 2\).*\(ty 2000\).*hidden
+.*
+\[ 8\]\(sec 2\).*\(ty 1000\).*internal
+.*
+.*
+.*
diff --git a/ld/testsuite/ld-vsb/visibility-1-xcoff-64.d b/ld/testsuite/ld-vsb/visibility-1-xcoff-64.d
new file mode 100644
index 0000000..a63dcf0
--- /dev/null
+++ b/ld/testsuite/ld-vsb/visibility-1-xcoff-64.d
@@ -0,0 +1,21 @@
+#source: define.s
+#source: undef.s
+#as: -a64 --defsym XCOFF_TEST=1
+#ld: -b64 -r
+#objdump: -t
+
+.*
+
+SYMBOL TABLE:
+.*
+.*
+.*
+.*
+\[ 4\]\(sec 2\).*\(ty 3000\).*protected
+.*
+\[ 6\]\(sec 2\).*\(ty 2000\).*hidden
+.*
+\[ 8\]\(sec 2\).*\(ty 1000\).*internal
+.*
+.*
+.*
diff --git a/ld/testsuite/ld-vsb/visibility-2-xcoff-32.d b/ld/testsuite/ld-vsb/visibility-2-xcoff-32.d
new file mode 100644
index 0000000..54beedd
--- /dev/null
+++ b/ld/testsuite/ld-vsb/visibility-2-xcoff-32.d
@@ -0,0 +1,16 @@
+#source: undef.s
+#as: -a32 --defsym XCOFF_TEST=1
+#ld: -b32 -r
+#objdump: -t
+
+.*
+
+SYMBOL TABLE:
+.*
+.*
+\[ 2\]\(sec 0\).*\(ty 3000\).*protected
+.*
+\[ 4\]\(sec 0\).*\(ty 2000\).*hidden
+.*
+\[ 6\]\(sec 0\).*\(ty 1000\).*internal
+.*
diff --git a/ld/testsuite/ld-vsb/visibility-2-xcoff-64.d b/ld/testsuite/ld-vsb/visibility-2-xcoff-64.d
new file mode 100644
index 0000000..b607a53
--- /dev/null
+++ b/ld/testsuite/ld-vsb/visibility-2-xcoff-64.d
@@ -0,0 +1,16 @@
+#source: undef.s
+#as: -a64 --defsym XCOFF_TEST=1
+#ld: -b64 -r
+#objdump: -t
+
+.*
+
+SYMBOL TABLE:
+.*
+.*
+\[ 2\]\(sec 0\).*\(ty 3000\).*protected
+.*
+\[ 4\]\(sec 0\).*\(ty 2000\).*hidden
+.*
+\[ 6\]\(sec 0\).*\(ty 1000\).*internal
+.*
diff --git a/ld/testsuite/ld-vsb/vsb.exp b/ld/testsuite/ld-vsb/vsb.exp
index 52a7d6b..bc2a9b8 100644
--- a/ld/testsuite/ld-vsb/vsb.exp
+++ b/ld/testsuite/ld-vsb/vsb.exp
@@ -29,7 +29,8 @@ if { ![check_compiler_available] } {
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*] \
@@ -45,11 +46,17 @@ if { ![istarget hppa*64*-*-hpux*] \
&& ![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]
@@ -61,6 +68,28 @@ set SHCFLAG ""
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
@@ -108,6 +137,10 @@ proc visibility_test { visibility progname testname main sh1 sh2 dat args } {
# 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"
}
@@ -128,8 +161,15 @@ proc visibility_test { visibility progname testname main sh1 sh2 dat args } {
# 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] } {
@@ -225,6 +265,14 @@ proc visibility_run {visibility} {
# 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.
@@ -287,7 +335,15 @@ proc visibility_run {visibility} {
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
@@ -328,9 +384,19 @@ proc visibility_run {visibility} {
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.
@@ -345,7 +411,7 @@ proc visibility_run {visibility} {
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
}
}}
@@ -392,7 +458,15 @@ proc visibility_run {visibility} {
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)"
}
@@ -405,7 +479,16 @@ proc visibility_run {visibility} {
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)"
}
@@ -461,7 +544,12 @@ if { ![ld_compile "$CC_FOR_TARGET -g $NOSANITIZE_CFLAGS $NOLTO_CFLAGS" $srcdir/$
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"] {
diff --git a/ld/testsuite/ld-vsb/xcoffvsb.dat b/ld/testsuite/ld-vsb/xcoffvsb.dat
new file mode 100644
index 0000000..aa75969
--- /dev/null
+++ b/ld/testsuite/ld-vsb/xcoffvsb.dat
@@ -0,0 +1,24 @@
+mainvar == 1
+overriddenvar == 2
+shlibvar1 == 3
+shlib_mainvar () == 1
+shlib_shlibvar1 () == 3
+shlib_shlibvar2 () == 4
+shlib_shlibcall () == 5
+shlib_maincall () == 6
+main_called () == 6
+shlib_checkfunptr1 (shlib_shlibvar1) == 1
+shlib_checkfunptr2 (main_called) == 1
+shlib_getfunptr1 () == shlib_shlibvar1
+shlib_getfunptr2 () == main_called
+shlib_check () == 1
+visibility_check () == 1
+visibility_checkfunptr () == 1
+main_visibility_check () == 1
+visibility_checkvar () == 1
+visibility_checkvarptr () == 1
+main_visibility_checkvar () == 1
+main_visibility_checkcom () == 1
+shlib_visibility_checkcom () == 1
+main_visibility_checkweak () == 1
+shlib_visibility_checkweak () == 1