// $Id: objfmt-elf32.txt 2217 2009-07-24 17:47:49Z peter $
[[objfmt-elf32]]
== `elf32`: Executable and Linkable Format 32-bit Object Files

indexterm:[`elf`,`elf32`]
indexterm:[`Linux`,`elf`]
indexterm:[Executable and Linkable Format]
indexterm:[Solaris x86]
indexterm:[UnixWare]
The Executable and Linkable Object Format is the primary object format
for many operating systems including ((FreeBSD)) or GNU/Linux. It
appears in three forms:

- Shared object files (.so)
- Relocatable object files (.o)
- Executable files (no convention)

Yasm only directly supports relocatable object files. Other tools,
such as the GNU Linker **ld**, help turn relocatable object files into
the other formats.  Yasm supports generation of both 32-bit and 64-bit
ELF files, called `elf32` and `elf64`.  A generic interface to both is
also provided, `elf`, which selects between `elf32` and `elf64` based
on the target machine architecture (see <<yasm-option-machine>>).

Yasm defaults to `BITS 32` mode when outputting to the `elf32` object
format.

[[objfmt-elf-dbgfmts]]
=== Debugging Format Support

ELF supports two debugging formats: `stabs` (see <<dbgfmt-stabs>>) and
`dwarf2` (see <<dbgfmt-dwarf2>>).  Different debuggers understand
these different formats; the newer debug format is `dwarf2`, so try
that first.

[[objfmt-elf-section]]
=== ELF Sections

indexterm:[`elf`,SECTION]
ELF's section-based output supports attributes on a per-section basis.
These attributes include `alloc`, `exec`, `write`, `progbits`, and
`align`. Except for align, they can each be negated in NASM syntax by
prepending ""no"", e.g., ""noexec"".  The attributes are later read by
the operating system to select the proper behavior for each section,
with the meanings shown in <<elf-section-attributes>>.

[[elf-section-attributes]]
.ELF Section Attributes
[cols="^,<",options="header"]
|========
|Attribute|Indicates the section

|`alloc`|
is loaded into memory at runtime. This is true for code and data
sections, and false for metadata sections.

|`exec`|has permission to be run as executable code.

|`write`|is writable at runtime.

|`progbits`|
is stored in the disk image, as opposed to allocated and initialized
at load.

|+align=?n?+|
requires a memory alignment of ?n? bytes. The value ?n? must always be
a power of 2.

|========

In NASM syntax, the attribute `nobits` is provided as an alias for
`noprogbits`.

The standard primary sections have attribute defaults according their
expected use, and any unknown section gets its own defaults, as shown
in <<elf-standard-sections>>.

[[elf-standard-sections]]
.ELF Standard Sections
[cols="<,5*^",options="header"]
|========
|Section    |`alloc`|`exec`|`write`|`progbits`|`align`
|`.bss`     | alloc |      | write |          | 4
|`.data`    | alloc |      | write | progbits | 4
|`.rodata`  | alloc |      |       | progbits | 4
|`.text`    | alloc | exec |       | progbits | 16
|`.comment` |       |      |       | progbits | 0
|unknown    | alloc |      |       | progbits | 1
|========

[[objfmt-elf-directives]]
=== ELF Directives

