Go to main content

Oracle® Solaris 11.3 Linkers and Libraries Guide

Exit Print View

Updated: March 2018
 
 

Symbol Table Section

An object file's symbol table holds information needed to locate and relocate a program's symbolic definitions and symbolic references. A symbol table index is a subscript into this array. Index 0 both designates the first entry in the table and serves as the undefined symbol index. See Figure 36, Table 36, ELF Symbol Table Entry: Index 0.

A symbol table entry has the following format. See sys/elf.h.

typedef struct {
        Elf32_Word      st_name;
        Elf32_Addr      st_value;
        Elf32_Word      st_size;
        unsigned char   st_info;
        unsigned char   st_other;
        Elf32_Half      st_shndx;
} Elf32_Sym;

typedef struct {
        Elf64_Word      st_name;
        unsigned char   st_info;
        unsigned char   st_other;
        Elf64_Half      st_shndx;
        Elf64_Addr      st_value;
        Elf64_Xword     st_size;
} Elf64_Sym;
st_name

An index into the object file's symbol string table, which holds the character representations of the symbol names. If the value is nonzero, the value represents a string table index that gives the symbol name. Otherwise, the symbol table entry has no name.

st_value

The value of the associated symbol. The value can be an absolute value or an address, depending on the context. See Symbol Values.

st_size

Many symbols have associated sizes. For example, a data object's size is the number of bytes that are contained in the object. This member holds the value zero if the symbol has no size or an unknown size.

st_info

The symbol's type and binding attributes. A list of the values and meanings appears in Figure 33, Table 33, ELF Symbol Binding, ELF32_ST_BIND and ELF64_ST_BIND. The following code shows how to manipulate the values. See sys/elf.h.

#define ELF32_ST_BIND(info)          ((info) >> 4)
#define ELF32_ST_TYPE(info)          ((info) & 0xf)
#define ELF32_ST_INFO(bind, type)    (((bind)<<4)+((type)&0xf))

#define ELF64_ST_BIND(info)          ((info) >> 4)
#define ELF64_ST_TYPE(info)          ((info) & 0xf)
#define ELF64_ST_INFO(bind, type)    (((bind)<<4)+((type)&0xf))
st_other

A symbol's visibility. A list of the values and meanings appears in Figure 35, Table 35, ELF Symbol Visibility. The following code shows how to manipulate the values for both 32-bit objects and 64-bit objects. Other bits are set to zero, and have no defined meaning.

#define ELF32_ST_VISIBILITY(o)       ((o)&0x3)
#define ELF64_ST_VISIBILITY(o)       ((o)&0x3)
st_shndx

Every symbol table entry is defined in relation to some section. This member holds the relevant section header table index. Some section indexes indicate special meanings. See Figure 16, Table 16, ELF Special Section Indexes.

If this member contains SHN_XINDEX, then the actual section header index is too large to fit in this field. The actual value is contained in the associated section of type SHT_SYMTAB_SHNDX. See Extended Section Header.

A symbol's binding, determined from its st_info field, determines the linkage visibility and behavior.

Table 33  ELF Symbol Binding, ELF32_ST_BIND and ELF64_ST_BIND
Name
Value
STB_LOCAL
0
STB_GLOBAL
1
STB_WEAK
2
STB_LOOS
10
STB_HIOS
12
STB_LOPROC
13
STB_HIPROC
15
STB_LOCAL

Local symbol. These symbols are not visible outside the object file containing their definition. Local symbols of the same name can exist in multiple files without interfering with each other.

STB_GLOBAL

Global symbols. These symbols are visible to all object files being combined. One file's definition of a global symbol satisfies another file's undefined reference to the same global symbol.

STB_WEAK

Weak symbols. These symbols resemble global symbols, but their definitions have lower precedence.

STB_LOOS - STB_HIOS

Values in this inclusive range are reserved for operating system-specific semantics.

STB_LOPROC - STB_HIPROC

Values in this inclusive range are reserved for processor-specific semantics.

