Chapter 7. Loader Information #pragma Directives
Prev |  | Next

## Chapter 7. Loader Information `#pragma` Directives

Table 7-1 lists the `#pragma` directives discussed in this chapter, along with a brief description of each and the compiler versions in which the directive is supported.

Table 7-1. Loader Information `#pragma` Directives

#pragma | Short Description | Compiler Versions
--- | --- | ---
`#pragma hidden` | Tells the compiler that the specified symbols are invisible to all executables or DSOs except the current one. | 7.2 and later
`#pragma internal` | Tells the compiler that the specified symbols are not referenced outside the current executable or DSO. | 7.2 and later
`#pragma no_delete` | Inhibits deletion of functions that are never referenced. | 7.1 and later
`#pragma optional` | Tells the linker that the specified symbols are optional. This is the basic mechanism used for adding extensions to a library that can then be queried. | 7.2.1 and later
`#pragma protected` | Tells the compiler that the specified symbols are not preemptible. | 7.1 and later
`#pragma section_gp` | Causes an object to be placed in a gp_relative section. | 7.2 and later
`#pragma section_non_gp` | Keeps an object from being placed in a gp_relative section. | 7.2 and later
`#pragma weak` | Tells the link editor not to issue a warning if it does not find a defining declaration of the weak_symbol. Also allows the overriding of a current definition by a non-weak definition. | 7.0 and later
`#pragma weak` weak_symbol = strong_symbol | Sets weak_symbol to be an alias for the function or data object denoted by strong_symbol , unless a defining declaration for weak_symbol is encountered at static link time. If encountered, the defining declaration preempts the weak denotation. | 7.0 and later

## `#pragma hidden`

The `#pragma hidden` directive tells the compiler that the specified symbols are invisible to all executables or DSOs except the current one. This allows hidden data objects to be placed in the small data area and accessed using the (fast) gp-relative load/store. Hidden symbols need not be put into the hash table of a DSO because they are not globally visible.

The syntax of the `#pragma hidden` directive is as follows:

    #pragma hidden symbol1 [, symbol2 ...]

`#pragma hidden` is not currently supported in C++, except for symbols marked `extern “C”`.

All of the listed symbols are marked as `STO_HIDDEN.` This means that the symbol definition can be referenced only within an object, not from outside. Even though a hidden symbol cannot be directly referenced from outside a DSO, its address may be taken and passed, so it is possible to call a hidden function from another DSO.

## `#pragma internal`

The `#pragma internal` directive tells the compiler that the specified functions are not referenced outside the current executable or DSO. Internal symbols are the same as hidden symbols, except that they are guaranteed not to be referenced from outside a DSO, even through pointers or weak bindings.

The syntax of the `#pragma internal` directive is as follows:

    #pragma internal func1 [, func2 ...]

`#pragma internal` is not currently supported in C++, except for symbols marked `extern “C”`.

The specified functions are marked `STO_INTERNAL`. This means that this function need not save, restore, or recalculate `$gp` (global pointer), because it is callable only from a location that has the same `$gp` (global pointer) value.

## `#pragma no_delete` name

The `#pragma no_delete` directive inhibits deletion of functions that are never referenced.

The syntax of the `#pragma no_delete` directive is as follows:

    #pragma no_delete

| Note: This pragma applies only to C++ and is not available for C programs. It applies only to functions, not data. It changes the ELF symbol name from its current name to a local name, thus making the ELF name (as seen by `dis(1)`) unusual and causing the name to not appear to debuggers.

## `#pragma optional`

The `#pragma optional` directive tells the linker that the specified symbols are optional.

The static linker (`ld`), converts references to optional definitions (in another DSO) to optional references. Unresolved optional references are not reported as errors.

The run-time linker (`rld`) resolves any unresolved optional references to a special symbol in `libc.so.1`.

Programs can check for the existence of an optional symbol by use of macros defined in the header file `/usr/include/optional_sym.h`.

This is the basic mechanism used for adding extensions to a library that you can then query. For example, when new functions are added to the next revision of `libfoo.so`, they can be added as optional functions; then programs can check for their existence and use them only when the new revision of the library is available and avoid them on older systems, thus giving backwards and forwards compatibility across a series of releases.

The syntax of the `#pragma optional` directive is as follows:

    #pragma optional symbol1 [, symbol2 ... ]

The following rules apply to `#pragma optional`:

- `#pragma optional` must come after the declaration or definition of symbol.

- `#pragma optional` is not currently supported in C++, except for symbols marked `extern “C”`.

## `#pragma protected`

The `#pragma protected` directive tells the compiler that the specified symbols are not preemptible, but are visible from outside of a DSO.

The syntax of the `#pragma protected` directive is as follows:

    #pragma protected symbol1 [, symbol2 ...]

`#pragma protected` is not currently supported in C++, except for symbols marked `extern “C”`.

The specified symbols are marked `STO_PROTECTED`. This means that the symbol definition cannot be preempted by another definition.

## `#pragma section_gp`

MIPS binaries have a global pointer (gp) that can be used to reference global data more efficiently (by using gp + offset) than constructing the entire address when that variable is referenced. Only a limited set of elements can be referenced in this fashion because the size of offset is limited to 16 bits. The compiler heuristically places global data in either gp-relative or non-gp-relative sections. However, it is sometimes useful to manually control which variables go within the gp-relative section and which need to be addressed explicitly.

The `#pragma section_gp` directive causes an object to be placed in a gp_relative section, while the `#pragma section_non_gp` directive causes an object to be placed in a non-gp-relative section.

