Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I get MSVC to put uninitialized data in .bss?

Tags:

c++

c

visual-c++

I am building a DLL using a custom build system (outside Visual Studio), and I can't get uninitialized data to show up in the .bss section; the compiler lumps it into .data. This bloats the final binary size, since it's full of giant arrays of zeroes.

For example (small 1KB arrays in the example, but the actual buffers are much larger):

int uninitialized[1024];
int initialized[1024] = { 123 };

The compiler emits assembly like this:

PUBLIC  _initialized
_DATA   SEGMENT
COMM    _uninitialized:DWORD:0400H
_initialized DD 07bH
    ORG $+4092
_DATA   ENDS

Which ends up in the object file like this:

SECTION HEADER #3
   .data name
       0 physical address
       0 virtual address
    1000 size of raw data
     147 file pointer to raw data (00000147 to 00001146)
       0 file pointer to relocation table
       0 file pointer to line numbers
       0 number of relocations
       0 number of line numbers
C0400040 flags
         Initialized Data
         8 byte align
         Read Write

(There is no .bss section.)

The current compilation flags:

cl -nologo -c -FAsc -Faobjs\ -W4 -WX -X -J -EHs-c- -GR- -Gy -GS- -O1 -Os -Foobjs\file.o file.cpp

I have looked through the list of options at http://msdn.microsoft.com/en-us/library/fwkeyyhe(v=vs.71).aspx but I haven't spotted anything obvious.

I'm using the compiler from Visual Studio 2008 SP1 (Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 15.00.30729.01 for 80x86).

like image 471
Daniel Verkamp Avatar asked Oct 10 '11 22:10

Daniel Verkamp


2 Answers

You want to use __declspec(allocate()), which you can read up on here: http://msdn.microsoft.com/en-us/library/5bkb2w6t(v=vs.80).aspx

like image 103
Necrolis Avatar answered Sep 26 '22 04:09

Necrolis


Notice that "size of raw data" is only 0x1000 or 4kB - exactly the size of your initialized array only. The VirtualSize of your .data section will be larger than the size of the actual data stored in the binary image and your uninitialized array will occupy the slack space. Using the bss_seg pragma will force the linker to place your uninitialized data into its own separate section.

like image 31
Rob Baker Avatar answered Sep 25 '22 04:09

Rob Baker