indexterm:[`elf`,directives]
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`.

[[objfmt-elf-dir-ident]]
==== `IDENT`: Add file identification

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:

[source]
----
[ident "$Id: objfmt-elf32.txt 2217 2009-07-24 17:47:49Z peter $"]
----

[[objfmt-elf-dir-size]]
==== `SIZE`: Set symbol size

indexterm:[`elf`,symbol size]
indexterm:[size,of symbols]
indexterm:[symbol sizes,specifying]
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:

[source]
----
func:
        ret
.end:
size func func.end-func
----

[[objfmt-elf-dir-type]]
==== `TYPE`: Set symbol type

indexterm:[`elf`,symbol type]
indexterm:[type,of symbols]
indexterm:[symbol types,specifying]
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 <<objfmt-elf-dir-global>>), 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:

[source]
----
func:
        ret
type func function
section .data
var dd 4
type var object
----

[[objfmt-elf-dir-weak]]
==== `WEAK`: Create weak symbol

indexterm:[`WEAK`]
indexterm:[`elf`,weak reference]
indexterm:[weak reference]
indexterm:[library]
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:

[source]
----
weakfunc:
strongfunc:
        ret
weak weakfunc
global strongfunc
----

[[objfmt-elf-dir-global]]
=== ELF Extensions to the `GLOBAL` Directive

indexterm:[symbol sizes,specifying]
indexterm:[size,of symbols]
indexterm:[symbol types,specifying]
indexterm:[type,of symbols]
ELF object files can contain more information about a global symbol
than just its address: they can contain the size of the symbol and its
type as well.  These are not merely debugger conveniences, but are
actually necessary when the program being written is a ((shared
library)).  Yasm therefore supports some extensions to the NASM syntax
((`GLOBAL`)) directive (see <<nasm-directive-global>>), allowing you
to specify these features.  Yasm also provides the ELF-specific
directives in <<objfmt-elf-directives>> to allow specifying this
information for non-global symbols.

You can specify whether a global variable is a function or a data
object by suffixing the name with a colon and the word ((`function`))
or ((`data`)).  (((`object`)) is a synonym for `data`.) For example:

[source]
----
global   hashlookup:function, hashtable:data
----

exports the global symbol `hashlookup` as a function and `hashtable`
as a data object.

Optionally, you can control the ELF visibility of the symbol.  Just
add one of the visibility keywords: ((`default`)), ((`internal`)),
((`hidden`)), or ((`protected`)).  The default is `default`, of
course.  For example, to make `hashlookup` hidden:

[source]
----
global   hashlookup:function hidden
----

You can also specify the size of the data associated with the symbol,
as a numeric expression (which may involve labels, and even forward
references) after the type specifier. Like this:

[source]
----
global  hashtable:data (hashtable.end - hashtable)

hashtable:
        db this,that,theother  ; some data here
.end:
----

This makes Yasm automatically calculate the length of the table and
place that information into the ELF symbol table.  The same
information can be given more verbosely using the `TYPE` (see
<<objfmt-elf-dir-type>>) and `SIZE` (see <<objfmt-elf-dir-size>>)
directives as follows:

[source]
----
global  hashtable
type hashtable object
size hashtable hashtable.end - hashtable

hashtable:
        db this,that,theother  ; some data here
.end:
----

Declaring the type and size of global symbols is necessary when
writing shared library code.

[[objfmt-elf-dir-common]]
=== ELF Extensions to the `COMMON` Directive

indexterm:[common variables,alignment in elf]
indexterm:[alignment,of common variables]
ELF also allows you to specify alignment requirements on common
variables. This is done by putting a number (which must be a power of
two) after the name and size of the common variable, separated (as
usual) by a colon. For example, an array of doublewords would benefit
from 4-byte alignment:

[source]
----
common  dwordarray 128:4
----

This declares the total size of the array to be 128 bytes, and
requires that it be aligned on a 4-byte boundary.

[[objfmt-elf32-wrt]]
=== `elf32` Special Symbols and `WRT`

indexterm:[Position-Independent Code]
indexterm:[ELF,32-bit shared libraries]
indexterm:[relocations,PIC-specific]
The ELF specification contains enough features to allow
position-independent code (PIC) to be written, which makes ELF shared
libraries very flexible. However, it also means Yasm has to be able to
generate a variety of strange relocation types in ELF object files, if
it is to be an assembler which can write ((PIC)).

Since ELF does not support segment-base references, the ((`WRT`))
operator is not used for its normal purpose; therefore Yasm's `elf32`
output format makes use of `WRT` for a different purpose, namely the
PIC-specific relocation types.

`elf32` defines five special symbols which you can use as the
right-hand side of the `WRT` operator to obtain PIC relocation types.
They are ((`..gotpc`)), ((`..gotoff`)), ((`..got`)), ((`..plt`)) and
((`..sym`)). Their functions are summarized here:

`..gotpc`::
  Referring to the symbol marking the ((global offset table)) base
  using `wrt ..gotpc` will end up giving the distance from the
  beginning of the current section to the global offset table.
  (((`_GLOBAL_OFFSET_TABLE_`)) is the standard symbol name used to
  refer to the ((GOT)).) So you would then need to add
  ((+++<literal>$$</literal>+++)) to the result to get the real
  address of the GOT.

`..gotoff`::
  Referring to a location in one of your own sections using `wrt
  ..gotoff` will give the distance from the beginning of the GOT to
  the specified location, so that adding on the address of the GOT
  would give the real address of the location you wanted.

`..got`::
  Referring to an external or global symbol using `wrt ..got` causes
  the linker to build an entry _in_ the GOT containing the address of
  the symbol, and the reference gives the distance from the beginning
  of the GOT to the entry; so you can add on the address of the GOT,
  load from the resulting address, and end up with the address of the
  symbol.

`..plt`::
  Referring to a procedure name using `wrt ..plt` causes the linker to
  build a ((procedure linkage table)) entry for the symbol, and the
  reference gives the address of the ((PLT)) entry.  You can only use
  this in contexts which would generate a PC-relative relocation
  normally (i.e. as the destination for `CALL` or `JMP`), since ELF
  contains no relocation type to refer to PLT entries absolutely.

`..sym`::
  Referring to a symbol name using `wrt ..sym` causes Yasm to write an
  ordinary relocation, but instead of making the relocation relative
  to the start of the section and then adding on the offset to the
  symbol, it will write a relocation record aimed directly at the
  symbol in question.  The distinction is a necessary one due to a
  peculiarity of the dynamic linker.

// vim: set syntax=asciidoc sw=2 tw=70:
