Previous: Output Section Attributes, Up: SECTIONS


3.6.9 Overlay Description

An overlay description provides an easy way to describe sections which are to be loaded as part of a single memory image but are to be run at the same memory address. At run time, some sort of overlay manager will copy the overlaid sections in and out of the runtime memory address as required, perhaps by simply manipulating addressing bits. This approach can be useful, for example, when a certain region of memory is faster than another.

Overlays are described using the OVERLAY command. The OVERLAY command is used within a SECTIONS command, like an output section description. The full syntax of the OVERLAY command is as follows:

     OVERLAY [start] : [NOCROSSREFS] [AT ( ldaddr )]
       {
         secname1
           {
             output-section-command
             output-section-command
             ...
           } [:phdr...] [=fill]
         secname2
           {
             output-section-command
             output-section-command
             ...
           } [:phdr...] [=fill]
         ...
       } [>region] [:phdr...] [=fill] [,]

Everything is optional except OVERLAY (a keyword), and each section must have a name (secname1 and secname2 above). The section definitions within the OVERLAY construct are identical to those within the general SECTIONS construct (see SECTIONS), except that no addresses and no memory regions may be defined for sections within an OVERLAY.

The comma at the end may be required if a fill is used and the next sections-command looks like a continuation of the expression.

The sections are all defined with the same starting address. The load addresses of the sections are arranged such that they are consecutive in memory starting at the load address used for the OVERLAY as a whole (as with normal section definitions, the load address is optional, and defaults to the start address; the start address is also optional, and defaults to the current value of the location counter).

If the NOCROSSREFS keyword is used, and there are any references among the sections, the linker will report an error. Since the sections all run at the same address, it normally does not make sense for one section to refer directly to another. See NOCROSSREFS.

For each section within the OVERLAY, the linker automatically provides two symbols. The symbol __load_start_secname is defined as the starting load address of the section. The symbol __load_stop_secname is defined as the final load address of the section. Any characters within secname which are not legal within C identifiers are removed. C (or assembler) code may use these symbols to move the overlaid sections around as necessary.

At the end of the overlay, the value of the location counter is set to the start address of the overlay plus the size of the largest section.

Here is an example. Remember that this would appear inside a SECTIONS construct.

       OVERLAY 0x1000 : AT (0x4000)
        {
          .text0 { o1/*.o(.text) }
          .text1 { o2/*.o(.text) }
        }

This will define both `.text0' and `.text1' to start at address 0x1000. `.text0' will be loaded at address 0x4000, and `.text1' will be loaded immediately after `.text0'. The following symbols will be defined if referenced: __load_start_text0, __load_stop_text0, __load_start_text1, __load_stop_text1.

C code to copy overlay .text1 into the overlay area might look like the following.

       extern char __load_start_text1, __load_stop_text1;
       memcpy ((char *) 0x1000, &__load_start_text1,
               &__load_stop_text1 - &__load_start_text1);

Note that the OVERLAY command is just syntactic sugar, since everything it does can be done using the more basic commands. The above example could have been written identically as follows.

       .text0 0x1000 : AT (0x4000) { o1/*.o(.text) }
       PROVIDE (__load_start_text0 = LOADADDR (.text0));
       PROVIDE (__load_stop_text0 = LOADADDR (.text0) + SIZEOF (.text0));
       .text1 0x1000 : AT (0x4000 + SIZEOF (.text0)) { o2/*.o(.text) }
       PROVIDE (__load_start_text1 = LOADADDR (.text1));
       PROVIDE (__load_stop_text1 = LOADADDR (.text1) + SIZEOF (.text1));
       . = 0x1000 + MAX (SIZEOF (.text0), SIZEOF (.text1));