Global symbols and weak symbols differ in two major ways.

  • When the link-editor combines several relocatable object files, multiple definitions of STB_GLOBAL symbols with the same name are not allowed. However, if a defined global symbol exists, the appearance of a weak symbol with the same name does not cause an error. The link-editor honors the global definition and ignores the weak definitions.

    Similarly, if a common symbol exists, the appearance of a weak symbol with the same name does not cause an error. The link-editor uses the common definition and ignores the weak definition. A common symbol has the st_shndx field holding SHN_COMMON. See Symbol Resolution.

  • When the link-editor searches archive libraries, archive members that contain definitions of undefined or tentative global symbols are extracted. The member's definition can be either a global or a weak symbol.

    The link-editor, by default, does not extract archive members to resolve undefined weak symbols. Unresolved weak symbols have a zero value. The use of –z weakextract overrides this default behavior. This options enables weak references to cause the extraction of archive members.


Note -  Weak symbols are intended primarily for use in system software. Their use in application programs is discouraged.

In each symbol table, all symbols with STB_LOCAL binding precede the weak symbols and global symbols. As Section Headers describes, a symbol table section's sh_info section header member holds the symbol table index for the first non-local symbol.

A symbol's type, as determined from its st_info field, provides a general classification for the associated entity.

Table 34  ELF Symbol Types, ELF32_ST_TYPE and ELF64_ST_TYPE
Name
Value
STT_NOTYPE
0
STT_OBJECT
1
STT_FUNC
2
STT_SECTION
3
STT_FILE
4
STT_COMMON
5
STT_TLS
6
STT_LOOS
10
STT_HIOS
12
STT_LOPROC
13
STT_SPARC_REGISTER
13
STT_HIPROC
15
STT_NOTYPE

The symbol type is not specified.

STT_OBJECT

This symbol is associated with a data object, such as a variable, an array, and so forth.

STT_FUNC

This symbol is associated with a function or other executable code.

STT_SECTION

This symbol is associated with a section. Symbol table entries of this type exist primarily for relocation and normally have STB_LOCAL binding.

STT_FILE

Conventionally, the symbol's name gives the name of the source file that is associated with the object file. A file symbol has STB_LOCAL binding and a section index of SHN_ABS. This symbol, if present, precedes the other STB_LOCAL symbols for the file.

Symbol index 1 of the SHT_SYMTAB is an STT_FILE symbol representing the object file. Conventionally, this symbol is followed by the files STT_SECTION symbols. These section symbols are then followed by any global symbols that have been reduced to locals.

STT_COMMON

This symbol labels an uninitialized common block. This symbol is treated exactly the same as STT_OBJECT.

STT_TLS

The symbol specifies a thread-local storage entity. When defined, this symbol gives the assigned offset for the symbol, not the actual address.

For allocable sections, symbols of type STT_TLS can be referenced only by special thread-local storage relocations. Thread-local storage relocations can reference only symbols of type STT_TLS, or symbols of type STT_SECTION where the referenced section has the SHF_TLS flag. See Thread-Local Storage for details. A reference to a symbol of type STT_TLS from a non-allocatable section does not have this restriction.

STT_LOOS - STT_HIOS

Values in this inclusive range are reserved for operating system-specific semantics.

STT_LOPROC - STT_HIPROC

Values in this inclusive range are reserved for processor-specific semantics.

A symbol's visibility is determined from its st_other field. This visibility can be specified in a relocatable object. This visibility defines how that symbol can be accessed once the symbol has become part of a dynamic object.

Table 35  ELF Symbol Visibility
Name
Value
STV_DEFAULT
0
STV_INTERNAL
1
STV_HIDDEN
2
STV_PROTECTED
3
STV_EXPORTED
4
STV_SINGLETON
5
STV_ELIMINATE
6
STV_DEFAULT

The visibility of symbols with the STV_DEFAULT attribute is as specified by the symbol's binding type. Global symbols and weak symbols are visible outside of their defining dynamic object. Local symbols are hidden. Global symbols and weak symbols can also be preempted. These symbols can by interposed by definitions of the same name in another component.

STV_PROTECTED

A symbol that is defined in the current component is protected if the symbol is visible in other components, but cannot be preempted. Any reference to such a symbol from within the defining component must be resolved to the definition in that component. This resolution must occur, even if a symbol definition exists in another component that would interpose by the default rules. A symbol with STB_LOCAL binding will not have STV_PROTECTED visibility.

STV_HIDDEN

