2010-08-01 2 views
2

Я портирую NewLib для своей ОС, следуя a tutorial.Портирование NewLib: crt0

В нем говорится, что как только я закончил свой crt0, я должен «связать его как первый объект». Как я могу это сделать?

+0

Предполагая, что вы используете GCC, редактировать его в спецификации для вашей цели, или один из файлов, используемых для создания спецификации (файл t_xxx?). Я забываю, что извините. – Rup

ответ

4

В нем говорится, что как только я закончил свой 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.

+2

На самом деле традиционная причина 'crt0.o' должна быть первым объектом, так это то, что традиционные линкеры не искали конкретного имени символа для использования для точки входа, а вместо этого просто помещали точку входа в начало' .text '. –

+0

@R ..: вы можете быть правы esp для случая. что объясняет, почему связанная статья wiki направлялась для чтения о скрипте компоновщика. исправит мой ответ. – Dummy00001

0

Один из способов, по крайней мере, для тестирования - разместить crt0.o в качестве первого файла в командной строке компилятора или линкера.

Для производства вы должны поместить его в файл команды компоновщика.

-1

перед тем, как перейти на main(), c время выполнения необходимо выполнить инициализацию, эта работа обрабатывается cert{i,n,0}.

enter image description here

+0

Это не отвечает на вопрос, каким образом ссылаться на компоновщик, чтобы связать 'crt0' первым. Вероятно, искатель уже знает, для чего он нужен. –

Смежные вопросы