I'm struggling to convert a C-program linked with ld, of the gnu tool-chain to make it compile as a visual-studio (2005) project. The program puts .data-symbols in different segments and during an initialization phase it copies data between segments. Pointers to the start and end of the segments are defined in the ld linker script.
I understand how to locate the variables into different, user-defined segments, but i havent been able to figure out how to define linker constants such as _start_of_my_segment or if there is something similar to a linker script in Visual Studio.
My goal is to be able to compile the program with, prefferably no modifications to the source-code that refers to the linker-defined symbols, but with my own custom layout of the data in the Visual Studio project.
Below is some example C-code that illustrates what i'd like to do and a (stripped-down, possibly syntax-incorrect) version of the make-script used when linking with gcc/ld.
Any hints would be greatly appreciated!
#pragma data_seg( "MY_DATA_FOO" )
#pragma data_seg( "MY_DATA_BAR" )
#pragma comment(linker, "/section:MY_DATA_BAR,R")
__declspec(allocate("MY_DATA_FOO")) int foo1;
__declspec(allocate("MY_DATA_FOO")) int foo2;
__declspec(allocate("MY_DATA_BAR")) int bar1 = 1;
__declspec(allocate("MY_DATA_BAR")) int bar2 = 2;
#pragma data_seg( )
void test() {
foo1 = bar1;
foo2 = bar2;
// i would rather do this as
//extern unsigned int __start_of_MY_DATA_FOO;
//extern unsigned int __start_of_MY_DATA_BAR;
//extern unsigned int __size_of_MY_DATA_BAR;
//memcpy(__start_of_MY_DATA_FOO, _start_of_MY_DATA_BAR, _size_of_MY_DATA_BAR);
}
Pseudo link-script (what would be the equivalent for Visual Studio
MEMORY
{
foo: org=0x1000, len=0x10开发者_JAVA技巧0
bar: org=0x2000, len=0x100
}
SECTIONS
{
GROUP:
{
MY_DATA_FOO : {}
__start_of_MY_DATA_FOO = ADDR(MY_DATA_FOO);
__end_of_MY_DATA_FOO = .;
__size_of_MY_DATA_FOO = SIZEOF(MY_DATA_FOO);
} > foo
GROUP:
{
MY_DATA_BAR : {}
__start_of_MY_DATA_BAR = ADDR(MY_DATA_BAR);
__end_of_MY_DATA_BAR = .;
__size_of_MY_DATA_BAR = SIZEOF(MY_DATA_BAR);
} > bar
}
padding can be removed by segments merging
for example
#pragma data_seg(".foo_begin")
#pragma data_seg(".foo_data")
#pragma data_seg(".foo_end")
#pragma comment( linker, "/merge:.foo_begin=.foo" )
#pragma comment( linker, "/merge:.foo_data=.foo" )
#pragma comment( linker, "/merge:.foo_end=.foo" )
__declspec(allocate(".foo_begin")) int foo_begin_marker;
__declspec(allocate(".foo_end")) int foo_end_marker;
__declspec(allocate(".foo_data")) int foo_data;
Create additional segments (they are placed in memory alphabetically):
#pragma data_seg("MY_DATA_FOO__a")
#pragma data_seg("MY_DATA_FOO__z")
#pragma data_seg("MY_DATA_FOO__m")
__declspec(allocate("MY_DATA_FOO__a")) int fooFirst;
__declspec(allocate("MY_DATA_FOO__z")) int fooLast;
__declspec(allocate("MY_DATA_FOO__m")) int foo1;
__declspec(allocate("MY_DATA_FOO__m")) int foo2;
Then copy everything between &fooFirst and &fooLast.
精彩评论