Whole document tree
    

Whole document tree

Using PRC-Tools: 3.1.1 Read-only data
[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

3.1.1 Read-only data

Read-only data, such as string literals and other constant data, are put into code sections rather than the global data section. This saves global data space, which is in short supply, and is valid since the data, just like the code resources that contain them, are read-only.

When an item of read-only data has file or global scope, it will be placed in the main code section. When it is local to a function, it will mostly, but not always, be placed in the same code section as that function.

GCC's optimizer will usually notice when a string literal (or other constant) is identical to one which has been previously emitted, and will reuse the storage previously emitted rather than reserving more space for a duplicate.

Thus, in the following example, when optimisation is on, the string literal referenced from bar may well be in the foosec section, while bar itself is in the main code section:

 
const char *foo () __attribute__ ((section ("foosec")));
const char *foo () { return "hello world"; }
const char *bar () { return "hello world"; }

The code emitted for such a reference is similar to that emitted for an inter-section function call: when there is a data reference in which the referring function and the referenced item of read-only data are in different sections, the code emitted uses the item's code resource's pointer, which is located in the application's global data.

This means that you must ensure that this sort of reference doesn't occur when globals are not available. Because this compiler optimisation (of course) occurs only within a single compilation unit, a sufficient (but not necessary) way to ensure this is by placing functions which are in different sections in different compilation units (e.g., in separate `.c' files).

In particular, all read-only data referenced while processing a launch code that doesn't give you globals must be in the main code section. (Thus, in the example above, bar is likely to crash if it is called during a no-globals launch.)

This can be arranged in the following ways, amongst others:

  • Write functions used during no-globals launches so that they use read-only data with file or global scope:

     
    const char greeting[] = "hello world";
    const char *bar () { return greeting; }
    

  • Order the functions within a compilation unit so that all functions in the main code section are defined before any functions in other code sections. Then any shared read-only data will be in the main code section.

    (When an item of read-only data is reused, it will have been placed in the same section as the function from which it was first referenced. Thus, if the functions are ordered as described, all read-only data referenced from the functions in the main code section will themselves be in the main code section. Any inter-section references to read-only data must then be from functions in other named code sections. But in order for such a function to have been called, globals must be available; hence the inter-section reference will be safe too.)


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

This document was generated by root on January, 30 2002 using texi2html