10.5.11. Creating and Filling Holes

The linker provides you with the ability to create areas within output sections that have nothing linked into them. These areas are called holes. In special cases, uninitialized sections can also be treated as holes. This section describes how the linker handles holes and how you can fill holes (and uninitialized sections) with values.

10.5.11.1. Initialized and Uninitialized Sections

There are two rules to remember about the contents of output sections. An output section contains either:

  • Raw data for the entire section

  • No raw data

A section that has raw data is referred to as initialized. This means that the object file contains the actual memory image contents of the section. When the section is loaded, this image is loaded into memory at the section’s specified starting address. The .text and .data sections always have raw data if anything was assembled into them. Named sections defined with the .sect assembler directive also have raw data.

By default, the .bss section (see Uninitialized Sections) and sections defined with the .usect directive (see User-Named Sections) have no raw data (they are uninitialized). They occupy space in the memory map but have no actual contents. Uninitialized sections typically reserve space in fast external memory for variables. In the object file, an uninitialized section has a normal section header and can have symbols defined in it; no memory image, however, is stored in the section.

10.5.11.2. Creating Holes

You can create a hole in an initialized output section. A hole is created when you force the linker to leave extra space between input sections within an output section. When such a hole is created, the linker must supply raw data for the hole.

Holes can be created only within output sections. Space can exist between output sections, but such space is not a hole. To fill the space between output sections, see MEMORY Directive Syntax.

To create a hole in an output section, you must use a special type of linker assignment statement within an output section definition. The assignment statement modifies the SPC (denoted by .) by adding to it assigning a greater value to it, or aligning it on an address boundary. The operators, expressions, an syntaxes of assignment statements are described in Assigning Symbols at Link Time.

The following example uses assignment statements to create holes in output sections:

SECTIONS
{
    outsect:
    {
        file1.c.o(.text)
        . += 0x0100      /* Create a hole with size 0x0100 */
        file2.c.o(.text)
        . = align(16);       /* Create a hole to align the SPC */
        file3.c.o(.text)
    }
}

The output section outsect is built as follows:

  1. The .text section from file1.c.o is linked in.

  2. The linker creates a 256-byte hole.

  3. The .text section from file2.c.o is linked in after the hole.

  4. The linker creates another hole by aligning the SPC on a 16-byte boundary.

  5. Finally, the .text section from file3.c.o is linked in.

All values assigned to the . symbol within a section refer to the relative address within the section. The linker handles assignments to the . symbol as if the section started at address 0 (even if you have specified a binding address). Consider the statement . = align(16) in the example. This statement effectively aligns the file3.c.o .text section to start on a 16-byte boundary within outsect. If outsect is ultimately allocated to start on an address that is not aligned, the file3.c.o .text section will not be aligned either.

The . symbol refers to the current run address, not the current load address, of the section.

Expressions that decrement the . symbol are illegal. For example, it is invalid to use the -= operator in an assignment to the . symbol. The most common operators used in assignments to the . symbol are += and align.

If an output section contains all input sections of a certain type (such as .text), you can use the following statements to create a hole at the beginning or end of the output section.

.text:   {  .+= 0x0100; }     /* Hole at the beginning */
.data:   {  *(.data)
            . += 0x0100; }    /* Hole at the end       */

Another way to create a hole in an output section is to combine an uninitialized section with an initialized section to form a single output section. In this case, the linker treats the uninitialized section as a hole and supplies data for it. The following example illustrates this method:

SECTIONS
{
    outsect:
    {
        file1.c.o(.text)
        file1.c.o(.bss)       /* This becomes a hole */
    }
}

Because the .text section has raw data, all of outsect must also contain raw data. Therefore, the uninitialized .bss section becomes a hole.

Uninitialized sections become holes only when they are combined with initialized sections. If several uninitialized sections are linked together, the resulting output section is also uninitialized.

10.5.11.3. Filling Holes

When a hole exists in an initialized output section, the linker must supply raw data to fill it. The linker fills holes with a 32-bit fill value that is replicated through memory until it fills the hole. The linker determines the fill value as follows:

  1. If the hole is formed by combining an uninitialized section with an initialized section, you can specify a fill value for the uninitialized section. Follow the section name with an = sign and a 32-bit constant. For example:

SECTIONS
    { outsect:
        {
            file1.c.o(.text)
            file2.c.o(.bss)= 0xFF00FF00  /* Fill this hole with 0xFF00FF00 */
        }
    }
  1. You can also specify a fill value for all the holes in an output section by supplying the fill value after the section definition:

SECTIONS
{ outsect:fill = 0xFF00FF00 /* Fills holes with 0xFF00FF00 */
    {
        . += 0x0010;        /* This creates a hole */
        file1.c.o(.text)
        file1.c.o(.bss)     /* This creates another hole */
    }
}
  1. If you do not specify an initialization value for a hole, the linker fills the hole with the value specified with the --fill_value option (see Set Default Fill Value (--fill_value Option)). For example, suppose the command file link.cmd contains the following SECTIONS directive:

    SECTIONS { .text: { .= 0x0100; } /* Create a 100 word hole */ }
    

    Now invoke the linker with the --fill_value option:

    tiarmclang -Wl,--fill_value=0xFFFFFFFF link.cmd
    

    This fills the hole with 0xFFFFFFFF.

  2. If you do not invoke the linker with the --fill_value option or otherwise specify a fill value, the linker fills holes with 0s.

Whenever a hole is created and filled in an initialized output section, the hole is identified in the link map along with the value the linker uses to fill it.

10.5.11.4. Explicit Initialization of Uninitialized Sections

You can force the linker to initialize an uninitialized section by specifying an explicit fill value for it in the SECTIONS directive. This causes the entire section to have raw data (the fill value). For example:

SECTIONS
{
    .bss: fill = 0x12341234 /* Fills .bss with 0x12341234 */
}

Note

Filling Sections

Because filling a section (even with 0s) causes raw data to be generated for the entire section in the output file, your output file will be very large if you specify fill values for large sections or holes.