Связывание символов с фиксированными адресами в Linux - PullRequest
9 голосов
/ 30 января 2009

Как можно связать (некоторые) символы с определенными фиксированными адресами, используя GNU ld, чтобы двоичный код мог все еще выполняться как обычно в Linux (x86)? Доступ к этим символам не будет, но их адреса важны.

Например, у меня будет следующая структура:

struct FooBar {
    Register32 field_1;
    Register32 field_2;
    //...
};

struct FooBar foobar;

Я бы хотел связать foobar с адресом 0x76543210, но обычно связывать стандартные библиотеки и остальную часть приложения. Затем приложение будет использовать адрес foobar, но не будет ссылаться на (возможно, не существующую) память за ним.

Обоснование этого запроса заключается в том, что один и тот же источник может использоваться на двух платформах: на собственной платформе Register32 может быть просто volatile uint32_t, а в Linux Register32 - это объект C ++ с тем же размером как uint32_t, который определяет, например, operator=, который затем использует адрес объекта и отправляет запрос в инфраструктуру связи с этим адресом (и данными) для выполнения фактического доступа на удаленном оборудовании. Таким образом, компоновщик обеспечит, чтобы поля Register32 структуры ссылались на правильные "адреса".

Ответы [ 3 ]

15 голосов
/ 30 января 2009

Предложение litb использовать --defsym symbol=address работает, но немного громоздко, когда у вас есть несколько десятков таких экземпляров для отображения. Тем не менее, --just-symbols=symbolfile делает только трюк. Мне потребовалось некоторое время, чтобы выяснить синтаксис symbolfile, то есть

symbolname1 = address;
symbolname2 = address;
...

Пробелы кажутся необходимыми, иначе ld сообщает file format not recognized; treating as linker script.

8 голосов
/ 30 января 2009

Попробуйте с

--defsym symbol=expression

Как с этим:

gcc -Wl,--defsym,foobar=0x76543210 file.c

И сделайте foobar в вашем коде внешним объявлением:

extern struct FooBar foobar;

Это выглядит многообещающе. Однако делать такую ​​вещь - плохая идея (если вы действительно не знаете, что делаете). Зачем тебе это нужно?

1 голос
/ 30 января 2009

Я дам вам горячий совет ... GNU LD может сделать это (при условии, что системным библиотекам не нужен адрес, который вы хотите). Вам просто нужно создать собственный скрипт компоновщика, а не использовать автоматически сгенерированный компилятором. Прочитайте справочную страницу для ld. Кроме того, создание сценария компоновщика для сложной части программного обеспечения является непростой задачей, если вы также задействуете GLIBC.

...