Controlling symbolic visibility of shared libraries (i) A brief introduction of symbolic visibility

Source: Internet
Author: User
Tags define variables visibility

What is symbol and symbol visibility

Symbols are one of the basic terms when it comes to the content of object files, links, and so on. In fact, in C + + languages, symbols are a number of user-defined variables, function names, and corresponding entities for namespaces, classes/structures/names, and so on. For example, when we define a non-static global variable or a non-static function, the C + + compiler generates symbols in the object file that are useful for the linker (linker) to determine whether different modules (object files, dynamic shared libraries, executables) share the same data or code.

Although variables and functions may be shared among modules, variable sharing between object files is more common. For example, a programmer might declare a variable in A.C:

extern int Shared_var;

The variable is defined in B.C:

int Shared_var;

In this way, two Shared_var symbols appear in the compiled objects A.O and B.O, and after the linker resolves, the symbols in A.O share the B.O address. However, it is rare for a variable to be shared between a shared library and an executable file. For such modules, the function is usually only visible to other modules. Sometimes we call this kind of function an API because we think the module is an interface that provides calls to other modules. We also refer to this symbol as an export (exported) because it is visible to other modules. Note that this visibility is only valid on dynamic links, because shared libraries are typically loaded as part of a memory image when the program is running. Therefore, symbolic visibility (symbol visibility) is a property for dynamic linking for all global symbols.

Why you need to control symbolic visibility

On different platforms, the XL/C + + compiler may choose to export or not export all symbols in the module. For example, when you create a executable and linking Format (ELF) shared library on an IBM PowerLinux platform, all symbols are exported by default. When you create a Xcoff library on an AIX system on the power platform, the current XL/C + + compiler may choose not to export any symbols without the help of a tool. There are other ways to allow programmers to determine symbol visibility one at a a--this is what the next part of this series is about. However, it is not generally recommended to export all the symbols in the module. Programmers can export symbols on demand. This is beneficial not only to the security of the library, but also to the dynamic link time.

When programmers choose to export all symbols, there is a high risk that there may be symbolic conflicts when linking, especially when the module is developed by different developers. Because a symbol is a low level concept, it does not involve scopes. As long as someone links to a library with the same symbolic name as your library, the library may accidentally overwrite your own symbols (hopefully with some warning or error messages) when the linker resolves. In most cases, such symbols are never used from the perspective of the Library designer. Therefore, it is helpful to avoid such problems by creating a limited, meaningful (and thoughtful) name for the symbol.

For C + + programming, now more and more performance-oriented. However, because of dependencies on other libraries and the use of specific C + + features (such as templates), compilers/linker tend to use and generate a large number of symbols. Therefore, exporting all symbols slows down the program and consumes a lot of memory. Exporting a limited number of symbols can shorten the load and link time for dynamic shared libraries. In addition, compiler-angle optimizations are supported, which means more efficient code is generated.

The above limitations on exporting all the symbols explain why you must define symbolic visibility. In this article, we will provide some solutions to control the symbols in the dynamic shared objects (DSO). Users can solve the same problem in different ways, and we will propose which solution should be preferred for a particular platform.

Ways to control symbol visibility

In the discussion that follows, we'll use the following C + + code fragment:
Listing 1. A.c

int myintvar = 5;

int func0 () {
return ++myintvar;
}

int func1 (int i) {
return func0 () * i;
}

In A.C, we define a variable myintvar, as well as two functions func0 and func1. By default, when you create a shared library on an AIX platform, the compiler and linker and the Createexportlist tool make all three symbols visible. We can check this out using the Dump binary tool from the Loader Symbol Table information:

$ xlc-qpic A.c-qmkshrobj-o libtest.a
$ Dump-tv LIBTEST.A

Loader Symbol Table information***
[Index] Value Scn IMEX sclass Type impid Name

[0] 0x20000280. Data EXP. RW secdef [Noimid] Myintvar
[1] 0x20000284. Data EXP DS secdef [Noimid] Func0__fv
[2] 0x20000290. Data EXP DS secdef [Noimid] Func1__fi

Here, "EXP" indicates that the symbol is exported. Function names Func0 and FUNC1 were restructured by the C + + reorganization rules (mangling rule) (but it's not hard to guess the meaning of names). The-t option for the Dump tool displays the Loader Symbol Table information, which the dynamic linker will use. In this case, all the symbols in the A.C are exported. But from the perspective of the library writer, in this case we might just want to export func1. Global symbol Myintvar and function func0 are considered to only maintain/change the internal state, or only in the local use. Therefore, it is important for library writers to make them invisible.

There are at least three ways we can achieve this. Includes: Using the static keyword, defining the GNU visibility property, and using the export list. Each approach has its own different functions and drawbacks. Here's a look at these ways.
1. Use the static keyword

Static in C + + is probably the most common keyword, because it can specify scope and storage for variables. For scopes, you can say that it disables external links for symbols in a file. This means that a symbol with a keyword static is never linked, because the compiler does not leave any information about the symbol for the linker. This is a language-level control that is the simplest way to hide a symbol.

Let's add the static keyword to the above example:
Listing 2. B.c

static int myintvar = 5;

static int func0 () {
return ++myintvar;
}

int func1 (int i) {
return func0 () * i;
}

To build the shared library and view the Loader Symbol Table information again, you can see the expected effect:

$ xlc-qpic A.c-qmkshrobj-o libtest.a
$ Dump-tv LIBTEST.A

Loader Symbol Table information***
[Index] Value Scn IMEX sclass Type impid Name

[0] 0x20000284. Data EXP DS secdef [Noimid] Func1__fi

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.