Data elements that are read-only should be moved into the text segment using const declarations. For example, the following character string resides in the .data section, which is part of the writable data segment:
char * rdstr = "this is a read-only string"; |
In contrast, the following character string resides in the .rodata section, which is the read-only data section contained within the text segment:
const char * rdstr = "this is a read-only string"; |
Reducing the data segment by moving read-only elements into the text segment is admirable. However, moving data elements that require relocations can be counterproductive. For example, examine the following array of strings:
char * rdstrs[] = { "this is a read-only string", "this is another read-only string" }; |
A better definition might seem to be:
const char * const rdstrs[] = { ..... }; |
This definition ensures that the strings and the array of pointers to these strings are placed in a .rodata section. Unfortunately, although the user perceives the array of addresses as read-only, these addresses must be relocated at runtime. This definition therefore results in the creation of text relocations. Representing it as:
const char * rdstrs[] = { ..... }; |
insures the array pointers are maintained in the writable data segment where they can be relocated. The array strings are maintained in the read-only text segment.
Some compilers, when generating position-independent code, can detect read-only assignments that result in runtime relocations. These compilers arrange for placing such items in writable segments (for example, .picdata).