A symbol that is defined in the current component is hidden if its name is not visible to other components. Such a symbol is necessarily protected. This attribute is used to control the external interface of a component. An object named by such a symbol can still be referenced from another component if its address is passed outside.

A hidden symbol contained in a relocatable object is either removed or converted to STB_LOCAL binding when the object is included in a dynamic object.

STV_INTERNAL

This visibility attribute is interpreted the same as STV_HIDDEN.

STV_EXPORTED

This visibility attribute ensures that a symbol remains global. This visibility can not be demoted, or eliminated by any other symbol visibility technique. A symbol with STB_LOCAL binding will not have STV_EXPORTED visibility.

STV_SINGLETON

This visibility attribute ensures that a symbol remains global, and that a single instance of the symbol definition is bound to by all references within a process. This visibility can not be demoted, or eliminated by any other symbol visibility technique. A symbol with STB_LOCAL binding will not have STV_SINGLETON visibility. A STV_SINGLETON can not be directly bound to.

STV_ELIMINATE

This visibility attribute extends STV_HIDDEN. A symbol that is defined in the current component as eliminate is not visible to other components. The symbol is not written to any symbol table of a dynamic object from which the component is used.

The STV_SINGLETON visibility attribute can affect the resolution of symbols within an executable or shared object during link-editing. Only one instance of a singleton can be bound to from any reference within a process.

A STV_SINGLETON can be combined with a STV_DEFAULT visibility attribute, with the STV_SINGLETON taking precedence. A STV_EXPORT can be combined with a STV_DEFAULT visibility attribute, with the STV_EXPORT taking precedence. A STV_SINGLETON or STV_EXPORT visibility can not be combined with any other visibility attribute. Such an event is deemed fatal to the link-edit.

Other visibility attributes do not affect the resolution of symbols within a dynamic object during link-editing. Such resolution is controlled by the binding type. Once the link-editor has chosen its resolution, these attributes impose two requirements. Both requirements are based on the fact that references in the code being linked might have been optimized to take advantage of the attributes.

  • All of the non-default visibility attributes, when applied to a symbol reference, imply that a definition to satisfy that reference must be provided within the object being linked. If this type of symbol reference has no definition within the object being linked, then the reference must have STB_WEAK binding. In this case, the reference is resolved to zero.

  • If any reference to a name, or definition of a name is a symbol with a non-default visibility attribute, the visibility attribute is propagated to the resolving symbol in the object being linked. If different visibility attributes are specified for distinct instances of a symbol, the most constraining visibility attribute is propagated to the resolving symbol in the object being linked. The attributes, ordered from least to most constraining, are STV_PROTECTED, STV_HIDDEN and STV_INTERNAL.

If a symbol's value refers to a specific location within a section, the symbol's section index member, st_shndx, holds an index into the section header table. As the section moves during relocation, the symbol's value changes as well. References to the symbol continue to point to the same location in the program. Some special section index values give other semantics.

SHN_ABS

This symbol has an absolute value that does not change because of relocation.

SHN_COMMON, and SHN_AMD64_LCOMMON

This symbol labels a common block that has not yet been allocated. The symbol's value gives alignment constraints, similar to a section's sh_addralign member. The link-editor allocates the storage for the symbol at an address that is a multiple of st_value. The symbol's size tells how many bytes are required.

SHN_UNDEF

This section table index indicates that the symbol is undefined. When the link-editor combines this object file with another object that defines the indicated symbol, this file's references to the symbol is bound to the definition.

As mentioned previously, the symbol table entry for index 0 (STN_UNDEF) is reserved. This entry holds the values listed in the following table.

Table 36  ELF Symbol Table Entry: Index 0
Name
Value
Note
st_name
0
No name
st_value
0
Zero value
st_size
0
No size
st_info
0
No type, local binding
st_other
0
st_shndx
SHN_UNDEF
No section

Symbol Values

Symbol table entries for different object file types have slightly different interpretations for the st_value member.

  • In relocatable files, st_value holds alignment constraints for a symbol whose section index is SHN_COMMON.

  • In relocatable files, st_value holds a section offset for a defined symbol. st_value is an offset from the beginning of the section that st_shndx identifies.

  • In dynamic object files, st_value holds a virtual address. To make these files' symbols more useful for the runtime linker, the section offset (file interpretation) gives way to a virtual address (memory interpretation) for which the section number is irrelevant.

