Компиляция без libc

Я хочу скомпилировать свой C-код без (g) libc. Как я могу деактивировать его и какие функции зависят от него?

Я попробовал-nostdlib, но он не помогает: код является компилируемым и выполнения, но я могу все еще найти название libc в hexdump моего исполняемого файла.

53
задан u149796 31 March 2010 в 20:37
поделиться

2 ответа

Если вы скомпилируете свой код с помощью -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 () недоступен.

68
ответ дан 7 November 2019 в 08:48
поделиться

Самый простой способ - скомпилировать код C в объектные файлы ( gcc -c , чтобы получить *. O ), а затем свяжите их напрямую с помощью компоновщика ( ld ). Вам нужно будет связать свои объектные файлы с несколькими дополнительными объектными файлами, такими как /usr/lib/crt1.o , чтобы получить рабочий исполняемый файл (между точкой входа, видимой ядром, и функция main () , есть над чем поработать). Чтобы узнать, с чем связать, попробуйте связать с glibc, используя gcc -v : это должно показать вам, что обычно входит в исполняемый файл.

Вы обнаружите, что gcc генерирует код, который может иметь некоторые зависимости от нескольких скрытых функций. Большинство из них находится в libgcc.a . Также могут быть скрытые вызовы memcpy () , memmove () , memset () и memcmp () , которые находятся в libc, поэтому вам, возможно, придется предоставить свои собственные версии (что несложно, по крайней мере, если вы не слишком требовательны к производительности).

Вещи могут время от времени проясняться, если вы посмотрите на созданную сборку (используйте флаг -S ).

7
ответ дан 7 November 2019 в 08:48
поделиться
Другие вопросы по тегам:

Похожие вопросы: