Visibility in shared objects
In the GNU Compiler Collection (GCC) environment, the term that is used for exporting is visibility. As it applies to functions and variables in a shared object, visibility refers to the ability of other shared objects to call a C/C++ function. Functions with default visibility have a global scope and can be called from other shared objects. Functions with hidden visibility have a local scope and cannot be called from other shared objects.
Visibility can be controlled by using either compiler options or
visibility attributes. The -fvisibility=default compiler
option (used in conjunction with the -fvisibility inlines=default compiler
option for C++ programs)
is used to define all of the functions in a shared object as visible
(global scope). These compiler options are available on all z/TPF-supported
compilers. Adding the visibility attribute can override a compiler
option.
Using the z/TPF MakeTPF
tool makes it relatively easy to control the visibility of functions
by changing the makefile to specify APP_EXPORT or
to use the visibility attribute in the program.
MakeTPF and visibility
APP_EXPORT variable controls which functions
are local to the shared object and which
functions can be called from other shared objects, where APP_EXPORT can
be set to: ALL, VISIBILITY, LIST,
or ENTRY. ALLis used to make all functions visible by default at compile time, by adding the-fvisibility=defaultcompiler option (used in conjunction with the-fvisibility inlines=defaultcompiler option for C++ programs) to the compile commands. Individual functions can be hidden by using the visibility attribute; add__attribute__ ((visibility("hidden"))to the functions you want to hide.Note: Avoid adding__attribute__ ((visibility("hidden"))to C++ code unless it is essential for class member functions to be hidden. For more information about potential problems when you use visibility with C++ classes, see Special considerations for C++ classes.VISIBILITYis used to hide all functions by default at compile time, by adding the-fvisibility=hiddencompiler option (used in conjunction with the-fvisibility inlines=hiddencompiler option for C++ programs) to the compile commands. Individual functions can be made visible by using the visibility attribute; add__attribute__ ((visibility("default"))to the functions you want to make visible.Note: Use this option for shared objects that contain only C language code because runtime problems can occur when you use this option on a shared object that contains C++ code. For more information about potential problems when you use visibility with C++ classes, see Special considerations for C++ classes.LISTis used to indicate that the list of visible functions is provided in an export file. As withALL, the-fvisibility=defaultcompiler option (used in conjunction with the-fvisibility inlines=defaultcompiler option for C++ programs) is used at compile time to make the functions visible; however, at link time, the export file provides:- A list of functions that are to be hidden.
- A list of functions that are visible.
Note: You must use theLISToption and export files when hiding functions that are coded in assembly language, because there is no assembly option that is equivalent to the-fvisibilityoption. For more information, see Export files.ENTRYis used to indicate that only the function specified byAPP_ENTRYis made visible. This is also controlled at link time by using the base/exp/app_entry.exp export file. For more information, see Export files.
Examples
- To make all of the functions for a given program visible except
for the
ftpc_get_filefunction, specifyAPP_EXPORT := ALLin the makefile for the program and code the following in your C/C++ application source code:
Adding the attribute hides the C/C++ function.__attribute__ ((visibility("hidden"))) size_t ftpc_get_file (void *ptr, size_t size, size_t nmemb, void *stream) { ... } - To hide all of the functions for a given program except for
the
mq_msgfunction, specify APP_EXPORT := VISIBILITY in the makefile for the program and code the following in your C/C++ application source code:
Adding the attribute makes the C/C++ function visible.__attribute__ ((visibility("default"))) char *mq_msg(size_t buffer_length); - In this example, the makefile for program ABCD makes all functions
visible by default. However, the application hides
uncallableFunction( )by declaring it as a static function; the application also hidesanotherUncallableFunction( )by using thevisibility("hidden")attribute. An important distinction to make is that the scope of the hidden function in terms of visibility is the shared object, while the scope of the static function is limited to the object.abcd.mak:APP := ABCD APP_EXPORT := ALL C_SRC := program.cprogram.h:void callableFunction( ); void anotherCallableFunction( ); static void uncallableFunction( ); __attribute__ ((visibility("hidden"))) void anotherUncallableFunction( );
Special considerations for C++ classes
C++ classes have a number of vague linkage entities; for example,typeinfo and vtable.
These entities take on the visibility attribute of the class; therefore,
if a class is hidden, the entities are hidden, which might have undesirable
side effects. Some side effects include not being able to be inherited
from a class in a different shared object and not being able to get
thrown by an exception. -fvisibility=hidden option
is when the now-hidden class needs to run a constructor from another
shared object (such as running a constructor for an inherited class);
it appears to compile and link, but you will receive a runtime linkage
error. APP_EXPORT := VISIBILITY.In general, it is best not to use the visibility option for C++ object-oriented programs because of the danger of generating runtime errors that are difficult to debug. Instead, take advantage of the inherent characteristics of C++ object-oriented programs, such as encapsulation, namespaces, inheritance, and other characteristics.
If, however, you do use the visibility option for C++ programs, use it with declarations; in most cases, you do not need to specify the visibility option in the definition.
Export files
Also called version scripts, export files in the z/TPF system are meant to be used when you have C/C++ functions that are coded in basic assembly language (BAL) that need to be hidden (not shared globally); the only way to hide them is by using an export file. With an export file, you can hide functions that were visible at assemble (or compile) time. However, at link time, you cannot make visible any functions that were hidden at assemble or compile time.
The executable and linking format (ELF)-compatible compilers support export files for z/TPF applications that require specific symbols to be modified. For more information about export files, see the GNU website.
For more information about using export files with the MakeTPF build solution, see Create an export file and Update export files.