diff --git a/sofort/ccenv/ccenv.in b/sofort/ccenv/ccenv.in
index 441f8ab..0daff84 100644
--- a/sofort/ccenv/ccenv.in
+++ b/sofort/ccenv/ccenv.in
@@ -84,8 +84,13 @@ PKGCONF                                 = @ccenv_pkgconf@
 AS                                      = @ccenv_as@
 LD                                      = @ccenv_ld@
 
+# @ccenv_cfgtype@ visibility attributes
+CFLAGS_ATTR_VISIBILITY_DEFAULT          = -D_ATTR_VISIBILITY_DEFAULT=@ccenv_attr_visibility_default@
+CFLAGS_ATTR_VISIBILITY_HIDDEN           = -D_ATTR_VISIBILITY_HIDDEN=@ccenv_attr_visibility_hidden@
+CFLAGS_ATTR_VISIBILITY_INTERNAL         = -D_ATTR_VISIBILITY_INTERNAL=@ccenv_attr_visibility_internal@
+CFLAGS_ATTR_VISIBILITY_PROTECTED        = -D_ATTR_VISIBILITY_PROTECTED=@ccenv_attr_visibility_protected@
+
 # @ccenv_cfgtype@ cflags
 CFLAGS_OS                              += -DOS_LIB_SUFFIX=\"@ccenv_os_lib_suffix@\"
 CFLAGS_OS                              += @ccenv_cflags_os@
 CFLAGS_PIC                             += @ccenv_cflags_pic@
-
diff --git a/sofort/ccenv/ccenv.sh b/sofort/ccenv/ccenv.sh
index a13aa07..0f7f486 100644
--- a/sofort/ccenv/ccenv.sh
+++ b/sofort/ccenv/ccenv.sh
@@ -1654,6 +1654,25 @@ ccenv_set_cc_linker_switch_vars()
 	done
 }
 
+ccenv_set_cc_attr_visibility_vars()
+{
+	if cfgtest_attr_visibility 'default'; then
+		ccenv_attr_visibility_default="$mb_cfgtest_attr"
+	fi
+
+	if cfgtest_attr_visibility 'hidden'; then
+		ccenv_attr_visibility_hidden="$mb_cfgtest_attr"
+	fi
+
+	if cfgtest_attr_visibility 'internal'; then
+		ccenv_attr_visibility_internal="$mb_cfgtest_attr"
+	fi
+
+	if cfgtest_attr_visibility 'protected'; then
+		ccenv_attr_visibility_protected="$mb_cfgtest_attr"
+	fi
+}
+
 ccenv_dso_verify()
 {
 	ccenv_str='int foo(int x){return ++x;}'
@@ -1760,6 +1779,7 @@ ccenv_set_toolchain_variables()
 	ccenv_set_os_dso_linkage
 	ccenv_set_os_dso_patterns
 	ccenv_set_os_pe_switches
+	ccenv_set_cc_attr_visibility_vars
 
 	ccenv_output_defs
 	ccenv_clean_up
diff --git a/sofort/ccenv/ccenv.vars b/sofort/ccenv/ccenv.vars
index 41eb327..054b638 100644
--- a/sofort/ccenv/ccenv.vars
+++ b/sofort/ccenv/ccenv.vars
@@ -82,6 +82,12 @@ ccenv_windrc=
 
 ccenv_pkgconf=
 
+# visibility attributes
+ccenv_attr_visibility_default=
+ccenv_attr_visibility_hidden=
+ccenv_attr_visibility_internal=
+ccenv_attr_visibility_protected=
+
 # cflags
 ccenv_cflags_os=
 ccenv_cflags_pic=
diff --git a/sofort/cfgtest/cfgtest.sh b/sofort/cfgtest/cfgtest.sh
index debdb8c..6abbfea 100644
--- a/sofort/cfgtest/cfgtest.sh
+++ b/sofort/cfgtest/cfgtest.sh
@@ -15,6 +15,7 @@
 # mb_cfgtest_cfgtype: the type of the current test (host/native)
 # mb_cfgtest_makevar: the make variable affected by the current test
 # mb_cfgtest_headers: headers for ad-hoc inclusion with the current test
+# mb_cfgtest_attr:    if supported, the compiler-specific attribute definition
 
 
 cfgtest_newline()
@@ -131,6 +132,15 @@ cfgtest_epilog()
 		return 1
 	fi
 
+	if [ "${1}" = 'attr' ] && [ "${2}" = '(error)' ]; then
+		printf '\n\ncfgtest: the %s compiler %s %s_ attribute.\n' \
+			"$mb_cfgtest_cfgtype"                            \
+			'does not appear to support the _'              \
+			"${3}" >&3
+		printf '%s\n' '------------------------' >&3
+		return 1
+	fi
+
 	if [ "${2}" = '-----' ] || [ "${2}" = '(missing)' ]; then
 		printf '\n\ncfgtest: %s %s is missing or cannot be found.\n' "${1}" "${3}" >&3
 		printf '%s\n' '------------------------' >&3
@@ -246,6 +256,8 @@ cfgtest_common_init()
 		fi
 	elif [ "$cfgtest_type" = 'asm' ]; then
 		cfgtest_fmt='%s -c -xc - -o a.out'
+	elif [ "$cfgtest_type" = 'attr' ]; then
+		cfgtest_fmt='%s -c -xc - -o a.out -Werror'
 	elif [ "$cfgtest_type" = 'lib' ]; then
 		cfgtest_fmt='%s -xc - -o a.out'
 	elif [ "$cfgtest_type" = 'ldflag' ]; then
@@ -534,6 +546,39 @@ cfgtest_type_size()
 }
 
 
+cfgtest_attr_visibility()
+{
+	# init
+	cfgtest_prolog 'compiler visibility attr' "${1}"
+
+	cfgtest_attr_syntax='__attribute__((__visibility__("'"${1}"'")))'
+	cfgtest_code_snippet="$cfgtest_attr_syntax"' int f_'"${1}"'(void);'
+
+	cfgtest_common_init 'attr'
+
+	# execute
+	cfgtest_ret=1
+
+	printf '%s' "$cfgtest_src"                  \
+		| eval $(printf '%s' "$cfgtest_cmd") \
+		> /dev/null 2>&3                      \
+	|| cfgtest_epilog 'attr' '(error)' "${1}"      \
+	|| return
+
+	# result
+	mb_cfgtest_attr=$(printf '__attribute__\\(\\(__visibility__\\(\\"%s\\"\\)\\)\\)' "${1}")
+
+	cfgtest_ret=0
+
+	printf 'cfgtest: %s compiler: above attribute is supported; see also ccenv/%s.mk.\n\n' \
+		"$mb_cfgtest_cfgtype" "$mb_cfgtest_cfgtype" >&3
+
+	cfgtest_epilog 'attr' '(ok)'
+
+	return 0
+}
+
+
 cfgtest_code_snippet_asm()
 {
 	# init