When is a variable placed in the `.rdata` section, and not in the` .text` section?

I am trying to understand the consequences of the .rdata vs .text section. I am trying a simple program as shown below

 int main() { const int a = 10; printf("%d\n", a); return 0; } 

When I create and delete the map file via gcc -o a.out sample.c -Wl,Map,test.map and search for sample.o , I find the following distributions

 .text 0x0040138c 0x34 sample.o .data 0x00402000 0x0 sample.o .rdata 0x00403064 0x8 sample.o .eh_frame 0x00404060 0x38 sample.o .bss 0x00405020 0x0 sample.o 

Now, if I change my program a bit to make a global variable like

 const int a = 10; int main() { printf("%d\n", a); return 0; } 

Repeating the same step as above, I noticed that the distributions are lower

 .text 0x0040138c 0x2c sample.o .data 0x00402000 0x0 sample.o .rdata 0x00403064 0xc sample.o .eh_frame 0x00404060 0x38 sample.o .bss 0x00405020 0x0 sample.o 

It clearly shows that a stands out in .rdata as

 .rdata 0x00403064 0xc sample.o 0x00403064 a 

From these experiments, I understand that the global const located in the .rdata section, while the size of the .text section has decreased. Therefore, I assume that a was highlighted in the .text section in the first example.

My questions:

  • The scope of the const variable is considered when determining its place in .rdata or .text ?

  • From my experiment, I noticed that the variable required 8 bytes when it was allocated to the .text section compared to 4 bytes in the .rdata section. What is the reason for this difference?

  • If there are too many local const variables, the size of the corresponding .text section will increase significantly. What is the recommended programming practice in this scenario?

Thank you very much in advance.

+6
source share
2 answers

In the first case, the variable is declared as a local variable . It has an โ€œautomaticโ€ storage duration, which means that it leaves at the end of the covering area. It cannot occupy any part of the memory forever due to the duration of its storage (this is true regardless of const ). Thus, it is usually stored on the stack or in the register.

In the second case, the variable is declared as a global variable . It has a static shelf life, so it is preserved throughout the life of the program. This can be stored in many places, such as .data , .bss , .text or .rdata (or .rodata ).

.data usually used for writing static data with some predefined (non-zero) content, for example. global int foo = 42; . .bss used for rewritable static data initialized to zero (or not initialized). rdata used for constant static data such as strings and const variables. Of course, these uses are "general" and can vary from compiler to compiler.

So why .text became bigger in the first case? This is because the compiler had to generate additional instructions for loading 10 onto the stack or into the register.

+5
source

This behavior will differ from goal to goal. In the first example, where you think that a ends in the .text section, this is 10 , which (possibly) falls into the text section and loads into a , which is on the stack. Some architectures that have, for example, relative addressing, will place such constants somewhere between the code. Other architectures encode 10 as an instant addressing mode, which also leads to a slightly larger code size.

In the second example, a produces a global variable and will be in the .data section, which is also what you observed.

So, let me answer your questions in the light of the foregoing.

  • const in C does not mean that it is a constant (uuh ??), it means that the program program promises does not write it. Compilers will warn if you do this, or if you run the risk of doing so, but you will still compile. So the difference between your cases is that a is a local variable in the first example and a global variable in the second example. Hmm, I just tried to write const int , and that really gives an error, not just a warning. However, you can pass such const reference to a function that will change it. Combined objects may not even be displayed.

  • If it is in the .data section, this is the size of the object, 4 bytes in your case. If 10 is in the code, either in a permanent table or in the mode of immediate addressing, then it really depends on the architecture, how big it will be and what effect will be in the surrounding code.

  • If you have many constants in your code, and the architecture supports relative pc addressing (for example, ARM), then it will probably find all these constants somewhere near the code in which they are used, but all together one jump is enough to jump over it or not if there is a natural branch where a direct table can hide. Thus, constants take up as much space as they need, and not (much) more. If all of them were implemented as immediate addressing, then the compiler can still decide to make a table out of it if there are more efficient ways to get the constants this way.

+2
source

All Articles