Shared object layout
This is the ordered layout of shared objects generated by ILINK:
ELF header | ELF file header |
Program headers | A sort of table of contents |
| Used for searching |
| Contains the shared object’s interface |
| Contains the dynamic names |
| Relocations for the global offset table (GOT) |
| Relocations for the PLT (procedure linkage table) part of the GOT |
| The procedure linkage table (PLT) for external code references |
| A regular read-only output section |
| A read-write output section that contains read-only data |
| Contains various data for the dynamic linker |
| The global offset table (GOT) |
| A regular initialized data output section |
| A regular zero-initialized data output section |
| 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
.dynamicsection
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 0x4Note
Note the following:
There are three segments here: a ROM segment (no
Wflag), a RAM segment (aWflag) and a dynamic segment. The dynamic segment (the.dynamicsection) resides inside the RAM segment, but that is not a problem.The first writable section—the first section with the
Wflag set (typically.dynamicor.data.rel.so)—is the first section to have the alignment of the load segments—so_alignment,0x1000in 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
pbitsRAM sections is the offset +so_alignment. (ThenobitsRAM 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.