Although the symbol table values have similar meanings for different object files, the data allow efficient access by the appropriate programs.

Symbol Table Layout and Conventions

The symbols in a symbol table are written in the following order.

  • Index 0 in any symbol table is used to represent undefined symbols. This first entry in a symbol table is always completely zeroed. The symbol type is therefore STT_NOTYPE.

  • If the symbol table contains any local symbols, the second entry of the symbol table is an STT_FILE symbol giving the name of the file.

  • Section symbols of type STT_SECTION.

  • Register symbols of type STT_REGISTER.

  • Global symbols that have been reduced to local scope.

  • For each input file that supplies local symbols, a STT_FILE symbol giving the name of the input file, followed by the symbols in question.

  • The global symbols immediately follow the local symbols in the symbol table. The first global symbol is identified by the symbol table sh_info value. Local and global symbols are always kept separate in this manner, and cannot be mixed together.

Three symbol tables are of special interest in the Oracle Solaris OS.

.symtab (SHT_SYMTAB)

This symbol table contains every symbol that describes the associated ELF file. This symbol table is typically non-allocable, and is therefore not available in the memory image of the process.

Global symbols can be eliminated from the .symtab by using a mapfile together with the ELIMINATE keyword. See Symbol Elimination, and SYMBOL_SCOPE and SYMBOL_VERSION Directives.

.dynsym (SHT_DYNSYM)

This table contains a subset of the symbols from the .symtab table that are needed to support dynamic linking. This symbol table is allocable, and is therefore available in the memory image of the process.

The .dynsym table begins with the standard NULL symbol, followed by the files global symbols. STT_FILE symbols are typically not present in this symbol table. STT_SECTION symbols might be present if required by relocation entries.

.SUNW_ldynsym (SHT_SUNW_LDYNSYM)

An optional symbol table that augments the information that is found in the .dynsym table. The .SUNW_ldynsym table contains local function symbols. This symbol table is allocable, and is therefore available in the memory image of the process. This section allows debuggers to produce accurate stack traces in runtime contexts when the non-allocable .symtab is not available, or has been stripped from the file. This section also provides the runtime environment with additional symbolic information for use with dladdr(3C).

A .SUNW_ldynsym table only exists when a .dynsym table is present. When both a .SUNW_ldynsym section and a .dynsym section exist, the link-editor places their data regions directly adjacent to each other, with the .SUNW_ldynsym first. This placement allows the two tables to be viewed as a single larger contiguous symbol table. This symbol table follows the standard layout rules that were enumerated previously.

The .SUNW_ldynsym table can be eliminated by using the link-editor –z noldynsym option.

Symbol Sort Sections

The dynamic symbol table formed by the adjacent .SUNW_ldynsym section and .dynsym section can be used to map memory addresses to their corresponding symbol. This mapping can be used to determine which function or variable that a given address represents. However, analyzing the symbol tables to determine a mapping is complicated by the order in which symbols are written to symbol tables. See Symbol Table Layout and Conventions. This layout complicates associating an address to a symbol name in the follows ways.

  • Symbols are not sorted by address, which forces an expensive linear search of the entire table.

  • More than one symbol can refer to a given address. Although these symbols are valid and correct, the choice of which of these equivalent names to use by a debugging tool might not be obvious. Different tools might use different alternative names. These issues are likely to lead to user confusion.

  • Many symbols provide non-address information. These symbols should not be considered as part of such a search.

Symbol sort sections are used to solve these problems. A symbol sort section is an array of Elf32_Word or Elf64_Word objects. Each element of this array is an index into the combined .SUNW_ldynsym.dynsym symbol table. The elements of the array are sorted so that the symbols that are reference are provided in sorted order. Only symbols representing functions or variables are included. The symbols that are associated with a sort array can be displayed using elfdump(1) with the –S option.

Regular symbols and thread-local storage symbols can not be sorted together. The value of a regular symbol is the address of the function or the address of the variable the symbol references. The value of a thread-local storage symbol is the variable's thread offset. Therefore, regular symbols and thread-local storage symbols use two different sort sections.

.SUNW_dynsymsort

