Linker and Libraries Guide

Generating the Output File

After input file processing and symbol resolution has completed with no fatal errors, the link-editor generates the output file. The link-editor first generates the additional sections necessary to complete the output file. These sections include the symbol tables, which contain local symbol definitions together with resolved global symbol and weak symbol information, from all the input files.

Also included are any output relocation and dynamic information sections required by the runtime linker. After all the output section information has been established, the total output file size is calculated. The output file image is then created accordingly.

When creating a dynamic executable or shared object, two symbol tables are usually generated. The .dynsym table and its associated string table .dynstr contain register, global, weak, and section symbols. These sections become part of the text segment that is mapped as part of the process image at runtime. See mmap(2). This mapping enables the runtime linker to read these sections to perform any necessary relocations.

The .symtab table, and its associated string table .strtab contain all the symbols collected from the input file processing. These sections are not mapped as part of the process image. These sections can even be stripped from the image by using the link-editor's -s option, or after the link-edit by using strip(1).

During the generation of the symbol tables, reserved symbols are created. These symbols have special meaning to the linking process. These symbols should not be defined in your code.

_etext

The first location after all read-only information, typically referred to as the text segment.

_edata

The first location after initialized data.

_end

The first location after all data.

_DYNAMIC

The address of the .dynamic information section.

_END_

The same as _end. The symbol has local scope and, together with the _START_ symbol, provides a simple means of establishing an object's address range.

_GLOBAL_OFFSET_TABLE_

The position-independent reference to a link-editor supplied table of addresses, the .got section. This table is constructed from position-independent data references that occur in objects that have been compiled with the -K pic option. See Position-Independent Code.

_PROCEDURE_LINKAGE_TABLE_

The position-independent reference to a link-editor supplied table of addresses, the .plt section. This table is constructed from position-independent function references that occur in objects that have been compiled with the -K pic option. See Position-Independent Code.

_START_

The first location within the text segment. The symbol has local scope and, together with the _END_ symbol, provides a simple means of establishing an object's address range.

When generating an executable, the link-editor looks for additional symbols to define the executable's entry point. If a symbol was specified using the link-editor's -e option, that symbol is used. Otherwise the link-editor looks for the reserved symbol names _start, and then main.

Identifying Hardware and Software Capabilities

The hardware and software capabilities of a relocatable object are typically recorded at compile time. The link-editor combines the capabilities of any input relocatable objects to create a final capabilities section for the output file. See Hardware and Software Capabilities Section.

In addition, capabilities can be defined when the link-editor creates an output file. These capabilities are identified using a mapfile and the link-editor's -M option. Capabilities that are defined by using a mapfile can augment, or override, the capabilities that are supplied from input relocatable objects.

The following sections describe how capabilities can be defined using a mapfile.

Identifying Hardware Capabilities

The hardware capabilities of an object identify the hardware requirements of a platform necessary for the object to execute correctly. An example of this requirement might be the identification of code that requires the MMX or SSE features that are available on some x86 architectures.

Hardware capability requirements can be identified using the following mapfile syntax.


hwcap_1 = TOKEN | Vval [ OVERRIDE ];

The hwcap_1 declaration is qualified with one or more tokens, which are symbolic representations of hardware capabilities. In addition, or alternatively, a numeric value representing one of more capabilities can be supplied by prefixing the value with a V. For SPARC platforms, hardware capabilities are defined as AV_ values in sys/auxv_SPARC.h. For x86 platforms, hardware capabilities are defined as AV_ values in sys/auxv_386.h.

The following x86 example shows the declaration of MMX and SSE as hardware capabilities required by the object foo.so.1.


$ egrep "MMX|SSE" /usr/include/sys/auxv_386.h
#define AV_386_MMX    0x0040
#define AV_386_SSE    0x0800
$ cat mapfile
hwcap_1 = SSE MMX;
$ cc -o foo.so.1 -G -K pic -Mmapfile foo.c -lc
$ elfdump -H foo.so.1

Hardware/Software Capabilities Section:  .SUNW_cap
     index  tag               value
       [0]  CA_SUNW_HW_1     0x840  [ SSE  MMX ]

