избегая перемещения текста при смешивании c / c ++ и сборки в .so

Я пытаюсь удалить все текстовые перемещения из .so, что смешивает c, c ++ и сборку. Для c / c ++ -fpic позаботится о ПОС.

На целевой Android ARM мы можем вызывать экспортированные asm-функции из c / c ++, не вызывая перераспределения текста. Но в нашей реализации мы имеем массивы данных, которые должны быть доступны как из C ++, так и для сборки. На C ++ это простой старый массив, то есть extern "C" { __declspec(align(32)) int16_t myarray[256]; } extern "C" { __declspec(align(32)) int16_t myarray[256]; } и на стороне asm мы используем .global myarray .

Во-вторых, мы используем такой символ в стороне asm, мы видим перемещение текста в финале .so, которое видно через scanelf и readelf . Android-загрузчик Android в режиме api 23 будет отказываться от загрузки такого .so.

Вопросы: – Эту проблему следует ожидать? – Есть ли специальная декларация, которая будет использоваться на стороне C или asm для обеспечения отсутствия пересадок текста?

Редактировать : Будет ли полезен минимальный пример?

Спасибо всем комментариям. Итак, чтобы подвести итог всем, кто борется с Android M, мы смогли решить некоторые из наших проблем. Теперь я понимаю следующее, и, пожалуйста, исправьте меня, если я ошибаюсь:

1) Я не мог в asm указать прямо на внешние глобальные переменные (т.е. ldr), не вызывая перемещения текста.

2) Я не мог в asm ссылаться на символ, содержащийся в разделе данных, даже если не глобальный, потому что относительный адрес от текста к данным неизвестен во время сборки. Почему. Linker не может решить это во время ссылки, я не уверен, но могу предположить, что относительный адрес слишком далеко или по природе PIC относительные адреса данных / текста не известны во время выполнения (?) ,

Итак, наше исправление было:

1) Предварительно создайте массивы и добавьте в текстовую секцию как можно ближе к используемому ей коду (относительные инструкции имеют ограниченное расстояние). Мы обнаружили, что слишком сильно удаляем таблицу из кода, используя ее.

2) Использование «adr» предпочтительнее «ldr» при загрузке с метки, поскольку, похоже, вы загружаетесь из текущего раздела и помогли нам избежать некоторых перемещений текста

К счастью, наши массивы были статическими данными, которые были сгенерированы во время выполнения и могут быть преобразованы в константу, известную во время сборки. Но для тех, где массив или память динамичны и должны быть переданы от C к asm, я не вижу другого выбора, чтобы передать его как параметр к ассемблеру, как это было предложено несколькими людьми в комментариях.

Полезным для чтения было: ARM – загрузка адресов в регистры