A section of type SHT_SUNW_SYMSORT, containing indexes to regular symbols in the combined .SUNW_ldynsym.dynsym symbol table, sorted by address. Symbols that do not represent variables or functions are not included.

.SUNW_dyntlssort

A section of type SHT_SUNW_TLSSORT, containing indexes to TLS symbols in the combined .SUNW_ldynsym.dynsym symbol table, sorted by offset. This section is only produced if the object file contains TLS symbols.

The link-editor uses the following rules, in the order that is shown, to select which symbols are referenced by the sort sections.

  • The symbol must have a function or variable type: STT_FUNC, STT_OBJECT, STT_COMMON, or STT_TLS.

  • The following symbols are always included, if present: _DYNAMIC, _end, _fini, _GLOBAL_OFFSET_TABLE_, _init, _PROCEDURE_LINKAGE_TABLE_, and _start.

  • If a global symbol and a weak symbol are found to reference the same item, the weak symbol is included and the global symbol is excluded.

  • The symbol must not be undefined.

  • The symbol must have a non-zero size.

These rules filter out automatically generated compiler and link-editor generated symbols. The symbols that are selected are of interest to the user. However, two cases exist where manual intervention might be necessary to improve the selection process.

  • The rules did not select a needed special symbol. For example, some special symbols have a zero size.

  • Unwanted extra symbols are selected. For example, shared objects can define multiple symbols that reference the same address and have the same size. These alias symbols effectively reference the same item. You might prefer to include only one of a multiple symbol family, within the sort section.

The mapfile keywords DYNSORT and NODYNSORT provide for additional control over symbol selection. See SYMBOL_SCOPE and SYMBOL_VERSION Directives.

DYNSORT

Identifies a symbol that should be included in a sort section. The symbol type must be STT_FUNC, STT_OBJECT, STT_COMMON, or STT_TLS.

NODYNSORT

Identifies a symbol that should not be included in a sort section.

For example, an object might provide the following symbol table definitions.

$ elfdump -sN.symtab foo.so.1 | egrep "foo$|bar$"
    [37]    0x4b0   0x1c  FUNC GLOB  D   0 .text      bar
    [38]    0x4b0   0x1c  FUNC WEAK  D   0 .text      foo

The symbols foo and bar represent an aliases pair. By default, when creating a sorted array, only the symbol foo is represented.

$ cc -o foo.so.1 -G foo.c
$ elfdump -S foo.so.1 | egrep "foo$|bar$"
    [13]    0x4b0   0x1c  FUNC WEAK  D   0 .text      foo

In the case where a global and a weak symbol are found by the link-editor to reference the same item, the weak symbol is normally kept. The symbol bar is omitted from the sorted array because of the association to the weak symbol foo.

The following mapfile results in the symbol bar being represented in the sorted array. The symbol foo is omitted.

$ cat mapfile
{
        global:
                bar = DYNSORT;
                foo = NODYNSORT;
};
$ cc -M mapfile -o foo.so.2 -Kpic -G foo.c
$ elfdump -S foo.so.2 | egrep "foo$|bar$"
    [13]    0x4b0   0x1c  FUNC GLOB  D   0 .text      bar

The .SUNW_dynsymsort section and .SUNW_dyntlssort section, require that a .SUNW_ldynsym section be present. Therefore, use of the –z noldynsym option also prevents the creation of any sort section.

Register Symbols

The SPARC architecture supports register symbols, which are symbols that initialize a global register. A symbol table entry for a register symbol contains the entries that are listed in the following table.

Table 37  SPARC: ELF Symbol Table Entry: Register Symbol
Field
Meaning
st_name
Index into the string table for the name of the symbol, or the value 0 for a scratch register.
st_value
Register number. See the ABI manual for integer register assignments.
st_size
Unused (0).
st_info
Bind is typically STB_GLOBAL, type must be STT_SPARC_REGISTER.
st_other
Unused (0).
st_shndx
SHN_ABS if this object initializes this register symbol,SHN_UNDEF otherwise.

The register values that are defined for SPARC are listed in the following table.

Table 38  SPARC: ELF Register Numbers
Name
Value
Meaning
STO_SPARC_REGISTER_G2
0x2
%g2
STO_SPARC_REGISTER_G3
0x3
%g3

Absence of an entry for a particular global register means that the particular global register is not used at all by the object.