Relocatable objects can contain hardware capabilities values. The link-editor combines any hardware capabilities values from multiple input relocatable objects. The resulting CA_SUNW_HW_1 value is a bitwise-inclusive OR of the associated input values. By default, these values are combined with the hardware capabilities specified by a mapfile.

The hardware capability requirements of the output file can be controlled explicitly from a mapfile by using the OVERRIDE keyword. An OVERRIDE keyword, together with a hardware capability value of 0, effectively removes any hardware capabilities requirement from the object being built.


$ elfdump -H foo.o

Hardware/Software Capabilities Section:  .SUNW_cap
     index  tag               value
       [0]  CA_SUNW_HW_1     0x840  [ SSE  MMX ]
$ cat mapfile
hwcap_1 = V0x0 OVERRIDE;
$ cc -o bar.o -r -Mmapfile foo.o
$ elfdump -H bar.o
$ 

Any hardware capability requirements defined by an object are validated by the runtime linker against the hardware capabilities that are available to the process. If any of the hardware capability requirements can not be satisfied, the object is not loaded at runtime. For example, if the SSE feature is not available to a process, ldd(1) indicates the following error.


$ ldd prog
        foo.so.1 =>      ./foo.so.1  - hardware capability unsupported: \
                         0x800 [ SSE ]
        ....

Dynamic objects that exploit different hardware capabilities can provide a flexible runtime environment using filters. See Hardware Capability Specific Shared Objects.

Identifying Software Capabilities

The software capabilities of an object identify characteristics of the software that might be important for debugging or monitoring processes. Presently, the only software capabilities that are recognized relate to frame pointer usage by the object.

Objects can indicate that their frame pointer use is known. This state is then qualified by declaring the frame pointer as being used or not.

Software capabilities flags are defined in sys/elf.h.

#define  SF1_SUNW_FPKNWN    0x001
#define  SF1_SUNW_FPUSED    0x002

These software capability requirements can be identified using the following mapfile syntax.


sfcap_1 = TOKEN | Vval [ OVERRIDE ];

The sfcap_1 declaration can be qualified with the tokens FPKNWN and FPUSED. Or, alternatively with a numeric value that represents these states.

Relocatable objects can contain software capabilities values. The link-editor combines the software capabilities values from multiple input relocatable objects. Software capabilities can also be supplied with a mapfile. By default, any mapfile values are combined with the values supplied by relocatable objects.

The software capability requirements of the output file can be controlled explicitly from a mapfile by using the OVERRIDE keyword. An OVERRIDE keyword, together with a software capability value of 0, effectively removes any software capabilities requirement from the object being built.


$ elfdump -H foo.o

Hardware/Software Capabilities Section:  .SUNW_cap
     index  tag               value
       [0]  CA_SUNW_SF_1     0x3  [ SF1_SUNW_FPKNWN  SF1_SUNW_FPUSED ]
$ cat mapfile
sfcap_1 = V0x0 OVERRIDE;
$ cc -o bar.o -r -Mmapfile foo.o
$ elfdump -H bar.o
$ 

Software Capability Frame Pointer Processing

The computation of a CA_SUNW_SF_1 value from two frame pointer input values is as follows.

Table 2–1 CA_SUNW_SF_1 Frame Pointer Flag Combination State Table

Input file 1 

Input file 2 

 

SF1_SUNW_FPKNWN SF1_SUNW_FPUSED

SF1_SUNW_FPKNWN

<unknown>

SF1_SUNW_FPKNWN SF1_SUNW_FPUSED

SF1_SUNW_FPKNWN SF1_SUNW_FPUSED

SF1_SUNW_FPKNWN

SF1_SUNW_FPKNWN SF1_SUNW_FPUSED

SF1_SUNW_FPKNWN

SF1_SUNW_FPKNWN

SF1_SUNW_FPKNWN

SF1_SUNW_FPKNWN

<unknown>

SF1_SUNW_FPKNWN SF1_SUNW_FPUSED

SF1_SUNW_FPKNWN

<unknown>

This computation is applied to each relocatable object value and mapfile value. The frame pointer software capabilities of an object are unknown if no .SUNW_cap section exists, or if the section contains no CA_SUNW_SF_1 value, or if neither the SF1_SUNW_FPKNW or SF1_SUNW_FPUSED flags are set.