Page 1 of 1

Remove bss section for modules

Posted: Thu Mar 22, 2012 5:31 pm
by Jezze
Hi,

For a while I've had kernel modules. These are just normal elf object files that comes with my initrd which is basically just a tar archive that grub loads into memory on boot. Because the initrd is already in memory I thought that when I load my modules I really don't need to copy them anywhere because they are already in memory so I just relocate them to where they actually are. I know this is not optimal but it worked. However I noticed I did a big mistake and that was to forget that they might contain .bss data and I forgot that I needed to reserve space for that.

I thought that can easily be fixed without having to move them and that would be to put everything in the bss as part of the program code.

My question is: Which is the preferable way to do this? I've figured I got two options but there might be something simpler like a compiler flag or something. One is to add the __attribute__section((".text"))) to each global variable and the other would be to create a linker script similar to the one I have for the kernel that puts the .bss section inside .text. None of these are particularly appealing. Ideas anyone?

Re: Remove bss section for modules

Posted: Thu Mar 22, 2012 6:26 pm
by Rudster816
1. Create your own bootloader that loads your modules as ELF files (and reserves the memory).
2. Hack GRUB to do the same thing.
3. Put your .bss section into the module's .data section (pretty much the same thing as putting it in the .text though).
4. Don't allow your modules to statically allocate memory, and instead rely on a kernel call to get memory.
5. Convert your modules into flat binaries after you link everything together into an ELF file.
6. Parse the ELF headers once inside your kernel and make sure that you make room for any modules .bss section yourself.
7. Write a script to pad your ELF modules with 0's to account for the length of the .bss section.

Re: Remove bss section for modules

Posted: Thu Mar 22, 2012 7:48 pm
by bubach
Jezze wrote:... but there might be something simpler like a compiler flag or something.
yup
GCC manual wrote:-fno-zero-initialized-in-bss
If the target supports a BSS section, GCC by default puts variables that are initialized to zero into BSS. This can save space in the resulting code.

This option turns off this behavior because some programs explicitly rely on variables going to the data section. E.g., so that the resulting executable can find the beginning of that section and/or make assumptions based on that.

The default is -fzero-initialized-in-bss.

Re: Remove bss section for modules

Posted: Fri Mar 23, 2012 2:04 am
by Combuster
That description does not guarantee that uninitialized variables end up in .data as well.

Re: Remove bss section for modules

Posted: Fri Mar 23, 2012 2:19 am
by Owen
Just use your linker script to put the sections which normally go in BSS (.bss*, COMMON*, etc) into data and you'll be find.

Otherwise, just use paging in order to remap the binaries so they can run in place but get an actual BSS section.

Finally, as a safety check, you may wish to have your loader error out if you find a NOBITS segment to be loaded of nonzero size

Re: Remove bss section for modules

Posted: Fri Mar 23, 2012 6:41 am
by Combuster
Owen wrote:Finally, as a safety check, you may wish to have your loader error out if you find a NOBITS segment to be loaded of nonzero size
Even better is to check if section size - stored size > 0, as ELF allows merged .bss and .data sections.

Re: Remove bss section for modules

Posted: Fri Mar 23, 2012 4:34 pm
by Jezze
Thanks for all the replies! I'll go with adding a linker script and put it in the .data section (and not the .text section as I said previously) until I make it work properly (by demand paging).

Re: Remove bss section for modules

Posted: Sat Mar 24, 2012 2:36 am
by Solar
Combuster wrote:That description does not guarantee that uninitialized variables end up in .data as well.
Erm... aren't all static variables initialized by definition? At least that's how it is with C/C++...

Re: Remove bss section for modules

Posted: Sat Mar 24, 2012 2:53 am
by Rudster816
Solar wrote:
Combuster wrote:That description does not guarantee that uninitialized variables end up in .data as well.
Erm... aren't all static variables initialized by definition? At least that's how it is with C/C++...

Code: Select all

#include <stdio.h>
static int foo;

int main()
{
	int bar = foo;
	printf("bar %i\n", bar);
	return 0;
}
From the point of view of the compiler, foo is uninitialized (and will probably give you a warning). In reality, when know that it will be 0 if it's stuck in the .bss section, or it will be whatever the compiler decides to put in its place in the .data section.

Re: Remove bss section for modules

Posted: Sat Mar 24, 2012 5:02 am
by Rudster816
Huh, I never knew the = 0 was implicit. I always thought that anything without an explicit initialization was undefined by the standard. :shrug:

Re: Remove bss section for modules

Posted: Sun Mar 25, 2012 4:07 pm
by qw
Rudster816 wrote:Huh, I never knew the = 0 was implicit. I always thought that anything without an explicit initialization was undefined by the standard.
In ISO C/C++ there is no such thing as uninitialized static data. Automatic, register and dynamically allocated data may be uninitialized, but static data that is not initialized explicitly, must be set to zero before main() is called.