Control symbols exported from libabigail.so

Symbols of pretty much all member functions of types that are meant to
be "private" to translation units that contribute to libabigail.so
were exported because we didn't do much to prevent that.

This patch starts controlling the set of symbols that are exported.

By default, symbols of any entity declared in a translation unit that
contributes to libabigail.so are hidden by default.  Only symbols of
entities declared in public headers (headers in include/*.h) are
exported.

There are many ways to achieve that.  This patch chooses to avoid
cluttering declarations of entities in the public header by adding
__attribute__((visibility="default")) to every declared type of
function in there.

Rather, the patch uses "#pragma GCC visibility push(default)" before
entities declared on those headers.  By doing so, all those entities
have their symbol marked as "visible" by the compiler.  Once the
header are #included, the #pragma GCC visibility pop" is used, so that
anything else has its symbol be hidden from that point on.

Note that for ease of maintenance the patch uses the macros
ABG_BEGIN_EXPORT_DECLARATIONS and ABG_END_EXPORT_DECLARATIONS rather
than using the pragma directive directly.

I believe this is a more elegant way of handling visibility, compared
to cluttering every single declaration in public headers with a
"__attribute__((visibility=("default")))" or with a macro which
expands to it.

This reduces the the set of symbols exported by libabigail.so from
20000+ to less than 5000.

	* VISIBILITY: New documentation about this visiblity business.
	* CONTRIBUTING: Update the "contributing guide" to refer to symbol
	visibility issues.
	* configure.ac: Define a variable VISIBILITY_FLAGS that is set to
	the -fvisibility=hidden flag to pass to GCC, when its available.
	* src/Makefile.am: Add VISIBILITY to source distribution.  Also
	add COMPILING and COMMIT-LOG-GUIDELINES that were missing.
	* src/Makefile.am: Use the new $(VISIBILITY_FLAGS) when buiding
	the library.
	* tests/Makefile.am: Use the new $(VISIBILITY_FLAGS) when buiding
	tests.
	* tools/Makefile.am: Use the new $(VISIBILITY_FLAGS) when buiding
	tools.
	* src/abg-comp-filter.cc: Enclose inclusion of public headers in
	ABG_BEGIN_EXPORT_DECLARATIONS and ABG_END_EXPORT_DECLARATIONS to
	export the symbols of entities declared in there.
	* src/abg-comparison.cc: Likewise.
	* src/abg-config.cc: Likewise.
	* src/abg-corpus.cc: Likewise.
	* src/abg-diff-utils.cc: Likewise.
	* src/abg-dwarf-reader.cc: Likewise.
	* src/abg-hash.cc: Likewise.
	* src/abg-ini.cc: Likewise.
	* src/abg-ir.cc: Likewise.
	* src/abg-libxml-utils.cc: Likewise.
	* src/abg-libzip-utils.cc: Likewise.
	* src/abg-reader.cc: Likewise.
	* src/abg-suppression.cc: Likewise.
	* src/abg-tools-utils.cc: Likewise.
	* src/abg-traverse.cc: Likewise.
	* src/abg-viz-common.cc: Likewise.
	* src/abg-viz-dot.cc: Likewise.
	* src/abg-viz-svg.cc: Likewise.
	* src/abg-workers.cc: Likewise.
	* src/abg-writer.cc: Likewise.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
This commit is contained in:
Dodji Seketeli 2016-07-27 12:18:58 +02:00
parent 8b2f4ac43f
commit 103a6eb94f
28 changed files with 263 additions and 25 deletions

View File

@ -30,6 +30,11 @@ Patches have to be sent by email to libabigail@sourceware.org.
Please read the file COMMIT-LOG-GUIDELINES in the source tree to learn
about how to write the commit log accompanying the patch.
If you are adding a new public header file to the project, or if you
are defining a new entry point to the API of libabigail, please take
some time to read the file VISIBILITY about how you need to handle the
visibility of symbols that are part of the API and ABI of libabigail.
Make sure you sign your patch. To learn about signing, please read
the "Sign your work" chapter below.

View File

@ -19,8 +19,9 @@ EXTRA_DIST = \
autoconf-archive/ax_check_python_modules.m4 \
autoconf-archive/ax_prog_python_version.m4 \
autoconf-archive/ax_compare_version.m4 \
NEWS README COPYING ChangeLog \
COPYING-LGPLV2 COPYING-LGPLV3 \
NEWS README COPYING COMPILING \
COMMIT-LOG-GUIDELINES VISIBILITY \
ChangeLog COPYING-LGPLV2 COPYING-LGPLV3 \
COPYING-GPLV3 gen-changelog.py \
$(headers) $(m4data_DATA) \
libabigail.pc.in

68
VISIBILITY Normal file
View File

@ -0,0 +1,68 @@
PLEASE READ ALL OF THIS FILE, ESPECIALLY IF YOU ARE DEFINING A NEW
PUBLIC HEADER IN LIBABIGAIL.
How symbols that are exported are controlled in libabigail
==========================================================
We try to limit the number of ELF symbols that are exported by the
libabigail.so shared library. We call this symbols visibility
control.
As GNU/Linux is our development platform, we control symbol visibility
by using the visibility support of the G++ compiler.
How to do so is properly explained at https://gcc.gnu.org/wiki/Visibility.
All symbols are hidden by default
=================================
When building translation units that make up the libabigail.so shared
library, G++ is invoked with the -fvisibility=hidden directive. Which
instructs it to make symbols of functions and global variables
*locally* defined in the shared library, *NOT* exported (or global).
Exporting symbols of entities declared in public headers
========================================================
In a translation unit that is part of the libabigail.so shared
library, before including a header file that is a public libabigail
header (e.g, abg-ir.h), one need to declare:
#include "abg-internal.h"
ABG_BEGIN_EXPORT_DECLARATIONS
then all the public header files inclusion (using #include directives)
follow. At the end of these public header files inclusion, one need
to declare:
ABG_END_EXPORT_DECLARATIONS
The ABG_BEGIN_EXPORT_DECLARATIONS is a macro defined in abg-internal.h
which expands to:
#pragma GCC visibility push(default)
This instructs G++ to export the symbol of all global functions and
variables definitions that are declared from that point on.
The ABG_END_EXPORT_DECLARATIONS is a macro defined in abg-internal.h
which expands to:
#pragma GCC visibility pop
It instructs G++ to stop exporting symbols of global functions and
variable definition from that point on.
In practice, the pair ABG_BEGIN_EXPORT_DECLARATIONS,
ABG_END_EXPORT_DECLARATIONS allows us to only export symbols of
global functions and variables declared in the block denoted by these
two macros. Symbols of anything else that is declared outside of that block
are going to be hidden, thanks to the -fvisibility=hidden option
passed to G++.
So whenever you are defining a new header file with declarations that
ought to be part of the API of libabigail, the *definition* file which
defines the declarations of the header file must use
the ABG_BEGIN_EXPORT_DECLARATIONS and ABG_END_EXPORT_DECLARATIONS
macro to include the public header.

View File

@ -134,10 +134,14 @@ if test x$SUPPORTS_GCC_VISIBILITY_ATTRIBUTE = xyes; then
AC_MSG_NOTICE([GCC visibility attribute is supported])
AC_DEFINE([HAS_GCC_VISIBILITY_ATTRIBUTE], 1,
[Defined if the compiler supports the attribution visibility syntax __attribute__((visibility("hidden")))])
VISIBILITY_FLAGS="-fvisibility=hidden"
else
AC_MSG_NOTICE([GCC visibility attribute is not supported])
VISIBILITY_FLAGS=
fi
AC_SUBST(VISIBILITY_FLAGS)
dnl Check for dependency: libelf, libdw, libebl (elfutils)
dnl Note that we need to use at least elfutils 0.159 but
dnl at that time elfutils didnt have pkgconfig capabilities

View File

@ -1,11 +1,13 @@
lib_LTLIBRARIES=libabigail.la
libabigaildir=$(libdir)
AM_CXXFLAGS = $(VISIBILITY_FLAGS)
if ENABLE_CXX11
CXX11_SOURCES = abg-viz-common.cc \
abg-viz-dot.cc \
abg-viz-svg.cc
AM_CXXFLAGS="-std=gnu++11"
AM_CXXFLAGS += "-std=gnu++11"
else
CXX11_SOURCES =
endif

View File

@ -1,6 +1,6 @@
// -*- Mode: C++ -*-
//
// Copyright (C) 2013-2015 Red Hat, Inc.
// Copyright (C) 2013-2016 Red Hat, Inc.
//
// This file is part of the GNU Application Binary Interface Generic
// Analysis and Instrumentation Library (libabigail). This library is
@ -25,8 +25,15 @@
/// This file contains definitions of diff objects filtering
/// facilities.
#include "abg-internal.h"
// <headers defining libabigail's API go under here>
ABG_BEGIN_EXPORT_DECLARATIONS
#include "abg-comp-filter.h"
ABG_END_EXPORT_DECLARATIONS
// </headers defining libabigail's API>
namespace abigail
{
namespace comparison

View File

@ -26,15 +26,23 @@
/// libabigail.
#include <ctype.h>
#include <libgen.h>
#include <algorithm>
#include <sstream>
#include <libgen.h>
#include "abg-internal.h"
// <headers defining libabigail's API go under here>
ABG_BEGIN_EXPORT_DECLARATIONS
#include "abg-hash.h"
#include "abg-suppression.h"
#include "abg-comp-filter.h"
#include "abg-sptr-utils.h"
#include "abg-tools-utils.h"
ABG_END_EXPORT_DECLARATIONS
// </headers defining libabigail's API>
namespace abigail
{

View File

@ -1,6 +1,6 @@
// -*- Mode: C++ -*-
//
// Copyright (C) 2013-2015 Red Hat, Inc.
// Copyright (C) 2013-2016 Red Hat, Inc.
//
// This file is part of the GNU Application Binary Interface Generic
// Analysis and Instrumentation Library (libabigail). This library is
@ -20,10 +20,16 @@
/// @file
#include "config.h"
#include "abg-internal.h"
// <headers defining libabigail's API go under here>
ABG_BEGIN_EXPORT_DECLARATIONS
#include "abg-config.h"
#include "abg-version.h"
ABG_END_EXPORT_DECLARATIONS
// </headers defining libabigail's API>
namespace abigail
{
config::config()

View File

@ -28,6 +28,11 @@
#include <stdexcept>
#include <algorithm>
#include <tr1/unordered_map>
#include "abg-internal.h"
// <headers defining libabigail's API go under here>
ABG_BEGIN_EXPORT_DECLARATIONS
#include "abg-sptr-utils.h"
#include "abg-ir.h"
#include "abg-corpus.h"
@ -38,6 +43,9 @@
#include "abg-libzip-utils.h"
#endif
ABG_END_EXPORT_DECLARATIONS
// </headers defining libabigail's API>
namespace abigail
{

View File

@ -1,6 +1,6 @@
// -*- Mode: C++ -*-
//
// Copyright (C) 2013-2015 Red Hat, Inc.
// Copyright (C) 2013-2016 Red Hat, Inc.
//
// This file is part of the GNU Application Binary Interface Generic
// Analysis and Instrumentation Library (libabigail). This library is
@ -19,8 +19,16 @@
// not, see <http://www.gnu.org/licenses/>.
#include <cstring>
#include "abg-internal.h"
// <headers defining libabigail's API go under here>
ABG_BEGIN_EXPORT_DECLARATIONS
#include "abg-diff-utils.h"
ABG_END_EXPORT_DECLARATIONS
// </headers defining libabigail's API>
/// @file
///
/// This file defines the declarations found in abg-diff-utils.h

View File

@ -46,10 +46,18 @@
#include <list>
#include <ostream>
#include <sstream>
#include "abg-internal.h"
// <headers defining libabigail's API go under here>
ABG_BEGIN_EXPORT_DECLARATIONS
#include "abg-dwarf-reader.h"
#include "abg-sptr-utils.h"
#include "abg-tools-utils.h"
ABG_END_EXPORT_DECLARATIONS
// </headers defining libabigail's API>
using std::string;
namespace abigail

View File

@ -20,9 +20,16 @@
/// @file
#include "abg-internal.h"
// <headers defining libabigail's API go under here>
ABG_BEGIN_EXPORT_DECLARATIONS
#include "abg-hash.h"
#include "abg-ir.h"
ABG_END_EXPORT_DECLARATIONS
// </headers defining libabigail's API>
namespace abigail
{

View File

@ -1,6 +1,6 @@
// -*- Mode: C++ -*-
//
// Copyright (C) 2013-2015 Red Hat, Inc.
// Copyright (C) 2013-2016 Red Hat, Inc.
//
// This file is part of the GNU Application Binary Interface Generic
// Analysis and Instrumentation Library (libabigail). This library is
@ -31,8 +31,16 @@
#include <memory>
#include <fstream>
#include <sstream>
#include "abg-internal.h"
// <headers defining libabigail's API go under here>
ABG_BEGIN_EXPORT_DECLARATIONS
#include "abg-ini.h"
ABG_END_EXPORT_DECLARATIONS
// </headers defining libabigail's API>
namespace abigail
{
namespace ini

View File

@ -39,8 +39,8 @@
///(function or variable) is going to be global. External ELF files
///will be able to link against the symbol.
#define ABG_EXPORTED __attribute__((visibility("default")))
#define ABG_BEGIN_EXPORT_DECLARATIONS #pagma GCC visibility push(default)
#define ABG_END_EXPORT_DECLARATIONS #pragma GCC visibility pop
#define ABG_BEGIN_EXPORT_DECLARATIONS _Pragma("GCC visibility push(default)")
#define ABG_END_EXPORT_DECLARATIONS _Pragma("GCC visibility pop")
#else
#define ABG_HIDDEN
#define ABG_EXPORTED

View File

@ -33,11 +33,19 @@
#include <sstream>
#include <tr1/memory>
#include <tr1/unordered_map>
#include "abg-internal.h"
// <headers defining libabigail's API go under here>
ABG_BEGIN_EXPORT_DECLARATIONS
#include "abg-sptr-utils.h"
#include "abg-interned-str.h"
#include "abg-ir.h"
#include "abg-corpus.h"
ABG_END_EXPORT_DECLARATIONS
// </headers defining libabigail's API>
namespace
{
/// This internal type is a tree walker that walks the sub-tree of a

View File

@ -1,6 +1,6 @@
// -*- mode: C++ -*-
//
// Copyright (C) 2013-2015 Red Hat, Inc.
// Copyright (C) 2013-2016 Red Hat, Inc.
//
// This file is part of the GNU Application Binary Interface Generic
// Analysis and Instrumentation Library (libabigail). This library is
@ -22,8 +22,16 @@
#include <string>
#include <iostream>
#include "abg-internal.h"
// <headers defining libabigail's API go under here>
ABG_BEGIN_EXPORT_DECLARATIONS
#include "abg-libxml-utils.h"
ABG_END_EXPORT_DECLARATIONS
// </headers defining libabigail's API>
namespace abigail
{

View File

@ -1,6 +1,6 @@
// -*- mode: C++ -*-
//
// Copyright (C) 2013-2015 Red Hat, Inc.
// Copyright (C) 2013-2016 Red Hat, Inc.
//
// This file is part of the GNU Application Binary Interface Generic
// Analysis and Instrumentation Library (libabigail). This library is
@ -20,12 +20,17 @@
/// @file
#include "config.h"
#include "abg-internal.h"
#ifdef WITH_ZIP_ARCHIVE
// <headers defining libabigail's API go under here>
ABG_BEGIN_EXPORT_DECLARATIONS
#include <string>
#include "abg-libzip-utils.h"
ABG_END_EXPORT_DECLARATIONS
// </headers defining libabigail's API>
#include <string>
namespace abigail
{

View File

@ -1,6 +1,6 @@
// -*- mode: C++ -*-
//
// Copyright (C) 2013-2015 Red Hat, Inc.
// Copyright (C) 2013-2016 Red Hat, Inc.
//
// This file is part of the GNU Application Binary Interface Generic
// Analysis and Instrumentation Library (libabigail). This library is
@ -35,13 +35,22 @@
#include <sstream>
#include <libxml/xmlstring.h>
#include <libxml/xmlreader.h>
#include "abg-internal.h"
// <headers defining libabigail's API go under here>
ABG_BEGIN_EXPORT_DECLARATIONS
#include "abg-libxml-utils.h"
#include "abg-reader.h"
#include "abg-corpus.h"
#ifdef WITH_ZIP_ARCHIVE
#include "abg-libzip-utils.h"
#endif
ABG_END_EXPORT_DECLARATIONS
// </headers defining libabigail's API>
namespace abigail
{

View File

@ -25,12 +25,19 @@
/// This contains the implementation of the suppression engine of
/// libabigail.
#include "abg-internal.h"
// <headers defining libabigail's API go under here>
ABG_BEGIN_EXPORT_DECLARATIONS
#include "abg-suppression.h"
#include "abg-ini.h"
#include "abg-sptr-utils.h"
#include "abg-comp-filter.h"
#include "abg-tools-utils.h"
// <headers defining libabigail's API go under here>
ABG_BEGIN_EXPORT_DECLARATIONS
namespace abigail
{

View File

@ -33,9 +33,17 @@
#include <fstream>
#include <iostream>
#include <sstream>
#include "abg-internal.h"
// <headers defining libabigail's API go under here>
ABG_BEGIN_EXPORT_DECLARATIONS
#include <abg-ir.h>
#include "abg-tools-utils.h"
ABG_END_EXPORT_DECLARATIONS
// </headers defining libabigail's API>
using std::string;
namespace abigail

View File

@ -1,6 +1,6 @@
// -*- Mode: C++ -*-
//
// Copyright (C) 2013-2015 Red Hat, Inc.
// Copyright (C) 2013-2016 Red Hat, Inc.
//
// This file is part of the GNU Application Binary Interface Generic
// Analysis and Instrumentation Library (libabigail). This library is
@ -20,8 +20,15 @@
/// @file
#include "abg-internal.h"
// <headers defining libabigail's API go under here>
ABG_BEGIN_EXPORT_DECLARATIONS
#include "abg-traverse.h"
ABG_END_EXPORT_DECLARATIONS
// </headers defining libabigail's API>
namespace abigail
{

View File

@ -18,10 +18,18 @@
// License along with this program; see the file COPYING-LGPLV3. If
// not, see <http://www.gnu.org/licenses/>.
#include "abg-viz-svg.h"
#include <stdexcept>
#include <fstream>
#include "abg-internal.h"
// <headers defining libabigail's API go under here>
ABG_BEGIN_EXPORT_DECLARATIONS
#include "abg-viz-svg.h"
ABG_END_EXPORT_DECLARATIONS
// </headers defining libabigail's API>
namespace abigail
{

View File

@ -1,6 +1,6 @@
// -*- mode: C++ -*-
//
// Copyright (C) 2013-2015 Red Hat, Inc.
// Copyright (C) 2013-2016 Red Hat, Inc.
//
// This file is part of the GNU Application Binary Interface Generic
// Analysis and Instrumentation Library (libabigail). This library is
@ -18,10 +18,19 @@
// License along with this program; see the file COPYING-LGPLV3. If
// not, see <http://www.gnu.org/licenses/>.
#include "abg-viz-dot.h"
#include <stdexcept>
#include <fstream>
#include "abg-internal.h"
// <headers defining libabigail's API go under here>
ABG_BEGIN_EXPORT_DECLARATIONS
#include "abg-viz-dot.h"
ABG_END_EXPORT_DECLARATIONS
// </headers defining libabigail's API>
namespace abigail
{

View File

@ -1,6 +1,6 @@
// -*- mode: C++ -*-
//
// Copyright (C) 2013-2015 Red Hat, Inc.
// Copyright (C) 2013-2016 Red Hat, Inc.
//
// This file is part of the GNU Application Binary Interface Generic
// Analysis and Instrumentation Library (libabigail). This library is
@ -18,10 +18,18 @@
// License along with this program; see the file COPYING-LGPLV3. If
// not, see <http://www.gnu.org/licenses/>.
#include "abg-viz-svg.h"
#include <stdexcept>
#include <fstream>
#include "abg-internal.h"
// <headers defining libabigail's API go under here>
ABG_BEGIN_EXPORT_DECLARATIONS
#include "abg-viz-svg.h"
ABG_END_EXPORT_DECLARATIONS
// </headers defining libabigail's API>
namespace abigail
{

View File

@ -32,7 +32,16 @@
#include <queue>
#include <vector>
#include <iostream>
#include "abg-internal.h"
// <headers defining libabigail's API go under here>
ABG_BEGIN_EXPORT_DECLARATIONS
#include "abg-workers.h"
ABG_END_EXPORT_DECLARATIONS
// </headers defining libabigail's API>
namespace abigail
{

View File

@ -1,6 +1,6 @@
// -*- mode: C++ -*-
//
// Copyright (C) 2013-2015 Red Hat, Inc.
// Copyright (C) 2013-2016 Red Hat, Inc.
//
// This file is part of the GNU Application Binary Interface Generic
// Analysis and Instrumentation Library (libabigail). This library is
@ -34,6 +34,11 @@
#include <stack>
#include <algorithm>
#include <tr1/unordered_map>
#include "abg-internal.h"
// <headers defining libabigail's API go under here>
ABG_BEGIN_EXPORT_DECLARATIONS
#include "abg-config.h"
#include "abg-corpus.h"
#include "abg-diff-utils.h"
@ -46,6 +51,9 @@
#include "abg-writer.h"
#include "abg-libxml-utils.h"
ABG_END_EXPORT_DECLARATIONS
// </headers defining libabigail's API>
namespace abigail
{
using std::cerr;

View File

@ -8,10 +8,12 @@ ZIP_ARCHIVE_TESTS += runtestdot
endif
endif
AM_CXXFLAGS = $(VISIBILITY_FLAGS)
CXX11_TESTS =
if ENABLE_CXX11
CXX11_TESTS += runtestsvg
AM_CXXFLAGS = "-std=gnu++11"
AM_CXXFLAGS += "-std=gnu++11"
endif
FEDABIPKGDIFF_TEST =

View File

@ -49,4 +49,6 @@ abipkgdiffdir = $(bindir)
abipkgdiff_LDADD = $(abs_top_builddir)/src/libabigail.la
abipkgdiff_LDFLAGS = -pthread
AM_CPPFLAGS=-I$(abs_top_srcdir)/include -I$(abs_top_srcdir)/tools -fPIC
AM_CXXFLAGS = \
$(VISIBILITY_FLAGS) -I$(abs_top_srcdir)/include \
-I$(abs_top_srcdir)/tools -fPIC