Я строю виртуальные таблицы вручную на C. При экспорте из DLL они создают много записей в своей таблице перемещений.
Пример objdump
вывода:
Virtual Address: 00002000 Chunk size 24 (0x18) Number of fixups 8
reloc 0 offset 0 [2000] HIGHLOW
reloc 1 offset 4 [2004] HIGHLOW
reloc 2 offset 8 [2008] HIGHLOW
reloc 3 offset c [200c] HIGHLOW
reloc 4 offset 10 [2010] HIGHLOW
reloc 5 offset 14 [2014] HIGHLOW
reloc 6 offset 18 [2018] HIGHLOW
reloc 7 offset 1c [201c] HIGHLOW
Есть ли способ избавиться от них, или это единственный способ в Windows?
Вот мои выводы на данный момент:
- в Visual Studio
link
есть опция/FIXED
(которая делает именно то, что я хочу) - есть это руководство , но большая часть из них применима только к
gcc
под Linux - Я могу собрать DLL без
-shared
и вместо этого установить--image-base
Последнее действительно работает (секция .reloc
не генерируется), но я считаю это крайне уродливым хаком, потому что на самом деле это уже не DLL.
Пояснение:
У меня складывается впечатление, что за этот вопрос проголосовали только отрицательно, потому что люди считают, что переезд — это хорошо. Я признаю, что они хороши в целом, но у меня есть очень конкретная цель. Я хочу показать, как динамический полиморфизм с vtables может быть достигнут в O (1), например:
struct IDerived {
union {
IBaseA asBaseA;
struct {
int (*foo)(Derived this); // inherited from BaseA
...
};
};
union {
IBaseB asBaseB;
struct {
int (*bar)(Derived this); // inherited from BaseB
...
};
};
int (*baz)(Derived this);
...
};
struct Derived {
const IDerived *iface;
void *data;
};
extern void doSthWithBaseB(BaseB x);
void doSthWithDerived(Derived x) {
x.iface->foo(x);
doSthWithBaseB((BaseB){ &x.iface->asBaseB, x.data }) // high-level cast
}
Поскольку «высокоуровневое приведение» включает только арифметику указателя, это O (1) (в частности, линейный поиск не выполняется, как в Java).
Теперь вернемся к перемещениям: независимо от того, насколько низка стоимость, она оказывается равной O(n), поскольку каждый метод в каждом классе нуждается в обновлении. Вздох.
tl;dr
Есть ли подвеска к Microsoft /FIXED
для GCC? Если нет, то какие флаги нужно установить в PE для достижения желаемого поведения?
-pie
, создает независимый от позиции исполняемый файл. Мне кажется, это просто не относится к указателям функций в разделе .rdata. Но именно в этом мой вопрос (я отредактировал его, чтобы сделать это более понятным). - person Philip   schedule 02.05.2016-pie
по большей части игнорируется для целей Windows. Он делает прямо противоположное тому, что вы хотите, он говорит компоновщику создавать релокации для исполняемых файлов (.EXE). Обычно исполняемые файлы в Windows нельзя перемещать, перемещения позволяют перемещать их, как DLL. Обычно библиотеки DLL имеют перемещение, параметр Visual Studio/FIXED
создает библиотеки DLL без них, предотвращая перемещение библиотеки DLL. Это предотвратит загрузку DLL Windows, если что-то уже находится по адресу, по которому должна быть загружена DLL. - person Ross Ridge   schedule 04.05.2016