Вопрос
Я хочу скомпилировать свой C-код без (g)libc.Как я могу отключить его и какие функции зависят от этого?
Я попробовал -nostdlib, но это не помогает:Код компилируется и выполняется, но я все еще могу найти имя libc в шестнадцатеричном дампе моего исполняемого файла.
Решение
Если вы скомпилируете свой код с -nostdlib
, вы не сможете вызывать какие-либо функции библиотеки C (конечно), но вы также не получите обычный загрузочный код C.В частности, реальной точкой входа программы в Linux не является main()
, а скорее функция , вызываемая _start()
.Стандартные библиотеки обычно предоставляют версию этого, которая запускает некоторый код инициализации, затем вызывает main()
.
Попробуйте скомпилировать это с помощью gcc -nostdlib -m32
:
void _start() {
/* main body of program: call main(), etc */
/* exit system call */
asm("movl $1,%eax;"
"xorl %ebx,%ebx;"
"int $0x80"
);
}
В _start()
функция всегда должна заканчиваться вызовом exit
(или другой невозвращающий системный вызов, такой как exec
).Приведенный выше пример вызывает системный вызов непосредственно с помощью встроенной сборки, поскольку обычный exit()
недоступен.
Другие советы
Самый простой способ - это скомпилировать C-код в объектные файлы (gcc -c
, чтобы получить некоторые *.o
файлы), а затем свяжите их непосредственно с компоновщиком (ld
).Вам нужно будет связать свои объектные файлы с несколькими дополнительными объектными файлами, такими как /usr/lib/crt1.o
для того, чтобы получить рабочий исполняемый файл (между точкой входа, видимой ядром, и main()
функция, нужно немного поработать).Чтобы знать, с чем связать, попробуйте связать с glibc, используя gcc -v
:это должно показать вам, что обычно входит в исполняемый файл.
Вы обнаружите, что gcc генерирует код, который может иметь некоторые зависимости от нескольких скрытых функций.Большинство из них находятся в libgcc.a
.Также могут быть скрытые вызовы для memcpy()
, memmove()
, memset()
и memcmp()
, которые находятся в libc, поэтому вам, возможно, придется предоставить свои собственные версии (что несложно, по крайней мере, до тех пор, пока вы не слишком придирчивы к производительности).
Вещи мог бы временами становится понятнее, если вы посмотрите на созданную сборку (используйте -S
флаг).