Подтвердить что ты не робот

Слабые псевдонимы символов на OS X, похожие на Linux, или ближайший эквивалент?

Что я делаю

При написании разделяемых библиотек для Linux я стараюсь обратить внимание на перемещение, видимость символов, GOT/PLT и т.д.

Когда это применимо, я пытаюсь избежать вызова PLT-заглушек, когда функции из одной библиотеки вызывают друг друга. Например, предположим, что общий объект предоставляет две публичные функции - foo() и bar() (любой из них может быть вызван пользователем). Однако функция bar() также вызывает foo(). Так что я делаю в этом случае следующее:

  • Определите функции _foo() и _bar(), которые имеют конфиденциальную видимость.
  • Определите слабые псевдонимы foo() и bar() для _foo() и _bar() соответственно.

Таким образом, код в совместно используемом объекте никогда не использует слабые символы. Он вызывает непосредственно локальные функции. Например, когда вызывается _bar(), он вызывает непосредственно _foo().

Но пользователи не знают о функциях _* и всегда используют соответствующие слабые псевдонимы.

Как я это делаю

В Linux это достигается с помощью следующей конструкции:

extern __typeof (_NAME) NAME __attribute__(weak, alias("_NAME"));

Проблема

К сожалению, это не работает для OS X. У меня нет глубоких знаний об OS X или его двоичных форматах, поэтому я немного задумался и нашел несколько примеров слабых функций (например, этот), но это не совсем то же самое, что вы можете иметь слабый символ, но не слабый символ, который является псевдонимом для локальной функции DSO.

Возможное решение...

На данный момент я отключил эту функцию (которая реализована с использованием макросов), так что все символы являются глобальными и имеют видимость по умолчанию. Единственный способ, к которому я могу сейчас прийти, - иметь все функции _foo с частной видимостью и иметь соответствующие функции foo с видимостью по умолчанию и вызывать их "скрытые" копии.

Лучший способ?

Это, однако, требует хорошего фрагмента кода, который нужно изменить. Поэтому я бы предпочел не идти туда, если нет другого пути.

Итак, что закрывает альтернативу OS X или самый простой способ получить одну и ту же семантику/поведение?

4b9b3361

Ответ 1

В OS X вызовы, сделанные в библиотеке, являются автоматически прямыми вызовами и не проходят через dyld-заглушку. Свидетельством тому фактом является то, что если вы хотите иметь возможность вводить альтернативные функции для обслуживания вызова, вам нужно использовать interposable для принудительного косвенного доступа к символам и принудительного выполнения вызова через dyld-заглушки. В противном случае, по умолчанию, локальные вызовы будут прямыми и не будут нести накладные расходы на запуск через dyld.

Таким образом, ваша оптимизация в Linux уже является поведением по умолчанию, и псевдоним не нужен.

Тем не менее, если вы хотите сделать это просто, чтобы сделать ваш совместимый с платформой код более простым, вы все равно можете сделать псевдонимы. Вам просто нужно использовать "слабый_импорт" или "слабый" (если вы хотите объединить) в качестве имени вашего атрибута.

extern typeof (_NAME) NAME __attribute (слабый_импорт, псевдоним ( "_ NAME" ));

Ссылка Apple на слабое соединение: Маркировка символов для слабой связи
Ссылка Apple на привязку времени исполнения Mach-O: Область и обработка определений символов