> The .bss segment has been zeroed, for obvious reasons, since the advent of modern linkage.
For your amusement: in the Linux kernel, at least on x86, .bss isn’t initialized when the kernel is loaded. Instead, the kernel memsets it to zero a little later. I don’t know why.
Also, because all this stuff predates any concept of security, there is no read-only equivalent of .bss in most systems, meaning that you get suboptimal code for:
Why would the code for "const int i" be any different from the code for "int i"? The Standard doesn't require the variable to be allocated in an immutable memory area. It just says that if you do anything to change its value, the result is undefined behavior. And actually changing the value in a way that would be observable via the const variable is a valid subset of undefined behavior.
It's hard to imagine many situations where you need to give a name to the constant value 0. And think how "optimal" it would be if there were many and we had a read-only BSS! We could cheaply get a huuuge section full of constant zeroes.
I think you can in fact realize the idea in PECOFF, by the way. I still need to figure out some aspects to it these days (it seems a bit arcane and maybe Windows doesn't follow the spec very well). But in any case PECOFF has this notion "VirtualSize" (size of section in running program) and "SizeInFile" (size of the prefix of the section that should be filled with contents from the executable file). If SizeInFile is smaller than VirtualSize then the rest of the image gets filled with zeroes I think.
But in any case PECOFF has this notion "VirtualSize" (size of section in running program) and "SizeInFile" (size of the prefix of the section that should be filled with contents from the executable file). If SizeInFile is smaller than the rest of the image gets filled with zeroes I think.
Correct. A common and low-hanging-(more like "lying on the ground")fruit optimisation for PE files is to reorder and realign the sections such that all the 0s are at the end, in which case they can be "cut off" by setting those header fields appropriately and not waste storage space.
> I think you can in fact realize the idea in PECOFF, by the way.
You can express it in ELF too, with a NOBITS segment with ALLOC but no WRITE flag. Whether that works or exercises bugs in the dynamic loader is an open question.
The OS program loader is who allocates pages to .bss and initializes them to zero. In the case of an OS, who would do that initialization? At best it would be the bootloader. Initialization during kernel_init() before using any globals is acceptable too.
Having seen both sides of this, people are arguing about the proper way to skin a cat. The standard only cares the cat be skinned not how.
On OS it's done by the OS for security and performance reasons. One you don't want people to snoop on memory freed from other processes. Two the OS can use the MMU to map in previously zero's pages of memory on demand, so you don't need to actually zero the entire .BSS section on startup.
On a bare metal system usually it's done either in assembly (or more cheezy in C) + linker magic.
For your amusement: in the Linux kernel, at least on x86, .bss isn’t initialized when the kernel is loaded. Instead, the kernel memsets it to zero a little later. I don’t know why.
Also, because all this stuff predates any concept of security, there is no read-only equivalent of .bss in most systems, meaning that you get suboptimal code for:
const int i = 0;