How to get a pointer to a binary section in MSVC?
There is also a way to do this with out using an assembly file.
#pragma section(".init$a")
#pragma section(".init$u")
#pragma section(".init$z")
__declspec(allocate(".init$a")) int InitSectionStart = 0;
__declspec(allocate(".init$z")) int InitSectionEnd = 0;
__declspec(allocate(".init$u")) int token1 = 0xdeadbeef;
__declspec(allocate(".init$u")) int token2 = 0xdeadc0de;
The first 3 line defines the segments. These define the sections and take the place of the assembly file. Unlike the data_seg pragma, the section pragma only create the section. The __declspec(allocate()) lines tell the compiler to put the item in that segment.
From the microsoft page: The order here is important. Section names must be 8 characters or less. The sections with the same name before the $ are merged into one section. The order that they are merged is determined by sorting the characters after the $.
Another important point to remember are sections are 0 padded to 256 bytes. The START and END pointers will NOT be directly before and after as you would expect.
If you setup your table to be pointers to functions or other none NULL values, it should be easy to skip NULL entries before and after the table, due to the section padding
See this msdn page for more details
First of all, you'll need to create an ASM-file containing all the sections you are interested (for ex., section.asm):
.686
.model flat
PUBLIC C __InitSectionStart
PUBLIC C __InitSectionEnd
INIT$A SEGMENT DWORD PUBLIC FLAT alias(".init$a")
__InitSectionStart EQU $
INIT$A ENDS
INIT$Z SEGMENT DWORD PUBLIC FLAT alias(".init$z")
__InitSectionEnd EQU $
INIT$Z ENDS
END
Next, in your code you can use the following:
#pragma data_seg(".init$u")
int token1 = 0xdeadbeef;
int token2 = 0xdeadc0de;
#pragma data_seg()
This gives such a MAP-file:
Start Length Name Class
0003:00000000 00000000H .init$a DATA
0003:00000000 00000008H .init$u DATA
0003:00000008 00000000H .init$z DATA
Address Publics by Value Rva+Base Lib:Object
0003:00000000 ?token1@@3HA 10005000 dllmain.obj
0003:00000000 ___InitSectionStart 10005000 section.obj
0003:00000004 ?token2@@3HA 10005004 dllmain.obj
0003:00000008 ___InitSectionEnd 10005008 section.obj
So, as you can see it, the section with the name .init$u
is placed between .init$a
and .init$z
and this gives you ability to get the pointer to the begin of the data via __InitSectionStart
symbol and to the end of data via __InitSectionEnd
symbol.