ELF adds additional assembler directives to
define weak symbols (WEAK
), set symbol size (SIZE
), and indicate whether a symbol is specifically a function or an
object (TYPE
). ELF also adds a directive to assist in
identifying the source file or version, IDENT
.
The IDENT
directive allows adding arbitrary string data to an ELF object
file that will be saved in the object and executable file, but will not be loaded into
memory like data in the .data
section. It is often used for
saving version control
keyword information from tools such as cvs
or svn into files so that the source
revision the object was created with can be read using the ident command found on most Unix systems.
The directive takes one or more string parameters. Each parameter is saved in sequence
as a 0-terminated string in the .comment
section of the object file.
Multiple uses of the IDENT
directive are legal, and the
strings will be saved into the .comment
section in the order
given in the source file.
In NASM syntax, no wrapper macro is provided for IDENT
,
so it must be wrapped in square brackets. Example use in NASM syntax:
[ident "$Id$"]
ELF’s symbol table has the capability of storing a
size for a symbol. This is commonly used for functions or data objects. While the size
can be specificed directly for COMMON
symbols, the SIZE
directive allows for specifying the size of any symbol, including local symbols.
The directive takes two parameters; the first parameter is the symbol name, and the second is the size. The size may be a constant or an expression. Example:
func: ret .end: size func func.end-func
ELF’s symbol table has the capability of indicating
whether a symbol is a function or data. While this can be specified directly in the
GLOBAL
directive (see Section 9.4), the TYPE
directive allows specifying the symbol type for any symbol, including local symbols.
The directive takes two parameters; the first parameter is the symbol name, and the
second is the symbol type. The symbol type must be either function
or object
.
An unrecognized type will cause a warning to be generated. Example of use:
func: ret type func function section .data var dd 4 type var object
ELF allows defining certain symbols as “weak”. Weak symbols are similar to global symbols, except during linking, weak symbols are only chosen after global and local symbols during symbol resolution. Unlike global symbols, multiple object files may declare the same weak symbol, and references to a symbol get resolved against a weak symbol only if no global or local symbols have the same name.
This functionality is primarily useful for libraries that want to provide common functions but not come into conflict with user programs. For example, libc has a syscall (function) called “read”. However, to implement a threaded process using POSIX threads in user-space, libpthread needs to supply a function also called “read” that provides a blocking interface to the programmer, but actually does non-blocking calls to the kernel. To allow an application to be linked to both libc and libpthread (to share common code), libc needs to have its version of the syscall with a non-weak name like “_sys_read” with a weak symbol called “read”. If an application is linked against libc only, the linker won’t find a non-weak symbol for “read”, so it will use the weak one. If the same application is linked against libc and libpthread, then the linker will link “read” calls to the symbol in libpthread, ignoring the weak one in libc, regardless of library link order. If libc used a non-weak name, which “read” function the program ended up with might depend on a variety of factors; a weak symbol is a way to tell the linker that a symbol is less important resolution-wise.
The WEAK
directive takes a single parameter, the symbol
name to declare weak. Example:
weakfunc: strongfunc: ret weak weakfunc global strongfunc