17. Section reference¶
Compiler-generated code and data objects are organized into sections within the object file. Understanding these sections is crucial for writing linker placement files and interpreting compiler and linker list files.
17.1. Section overview¶
Code and data objects occupy space in target memory, either as program-bits (actual data written to memory) or no-bits (sections represented only by their size in the ELF object file).
The Calypsi C compiler tool chain has adapted names that trace back to the origins to the early days of computing. These may not always be the best possible names, but they are widely known and familiar to many.
Sections are broadly categorized into three groups: text, data, and bss. Text sections are read-only program-bits. Data sections are read-write program-bits. BSS sections are read-write no-bits.
Note
If you ever wondered about what bss section stands for, it originally is block started by symbol, a pseudo operation in an assembler for IBM 704 from the mid fifties. Some people suggest it is easier to remember as better save space, as it is a way to save space in the output file by just storing the size of the section without any explicit data bits.
Section names¶
Each section has a name, and multiple section fragments can share the same name. Section names serve two purposes:
To provide a descriptive identifier for the section.
To control memory placement through rules that reference these names.
Section types¶
Each section has a type: text, data, or bss. For embedded systems, rodata (read-only data) and no-init sections are also available. Read-only data sections are similar to text sections but identify data rather than executable code. No-init sections resemble bss but lack the memory-clearing mechanism.
Data sections¶
From the compiler’s perspective, data sections are read-write program-bits sections, meaning they have initializer values that reside in memory. In a hosted environment, such sections are loaded into memory before program execution. This approach is unsuitable for programs stored in flash memory where execution is expected to begin immediately upon power-on.
To address this, the linker clones data sections. The initializers for
the original data section are moved and placed in the clone. The clone
has a section name with an “i” prepended (e.g., idata for
data) and is intended for flash (read-only) memory.
To initialize data sections on power-on, a copy routine is inserted
before the main() function. This routine copies initializers from
flash to RAM, initializing data memory and clearing bss sections.
The linker generates a data-init_table describing data to be copied and cleared.
Note
For some targets, the Calypsi C compiler tool chain can cross-compile executables for OS loading.
The --hosted option prevents data section cloning, avoiding duplication.
However, the table-driven initializer is still needed for BSS sections in
such environments.
17.2. Sections used by the compiler¶
The following sections are sections used by the Calypsi C compiler tool chain.
Section name |
Type |
Memory kind |
Description |
|---|---|---|---|
|
text |
ROM |
Executable code |
|
bss |
RAM |
Zero-initialized (bss) data |
|
data |
RAM |
Initialized data |
|
rodata |
ROM |
Constant data |
|
bss |
RAM |
Zero-initialized (bss) zero page data |
|
data |
RAM |
Initialized zero page data |
|
rodata |
ROM |
Switch tables |
|
rodata |
ROM |
Data initializers for
|
|
rodata |
ROM |
Data initializers for
|
|
rodata |
ROM |
Data initializer table |
|
noinit |
RAM |
Pseudo registers in zero page |
|
text |
ROM |
Reset vector, when used |
|
noinit |
RAM |
Heap memory, for
|
|
noinit |
RAM |
CPU stack, always in page 1 on the 6502 |
|
noinit |
RAM |
C stack, simulated stack, anywhere in memory |
|
noinit |
RAM |
Commodore targets, save
area for |
|
bss |
RAM |
Zero-initialized (bss) far data, MEGA65 only |
|
data |
RAM |
Initialized far data, and MEGA65 only |
|
rodata |
ROM |
Constant far data, MEGA65 only |
|
rodata |
ROM |
Data initializers for
|
|
bss |
RAM |
Zero-initialized (bss) huge data, MEGA65 only |
|
data |
RAM |
Initialized huge data, MEGA65 only |
|
rodata |
ROM |
Constant huge data, MEGA65 only |
|
rodata |
ROM |
Data initializers for
|
The sections izpage, idata, ifar, ihuge, and data_init_table
in the table above are linker generated.
Note
It is assumed that no ROM exists in the zero page. Consequently,
constants placed in the zero page are placed in zpage (the normal
RAM initialized zero page section), and the const attribute only
affects the object type.
Note
The table assigns sections to ROM and RAM for ROM-based applications that start on power-up. For hosted systems loading from storage to RAM, this distinction is not applicable. Always consider ROM-marked sections as read-only.
The vector section¶
An interrupt function will have an associated vector. This is a
specially named section for the purpose of holding a single vector.
The name looks something like $$interruptVector_0xfffe. The intended
address of the vector is encoded in the section name and the linker
recognizes these and will place the vector at the address
specified. This is handled without the help of any section placement
rules.
Section reference¶
The following goes through the available sections in detail.
code¶
Holds program code for the address range 0x0000-0xffff. This section
is intended for placement in flash or ROM memory.
zdata¶
Holds zero-initialized (bss) data in main memory, address range
0x0000-0xffff.
data¶
Holds non-zero initialized data in the main memory, address range
0x0000-0xffff.
cdata¶
Holds initialized constant data in main memory, address range
0x0000-0xffff. This section is intended for placement in flash or
ROM memory.
zzpage¶
Holds zero-initialized (bss) data in the zero page, address range
0x00-0xff.
zpage¶
Holds non-zero initialized data in the zero page memory,
address range 0x00-0xff.
switch¶
Holds switch tables in main memory, address range
0x0000-0xffff. This section is intended for placement in flash or
ROM memory.
izpage¶
Holds initializers for the zpage section. The linker creates this
section by cloning the zpage section provided by the compiler. It is
placed in main memory, address range 0x0000-0xffff, and must be placed
in flash or ROM. This section is not used when linking for a hosted
system.
idata¶
Holds initializers for the data section. The linker creates this
section by cloning the data section provided by the compiler. It is
placed in main memory, address range 0x0000-0xffff, and must be placed
in flash or ROM. This section is not used when linking for a hosted
system.
data_init_table¶
The linker creates this section and populates it with information for
the C startup code, detailing how to copy and clear memory regions to
properly initialize data objects before transferring control to
main(). It is placed in main memory, address range 0x0000-0xffff,
and must reside in read-only memory, such as flash or ROM.