Chapter 1 discusses the idea that embedded systems typically have some form of ROM for non-volatile storage and that the software for an embedded system can be stored in ROM. Modifiable data must reside in RAM. Programs that require fast execution speed also execute out of RAM. Commonly therefore, a small program in ROM, called a loader, copies the initialized variables into RAM, transfers the program code into RAM, and begins program execution out of RAM. This physical ROM storage address is referred to as the section's load address. The section's run address refers to the location where the section is at the time of execution. For example, if a section is copied into RAM for execution, the section's run address refers to an address in RAM, which is the destination address of the loader copy operation. The linker uses the program's run address for symbol resolutions.
The ELF
file format has two different interpretations, as shown in Figure 2.4. The linker interprets the file as a linkable module described by the section header table, while the loader interprets the file as an executable module described by the program header table.
Figure 2.4: Executable and linking format.
Listing 2.1 shows both the section header and the program header, as represented in C programming structures. We describe the relevant fields during the course of this discussion.
Listing 2.1: Section header and program header.
Elf32_Word sh_name;
Elf32_Word sh_type;
Elf32_Word sh_flags;
Elf32_Addr sh_addr;
Elf32_Off sh_offset;
Elf32_Word sh_size;
Elf32_Word sh_link;
Elf32_Word sh_info;
Elf32_Word sh_addralign;
Elf32_Word sh_entsize;
} Elf32_Shdr;
Elf32_Word p_type;
Elf32_Off p_offset;
Elf32_Addr p_vaddr;
Elf32_Addr p_paddr;
Elf32_Word p_filesz;
Elf32_Word p_memsz;
Elf32_Word p_flags;
Elf32_Word p_align;
} Elf32_Phdr;
A section header table is an array of section header structures describing the sections of an object file. A program header table is an array of program header structures describing a loadable segment of an image that allows the loader to prepare the image for execution. Program headers are applied only to executable images and shared object files..
Table 2.1: Section types.
| NULL | Inactive header without a section. |
| PROGBITS | Code or initialized data. |
| SYMTAB | Symbol table for static linking. |
| STRTAB | String table. |
| RELA/REL | Relocation entries. |
| HASH | Run-time symbol hash table. |
| DYNAMIC | Information used for dynamic linking. |
| NOBITS | Uninitialized data. |
| DYNSYM | Symbol table for dynamic linking. |
The sh_flags field in the section header specifies the attribute of a section. Table 2.2 lists some of these attributes.
Table 2.2: Section attributes.
| WRITE | Section contains writeable data. |
| ALLOC | Section contains allocated data. |
| EXECINSTR | Section contains executable instructions. |
Other common system-defined sections are.symtab containing the symbol table,.strtab containing the string table for the program symbols,.shstrtab containing the string table for the section names, and.relaname containing the relocation information for the section named name . We have discussed the role of the symbol table (SYMTAB) previously. In Figure 2.3, the symbol name is shown as part of the symbol table. In practice, each entry in the symbol table contains a reference to the string table (STRTAB) where the character representation of the name is stored.
The developer can define custom sections by invoking the linker command.section. For example, where the source files states
.section my_section
the linker creates a new section called my_section. The reasons for creating custom named sections are explained shortly.
The sh_addr is the address where the program section should reside in the target memory. The p_paddr is the address where the program segment should reside in the target memory. The sh_addr and the p_paddr fields refer to the load addresses. The loader uses the load address field from the section header as the starting address for the image transfer from non-volatile memory to RAM.