Я хочу скомпилировать свой C-код без (g) libc. Как я могу деактивировать его и какие функции зависят от него?
Я попробовал-nostdlib, но он не помогает: код является компилируемым и выполнения, но я могу все еще найти название libc в hexdump моего исполняемого файла.
Если вы скомпилируете свой код с помощью -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
).