Skip to main content

IAR Embedded Workbench for Arm 9.70.x

Shared object layout

In this section:

This is the ordered layout of shared objects generated by ILINK:

ELF header

ELF file header

Program headers

A sort of table of contents

.hash

Used for searching .dynsym more efficiently

.dynsym

Contains the shared object’s interface

.dynstr

Contains the dynamic names

.rel.dyn

Relocations for the global offset table (GOT)

.rel.plt

Relocations for the PLT (procedure linkage table) part of the GOT

.plt

The procedure linkage table (PLT) for external code references

.text

A regular read-only output section

.data.rel.ro

A read-write output section that contains read-only data

.dynamic

Contains various data for the dynamic linker

.got

The global offset table (GOT)

.data

A regular initialized data output section

.bss

A regular zero-initialized data output section

.uninit

A regular uninitialized output section

ELF header

A regular standards-compliant ELF file header. It always consists of the first bytes in the file, and it is not a section. This header is downloaded to the target processor because the dynamic linker needs it.

Program headers

The program headers are part of all executable and shared ELF files, and they are not a section. They are downloaded to the target processor because the dynamic linker needs them.

There are typically three program headers:

  • One header for read-only content (code and constants)

  • One header for read/write content (initialized and zero-initialized)

  • One header for the .dynamic section

The .dynamic section is a part of the read/write segment. It is a separate entry so that a dynamic linker can find it fast.

There are other segment types, but the IAR implementation only supports two: load (ROM/RAM) and dynamic.

.hash

An ELF section in the shared object. It is downloaded to the target processor because the dynamic linker needs it. It is used for more efficient searching for symbols in the .dynsym section. .hash is a standard ELF hash section and should work with all standards-compliant dynamic linkers.

.dynsym

An ELF section in the shared object. It is downloaded to the target processor because the dynamic linker needs it. It is used for keeping track of the interface of the shared object, symbols that it needs (externals) and symbols that it exports (globals). .dynsym is a standard ELF symbol table section.

.dynstr

An ELF section in the shared object. It is downloaded to the target processor because the dynamic linker needs it. It contains all the dynamic names in the shared object (names in ELF are indices into a string table). .dynstr is a standard ELF string table section.

.rel.dyn

An ELF section in the shared object. It is downloaded to the target processor because the dynamic linker needs it. It contains the relocation directives that the dynamic linker needs to perform eager loading of GOT entries. .rel.dyn is a standard ELF relocation section.

See also Loading and unloading a shared object.

.rel.plt

An ELF section in the shared object. It is downloaded to the target processor because the dynamic linker needs it. It contains the relocation directives that the dynamic linker needs to perform lazy loading of PLT entries in the GOT. .rel.plt is a standard ELF relocation section.

See also Loading and unloading a shared object.

.plt

An ELF section in the shared object. It is downloaded to the target processor because the code transfers control to this section when external code is accessed by the shared object. All external code symbols have their own PLT entry. The PLT entry fetches the address of the external symbol from the GOT and transfers control to that address. The call/jump in the .text section is redirected to the corresponding PLT entry. .plt is a standard ELF SHT_PROGBITS section.

.text

An ELF section in the shared object. This section typically contains the shared object's code and constants, and is downloaded to the target processor. .text is a standard ELF SHT_PROGBITS section.

.data.rel.ro

An ELF section in the shared object.

Constant pointers to data—in either RAM or ROM—must be relocated. To make relocation possible, the compiler generates the constant pointers in this writable ELF section (but only when --shared has been specified—modules with pointers that are not shared can always be relocated at link time because the final address is known).

Because the pointers themselves are const they cannot be modified at runtime, but must be relocated at load time. In many cases, but not always, you can avoid load-time relocation by using relative references or the global offset table (GOT).

In a shared linking operation, the linker will preserve the relocations of .data.rel.ro sections and make sure that they are resolved when the shared object is loaded. The relocations will be generated in the .rel.dyn section (to ensure that they are always resolved—they cannot be lazy, see Loading and unloading a shared object).

Note

Because the .data.rel.ro section is writable, any constants it holds can be modified at runtime. For that reason, you should if possible write-protect it using the MMU (if such a mechanism is available).

.data.rel.ro is a standard ELF SHT_PROGBITS section.

.dynamic

An ELF section in the shared object. It is downloaded to the target processor because the dynamic linker needs it. It contains information that the dynamic linker needs to access the shared object—where the GOT is located and what kind of relocations that are used. .dynamic is a standard ELF dynamic section.

The shared objects generated by ILINK use the standard ELF DT tags, and some GCC extensions.

.got

An ELF section in the shared object. It is downloaded to the target processor because the dynamic linker needs it. It is accessed every time data or external code is accessed. The GOT is stored here—basically an array of addresses. The dynamic linker writes addresses into the GOT, and all accesses use those addresses. .got is a standard ELF SHT_PROGBITS section.

.data

An ELF section in the shared object. This section typically contains the shared object’s initialized data, and is downloaded to the target processor. (The dynamic linker is responsible for initializing the content.) .data is a standard ELF SHT_PROGBITS section.

.bss

