views:

24

answers:

1

Hi,

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=0x100
  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
}
A: 

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.

Sergius
ara
Thanks again! I found an example of the trick you suggest in the doc for #pragma init_seg (here http://msdn.microsoft.com/en-us/library/7977wcck.aspx). It says "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 $."And, when I changed the section-names to "MY_DATA_FOO$a" etc they ended up correctly sorted. However each section-size's is still zero-padded up to approx 0x100 bytes which makes it hard to know the "proper" end of the segment.
ara
Here is an example from ATL sources:#pragma section("ATL$__a", read, shared)#pragma section("ATL$__z", read, shared)#pragma section("ATL$__m", read, shared)Try section instead of data_seg.
Sergius
Yes, they both work (if one uses '$' in the section name). However both still add some padding so i still cant figure out how to construct the symbol __size_of_MY_DATA_BAR.
ara
Hmmm... I've got an alignment too. And it is quite strange.
Sergius