The syntax of the `#pragma section_gp` directive is as follows:

    #pragma section_gp symbol1[, symbol2 ...]

symbol must be a static or global variable.

## `#pragma section_non_gp`

MIPS binaries have a global pointer (gp) that can be used to reference global data more efficiently (by using gp + offset) than constructing the entire address when that variable is referenced. Only a limited set of elements can be referenced in this fashion because the size of offset is limited to 16 bits. The compiler heuristically places global data in either gp-relative or non-gp-relative sections. However, it is sometimes useful to manually control which variables go within the gp-relative section and which need to be addressed explicitly.

The `#pragma section_gp` directive causes an object to be placed in a gp_relative section, while the `#pragma section_non_gp` directive causes an object to be placed in a non-gp-relative section.

The syntax of the `#pragma section_non_gp` directive is as follows:

    #pragma section_non_gp symbol1[, symbol2 ...]

symbol must be a static or global variable.

## `#pragma weak`

The `#pragma weak` directive can be used in two ways. It can instruct the link editor to not issue a warning if it does not find a defining declaration of the specified weak symbol, or it can allow the overriding of a current definition by a non-weak definition.

Weak definitions behave as follows:

- A definition is weak if a symbol defined in an executable or DSO is marked as weak at the point of definition.

- A weak definition is preemptible and will be preempted by any strong global definition of the same name in the executable, the DSOs linked in at static link time, or the DSOs linked in at run time. Multiple weak definitions follow the same preemption rules as for global symbols except that they will all be preempted by any strong definition of their name.

- Multiple global weak definitions of a symbol may or may not result in an error:

  - At static link time, multiple global definitions of a weak symbol within a DSO or executable result in an error. For example, linking `a.o` and `b.o` when they both have definitions for the symbol x results in an error.

  - At run time, multiple global weak definitions of a symbol across the executable and its DSOs, result in the first definition preempting all others. No error message is generated. For example, if your executable, `j`, references the DSOs `k.so` and `l.so` that have weak definitions of the symbol y, the first definition encountered is used, and the other is ignored.

- Unresolved weak references do not cause a run-time error, even if the environment variable `LD_BIND_NOW` is set. They have a value of 0 (that is, the symbol address is taken as 0). Attempting a call of a weak undefined function symbol gets either a core dump (if `LD_BIND_NOW` is 1) or a fatal run-time linker error on an attempted address of an unresolved symbol (if `LD_BIND_NOW` is not 1). Attempting a load or store of an undefined weak symbol results in a core dump because the address is 0, and 0 is normally not a legal virtual address.

- Weak references do not trigger the loading of delay-loaded libraries. This implies that weak object references may go unresolved until some other event triggers the loading of the delay-load library.

The syntax of the `#pragma weak` directive is as follows:

    #pragma weak weak_symbol [= strong_symbol]

When `#pragma weak` applies to a C++ function, weak_symbol and strong_symbol must be the mangled names.

The `#pragma weak` directive can be used in the following two ways:

- `#pragma weak`weak_symbol

  Used in this way, the `#pragma weak` directive tells the link editor to not issue a warning if it does not find a defining declaration of weak_symbol. References to the symbol use the appropriate lvalue if the symbol is defined; otherwise, it uses memory location zero (0).

- `#pragma weak` weak_symbol = strong_symbol

  In this case, the weak_symbol is an alias that denotes the same function or data object as that denoted by the strong_symbol, unless a defining declaration for the weak_symbol is encountered at static link time or in dynamically linked libraries. If encountered, the defining declaration preempts the weak denotation.

  Observe the following conventions when using this form of the directive:

  - Define the strong_symbol within the same compilation unit in which the directive occurs.

  - Declare the weak and strong symbols with compatible types. When the strong symbol is a data object, its declaration must be initialized.

  - Declare the weak_symbol with extern linkage in the same compilation unit. The extern declaration of the weak symbol is not required, unless the symbol is referenced within the compilation unit, but Silicon Graphics recommends it for type-checking purposes.

    Weak `extern` declarations are typically used to export non-ANSI C symbols from a library without polluting the ANSI C name-space. As an example, `libc` may export a weak symbol `read()`, which aliases a strong symbol `_read()`, where `_read()` is used in the implementation of the exported symbol `fread()`. You can either use the exported (weak) version of `read()`, or define your own version of `read()`, thereby preempting the weak denotation of this symbol. This will not alter the definition of `fread()`, because it depends only on the (strong) symbol `_read()`, which is outside of the ANSI C name-space.

    For example, the following code defines a new version of `read()` (which is a weak symbol in `libc.so.1`):

        /* read() is a weak symbol in libc.so.1
             This program omits error checking and makes no
             attempt at good style!
        */
        #include <stdio.h>
        char *read(int);

        int main(int argc, char **argv)
        {
          char *var;
          int c;

          c = getchar();

          var = read(c);
          printf(“%s\n”,var);
          return c;
        }

        char *read(int val)
        {
          static char buf[100];
          sprintf(buf,”%d”,val);
          return buf;
        }

    This program reads a single character from standard input and prints the character's decimal value. Even though `getchar()` uses the `libc.so` version of `fread()`, the redefinition of `read()` has no effect on the internal processing in `libc.so` because `fread()` uses the strong symbol `_read()`.

| Caution: The `#pragma weak` directive is not supported in `-o32` C++.

Prev | Table of Contents | Next
Chapter 6. Inlining #pragma Directives |  | Chapter 8. Loop Nest Optimization #pragma Directives