Index: tools/build/v2/tools/builtin.jam
===================================================================
--- tools/build/v2/tools/builtin.jam	(revision 62422)
+++ tools/build/v2/tools/builtin.jam	(working copy)
@@ -304,6 +304,11 @@
 # Used to select a specific variant of C++ ABI if the compiler supports several.
 feature.feature c++abi : : propagated optional ;
 
+# gcc symbol visibility feature 
+# Fixes #2114, see http://gcc.gnu.org/wiki/Visibility
+feature.feature visibility : default hidden internal protected ;
+feature.feature visibility-inlines : default hidden ; 
+
 feature.feature conditional : : incidental free ;
 
 # The value of 'no' prevents building of a target.
Index: tools/build/v2/tools/darwin.jam
===================================================================
--- tools/build/v2/tools/darwin.jam	(revision 62422)
+++ tools/build/v2/tools/darwin.jam	(working copy)
@@ -64,7 +64,13 @@
      <architecture>x86/<instruction-set>
      <architecture>power/<address-model>32
      <architecture>power/<address-model>64
-     <architecture>power/<instruction-set>  ;
+     <architecture>power/<instruction-set>  
+     <visibility>default
+     <visibility>hidden
+     <visibility>internal
+     <visibility>protected
+     <visibility-inlines>hidden
+  ;
 
 # Options:
 #
Index: tools/build/v2/tools/gcc.jam
===================================================================
--- tools/build/v2/tools/gcc.jam	(revision 62422)
+++ tools/build/v2/tools/gcc.jam	(working copy)
@@ -83,12 +83,13 @@
     {    
         local machine = [ MATCH "^([^ ]+)"
             : [ SHELL "$(command-string) -dumpmachine" ] ] ;
-        version ?= [ MATCH "^([0-9.]+)"
+        real-version = [ MATCH "^([0-9.]+)"
             : [ SHELL "$(command-string) -dumpversion" ] ] ;
         switch $(machine:L)
         {
             case *mingw* : flavor ?= mingw ;
         }
+        version ?= $(real-version) ;
     }
 
     local condition ;
@@ -109,6 +110,8 @@
 
     common.handle-options gcc : $(condition) : $(command) : $(options) ;
 
+    configure-version-specific $(real-version) : $(condition) ;
+
     local linker = [ feature.get-values <linker-type> : $(options) ] ;
     # The logic below should actually be keyed on <target-os>
     if ! $(linker)
@@ -205,6 +208,22 @@
     rc.configure $(rc) : $(condition) : <rc-type>$(rc-type) ;
 }
 
+rule configure-version-specific ( real-version : condition )
+{
+    if $(real-version) >= "4.0.0"
+    {
+        toolset.flags gcc.compile OPTIONS $(condition)/<visibility>default   : -fvisibility=default ;
+        toolset.flags gcc.compile OPTIONS $(condition)/<visibility>hidden    : -fvisibility=hidden ;
+        toolset.flags gcc.compile OPTIONS $(condition)/<visibility>internal  : -fvisibility=internal ;
+        toolset.flags gcc.compile OPTIONS $(condition)/<visibility>protected : -fvisibility=protected ;
+    }
+
+    if $(real-version) >= "4.3.0"
+    {
+        toolset.flags gcc.compile OPTIONS $(condition)/<visibility-inlines>hidden : -fvisibility-inlines-hidden ;
+    }
+}
+
 if [ os.name ] = NT
 {
     # This causes single-line command invocation to not go through .bat files,

