Я портирую NewLib для своей ОС, следуя a tutorial.Портирование NewLib: crt0
В нем говорится, что как только я закончил свой crt0, я должен «связать его как первый объект». Как я могу это сделать?
Я портирую NewLib для своей ОС, следуя a tutorial.Портирование NewLib: crt0
В нем говорится, что как только я закончил свой crt0, я должен «связать его как первый объект». Как я могу это сделать?
В нем говорится, что как только я закончил свой crt0, мне нужно «связать его как первый объект».
Это означает, что именно говорится. Когда приложение для вашей ОС связано, crt0 должен быть самым первым объектным файлом в командной строке компоновщика: перед любым другим объектным файлом.
Традиционно UNIX-линкеры разрешают символ, просматривая исходный объект, начиная с первого объекта/библиотеки, переходящего в последний объект/библиотеку. Помещение crt0
в качестве первого объектного файла гарантирует, что системные символы (функции, переменные) выбраны из файла crt0, а не какого-либо другого файла.
Кроме того, как указано R .., традиционные линкеры предполагают, что точка входа приложения находится в начале сегмента кода. Это также соответствует исходному коду, найденному на связанной странице: первый символ в коде: _start
, обычное имя точки входа в программу.
E.g. работает gcc -v a.c -o a
на моем Debian (обратите внимание на -v
), один видит следующие ссылки команды (я добавил новые строки для удобства чтения):
/usr/lib/gcc/i486-linux-gnu/4.4.4/collect2
--build-id
--eh-frame-hdr
-m elf_i386
--hash-style=both
-dynamic-linker /lib/ld-linux.so.2
-o a
/usr/lib/gcc/i486-linux-gnu/4.4.4/../../../../lib/crt1.o
/usr/lib/gcc/i486-linux-gnu/4.4.4/../../../../lib/crti.o
/usr/lib/gcc/i486-linux-gnu/4.4.4/crtbegin.o
-L/usr/lib/gcc/i486-linux-gnu/4.4.4
-L/usr/lib/gcc/i486-linux-gnu/4.4.4
-L/usr/lib/gcc/i486-linux-gnu/4.4.4/../../../../lib
-L/lib/../lib
-L/usr/lib/../lib
-L/usr/lib/gcc/i486-linux-gnu/4.4.4/../../..
/tmp/ccndJ4YV.o
-lgcc
--as-needed
-lgcc_s
--no-as-needed
-lc
-lgcc
--as-needed
-lgcc_s
--no-as-needed
/usr/lib/gcc/i486-linux-gnu/4.4.4/crtend.o
/usr/lib/gcc/i486-linux-gnu/4.4.4/../../../../lib/crtn.o
Можно видеть, что CRT1 является первым объектом в командной строке. Глядя на сценарий компоновщика (-m elf_i386
->find /usr -name '*elf_i386*'
-> на моей системе /usr/lib/ldscripts/elf_i386.x
) можно проверить, что в Linux нет crt0
, но есть: crt1
, crti
, crtbegin
, crtend
, crtn
. И файлы объектов приложения (/tmp/ccndJ4YV.o
в примере выше) помещаются между crtbegin
и crtend
.
На самом деле традиционная причина 'crt0.o' должна быть первым объектом, так это то, что традиционные линкеры не искали конкретного имени символа для использования для точки входа, а вместо этого просто помещали точку входа в начало' .text '. –
@R ..: вы можете быть правы esp для случая. что объясняет, почему связанная статья wiki направлялась для чтения о скрипте компоновщика. исправит мой ответ. – Dummy00001
Один из способов, по крайней мере, для тестирования - разместить crt0.o в качестве первого файла в командной строке компилятора или линкера.
Для производства вы должны поместить его в файл команды компоновщика.
перед тем, как перейти на main()
, c время выполнения необходимо выполнить инициализацию, эта работа обрабатывается cert{i,n,0}
.
Это не отвечает на вопрос, каким образом ссылаться на компоновщик, чтобы связать 'crt0' первым. Вероятно, искатель уже знает, для чего он нужен. –
Предполагая, что вы используете GCC, редактировать его в спецификации для вашей цели, или один из файлов, используемых для создания спецификации (файл t_xxx?). Я забываю, что извините. – Rup