Инжекционные секции в GNU ld script; script совместимость между версиями binutils.
Я создаю что-то вроде вопроса Как собирать данные из разных файлов .a в один массив? Как сохранить разделы в файлах .a с помощью ld script?, т.е. Массивы, созданные во время компоновки ссылок из элементов из разных объектных файлов.
В моем случае имеется несколько массивов, каждый из которых входит в свой раздел,.ld_comp_array_ *, где * соответствует имени массива. Затем я беру компоновщик по умолчанию script с помощью ld -verbose и изменяю его, помещая все эти разделы (отсортированные, чтобы элементы разных массивов не смешивались) в выходной раздел:
KEEP (*(SORT_BY_NAME(.ld_comp_array*)))
и все работает нормально.
Тогда все становится немного сложнее, потому что приложения (приложения), использующие эту функцию, могут быть созданы для разных платформ - до сих пор я успешно тестировал AVR Xmega как целевую платформу, а также 32-разрядную и Linux-версию Windows 32- и 64-бит для модульного тестирования, и список открыт (новые платформы, вероятно, будут добавлены в ближайшем будущем).
Однако для каждой конкретной платформы сценарии компоновщика по умолчанию отличаются от других платформ, и в настоящее время я вставляю разделы .ld_comp_array * вручную - можно ли это сделать как-то автоматически? Единственное решение, о котором я думал, - это разбор по умолчанию script и вставка вышеприведенного описания раздела ввода, но это кажется слишком тяжелым.
Я мог бы сделать это вручную, если не было относительно простого решения, но я не уверен, что скрипты по умолчанию, полученные из локальной версии ld, могут быть разбиты на разные версии binutils. Может ли кто-нибудь уточнить, безопасно это или нет?
Если это можно сделать автоматически, нормально ли "вводить" спецификацию раздела ввода непосредственно в раздел .text, предполагая, что массивы должны быть "неизменными"?
Ответы
Ответ 1
Я нашел удовлетворительное решение для этой проблемы. GNU ld имеет опцию INSERT, которая делает внешнюю поддержку script не переопределять по умолчанию script, а просто добавляет новый раздел в позицию относительно некоторого раздела, который существует в стандартном script.
Итак, в моем случае script, переданный компоновщику, может быть таким же простым, как:
SECTIONS
{
.rodata.ld_comp_array :
{
*(SORT_BY_NAME(.ld_comp_array*))
}
}
INSERT AFTER .rodata;
Подробнее о опции INSERT: http://sourceware.org/binutils/docs/ld/Miscellaneous-Commands.html#Miscellaneous-Commands