Как обратиться к началу определенного пользователем сегмента в Visual Studio-проекте? - PullRequest
6 голосов
/ 07 июля 2010

Я изо всех сил пытаюсь преобразовать C-программу, связанную с ld, из цепочки инструментов gnu, чтобы она компилировалась как проект visual-studio (2005).Программа помещает .data-символы в разные сегменты и на этапе инициализации копирует данные между сегментами.Указатели на начало и конец сегментов определяются в сценарии компоновщика ld.

Я понимаю, как расположить переменные в разных пользовательских сегментах, но я не смог понять, как определить константы компоновщика, такие как _start_of_my_segment или есть ли что-то похожее на скрипт компоновщика в Visual Studio,

Моя цель состоит в том, чтобы иметь возможность компилировать программу, предпочтительно без изменений в исходном коде, который ссылается на символы, определенные компоновщиком, но с моей собственной пользовательской компоновкой данных в проекте Visual Studio.

Ниже приведен пример C-кода, который иллюстрирует то, что я хотел бы сделать, и (упрощенную, возможно, синтаксически неправильную) версию make-script, используемую при связывании с gcc / ld.

Будем благодарны за любые подсказки!

#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);
}

Псевдо-ссылка-скрипт (что будет эквивалентно 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
}

Ответы [ 2 ]

3 голосов
/ 07 августа 2011

заполнение может быть удалено объединением сегментов

например

#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;
0 голосов
/ 07 июля 2010

Создание дополнительных сегментов (они располагаются в памяти в алфавитном порядке):

#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;

Затем скопируйте все между & fooFirst и & fooLast.

...