Портирование NewLib: crt0

Я портирую NewLib для своей ОС, следуя руководству.

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


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


Ответы (3)


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

Это означает именно то, что написано. Когда компонуется приложение для вашей ОС, crt0 должен быть самым первым объектным файлом в командной строке компоновщика: перед любым другим объектным файлом.

Традиционно компоновщики UNIX разрешают символ, выполняя поиск, начиная с первого объекта/библиотеки и заканчивая последним объектом/библиотекой. Помещение crt0 в качестве первого объектного файла гарантирует, что системные символы (функции, переменные) выбираются из файла crt0, а не из какого-либо другого файла.

Кроме того, как указывает Р.., традиционные компоновщики предполагают, что точка входа приложения находится в начале сегмента кода. Это также соответствует исходному коду, найденному на связанной странице: первый символ в коде — _start, обычное имя точки входа в программу.

Например. запуская 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.

person Dummy00001    schedule 01.08.2010
comment
На самом деле традиционная причина, по которой crt0.o должен быть первым объектом, заключается в том, что традиционные компоновщики не искали конкретное имя символа для использования в качестве точки входа, а вместо этого просто помещали точку входа в начало .text. - person R.. GitHub STOP HELPING ICE; 01.08.2010
comment
@R..: ты можешь быть прав, особенно в этом случае. это объяснило бы, почему связанная вики-статья указывала на чтение о скрипте компоновщика. поправил бы мой ответ. - person Dummy00001; 01.08.2010

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

введите здесь описание изображения

person Peter Cheung    schedule 09.06.2016
comment
Это не отвечает на вопрос, как сначала вызвать компоновщик для ссылки crt0. Спрашивающий, по-видимому, уже знает, для чего это нужно. - person Toby Speight; 09.06.2016
comment
Хороший график, визуальное представление хорошее, так как некоторые люди больше ориентированы на движение, чем на письмо. - person Surt; 14.12.2018

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

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

person Richard Pennington    schedule 01.08.2010