An ELF section in the shared object. This section contains the shared object’s zero-initialized data, and is downloaded to the target processor. (The dynamic linker is responsible for zero-initializing the content.) .bss is a standard ELF SHT_NOBITS section.

.uninit

An ELF section in the shared object. This section contains the shared object’s uninitialized data. It is not a part of any segment—its addresses are not covered in a program header, see Program headers—so the bytes of the .uninit section are not touched by the dynamic linker. This means that this uninitialized section contains undefined bytes, which is potentially hazardous—it is the responsibility of your application to manage this safely. .uninit is a standard ELF SHT_NOBITS section that is a treated in a non-standard way—writable content is typically initialized or zero-initialized.

Sample contents listing

This is a sample listing of (dump) the contents of a shared object, created using ielfdumparm:

32-bit little-endian shared object ELF file for Advanced RISC Machines ARM

  File version 1, header size 52, section header string section #28.
  Flags 0x500'0000 (ARM ELF revision 5 [AAELF 2.0])
  Entry 0x0

   3 program headers, each 32 bytes, at offset   0x34
  29 section headers, each 40 bytes, at offset 0x10ec
SEGMENTS:

   Type    Offset Virtual Physical File Sz Mem Sz Flags   Align
   ‑‑‑‑    ‑‑‑‑‑‑ ‑‑‑‑‑‑- ‑‑‑‑‑‑‑‑ ‑‑‑‑‑‑- ‑‑‑‑‑‑ ‑‑‑‑-   ‑‑‑‑-
0: load       0x0     0x0      0x0   0x1c4  0x1c4 0x5 X R 0x1000
1: load     0x1c4  0x11c4   0x11c4    0x88   0x90 0x6  WR 0x1000
2: dynamic  0x1c4  0x11c4   0x11c4    0x68   0x68 0x6  WR    0x4
SECTIONS:

    Name             Type       Addr Offset  Size Aln Lnk Inf ESz Flags
    ‑‑‑‑             ‑‑‑‑       ‑‑‑‑ ‑‑‑‑‑‑  ‑‑‑‑ ‑‑- ‑‑- ‑‑- ‑‑- ‑‑‑‑-
 1: .hash            hash       0x94   0x94  0x2c 0x4   2       4 0x2  A
 2: .dynsym          dynsym     0xc0   0xc0  0x70 0x4   3   3  16 0x2  A
 3: .dynstr          strtab    0x130  0x130  0x13 0x4             0x2  A
 4: .rel.dyn         rel       0x144  0x144  0x18 0x4   2   9   8 0x2  A
 5: .rel.plt         rel       0x15c  0x15c   0x8 0x4   2   9   8 0x2  A
 6: .plt             pbits     0x164  0x164  0x20 0x4           4 0x6  AX
 7: .text            pbits     0x184  0x184  0x3e 0x4           1 0x6  AX
 8: .dynamic         dyn      0x11c4  0x1c4  0x68 0x4   3       8 0x3 WA
 9: .got             pbits    0x122c  0x22c  0x1c 0x4           4 0x3 WA
10: .data            pbits    0x1248  0x248   0x4 0x4           1 0x3 WA
11: .bss             nobits   0x124c  0x24c   0x8 0x4           1 0x3 WA
12: .noinit          nobits   0x1254  0x24c   0x8 0x4           1 0x3 WA
13: .debug_abbrev    pbits            0x24c  0x81               1
14: .debug_aranges   pbits            0x2d0  0x40               1
15: .debug_frame     pbits            0x310  0x55               1
16: .debug_info      pbits            0x368 0x4b6               1
17: .debug_line      pbits            0x820  0xd9               1
18: .debug_loc       pbits            0x8fc  0x34               1
19: .debug_macinfo   pbits            0x930   0x5               1
20: .debug_pubnames  pbits            0x938  0x7e               1
21: .iar.debug_frame pbits            0x9b8  0x24               1
22: .iar.debug_line  pbits            0x9dc  0xb8               1
23: .comment         pbits            0xa94 0x184               1
24: .iar.rtmodel     pbits            0xc18  0x25               1
25: .ARM.attributes  arm_attr         0xc40  0x2c               1
26: .symtab          symtab           0xc6c 0x240 0x4  27  20  16
27: .strtab          strtab           0xeac 0x11a 0x4
28: .shstrtab        strtab           0xfc8 0x122 0x4

Note

Note the following:

  • There are three segments here: a ROM segment (no W flag), a RAM segment (a W flag) and a dynamic segment. The dynamic segment (the .dynamic section) resides inside the RAM segment, but that is not a problem.

  • The first writable section—the first section with the W flag set (typically .dynamic or .data.rel.so)—is the first section to have the alignment of the load segments—so_alignment, 0x1000 in this file—added to its offset. See so_alignment directive.

  • The address of all ROM sections is the same as the offset, and the address of all pbits RAM sections is the offset + so_alignment. (The nobits RAM sections have no bytes in the file, so their address is not necessarily equal to offset + so_alignment.)

Sections without the A flag (for Alloc) set are not downloaded to the target. They contain supplementary information (like debug information) that is not needed during execution.