LINUX.ORG.RU

ld не видит strlen при подключенном заголовочном файле

 


0

3

Приветствую.

Имеется файл kernel.c, к нему подключаю kernel.h в котором включены stdlib.h и string.h и в том же kernel.h имеется функция, которая использует strlen, компилирую удачно, но при линковке ld говорит это: «undefined reference to `strlen'».

Делаю всё следующей последовательностью команд: gcc -m32 -c kernel.c -o kc.o ld -m elf_i386 -T link.ld -o kernel-0 kasm.o kc.o

То есть, заголовочные файлы имеются и всё компилируется, а значит что проблем с кодом и нет, но линкер в отличии от компилятора не видит strlen Что же не так?


-m32 а для целевой платформы имеется 32-битный glibc?

EXL ★★★★★
()

Если ты хочешь своё ядро делать, готовься писать без glibc.

hateyoufeel ★★★★★
()

заголовочные файлы имеются и всё компилируется

В заголовочных файлах описывается, что вот где-то там есть такая функция strlen, параметры у которой такие-то такие-то, а возвращаемое значение — такое-то. Этого достаточно, чтобы скомпилировать исходный файл в объектный.

но линкер в отличии от компилятора не видит strlen Что же не так?

Ты ему не дал объектный файл с реализацией strlen(). Обычно при компиляции программ неявно используется libc, где есть реализация в том числе и strlen(). Если ты решил всё делать сам, то ничего из libc у тебя в распоряжении нет.

i-rinat ★★★★★
()

у тебя где-то в ядре есть strlen? Это не встроенный оператор, а обычная функция. Она реализуется в libc. Тебе нужен либо какой-то простой libc типа newlib, либо не использовать стандартных функций и писать что-то своё. strlen тот же в пару строк реализуется

mittorn ★★★★★
()
Ответ на: комментарий от i-rinat

Ну вы блин даёте...

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

int main(void)
{
        char buf[128];
        fgets(buf, 128, stdin);
        printf("%d\n", strlen(buf));
        return 0;
}
$ cc -c t.c
$ nm -g t.o | grep strlen
                 U strlen
$ cc -O2 -c t.c
$ nm -g t.o | grep strlen

vodz ★★★★★
()
Последнее исправление: vodz (всего исправлений: 1)
Ответ на: комментарий от mittorn

Понятно, я ожидал что

strlen()
включится в kc.o.

Значит реализую сам. Спасибо.

mrjbom
() автор топика
Ответ на: комментарий от mittorn

Такое поведение убирается через -fno-builtins

Я не понял, зачем вы именно мне это пишите? Цитируете запись, что себе сделали в пямятный блокнот?

Вы выбрали именно ту функцию, которую не надо вносить в ядерную библиотеку именно по причине, что можно заюзать встроенную.

vodz ★★★★★
()
Ответ на: комментарий от vodz

нельзя заюзать встроенную т.к builtin оптимизируется только когда вызов функции можно заменить числом на стадии компиляции. Будь там указатель произвольный - O2 бы не помогло

mittorn ★★★★★
()
Ответ на: комментарий от mittorn

Что за чушь? Не позорьтесь. Это именно встроенная функция, а не константа. Наличие её в ядре определяется тупо, в arch/*/include/asm/string*.h от архитектуры.

vodz ★★★★★
()
Ответ на: комментарий от vodz

Я сначала думал, что это ты прикалываешься так. Ан нет, ты серьёзно.

#include <stdio.h>
#include <string.h>

int main(int argc, char *argv[]) {
    printf("%zd\n", strlen(argv[0]));
    return 0;
}

Скомпилируй и посмотри внимательно.

i-rinat ★★★★★
()
Последнее исправление: i-rinat (всего исправлений: 1)
Ответ на: комментарий от vodz

в ядре реализация в lib/string.c
builtin оптимизации только заменяют константные варианты типа sqrt(4), cos(0), strlen от строки с известным при компиляции содержимым

mittorn ★★★★★
()
Последнее исправление: mittorn (всего исправлений: 2)
Ответ на: комментарий от mittorn

в ядре реализация в lib/string.c

Которая обёрнута в #ifndef __HAVE_ARCH_STRLEN, которая определена в arch/*/include/asm/string*.h

vodz ★★★★★
()
Ответ на: комментарий от i-rinat

Скомпилируй и посмотри внимательно.

Да, время течет..., в x86_32 таки builtin всегда. В 64 не захотели извращаться. :(

vodz ★★★★★
()
Ответ на: комментарий от mittorn

strlen от строки с известным при компиляции содержимым

чушь
даже memcpy очень часто инлайнится без понимания а что у нее там за содержимое

anonymous
()
Ответ на: комментарий от anonymous

чушь

Я скопировал из исходников ядра.

даже memcpy очень часто инлайнится

Да, там же следующей строкой идёт именно разборки с memcpy и оно реже бывает builtin.

vodz ★★★★★
()
Ответ на: комментарий от i-rinat

Ты проверял? Рекомендую проверить сейчас, потому что твои убеждения ложны.

Какая-то подлянка. Какая разница с стеком внутри функции и указателем на стек из вне функции? С ядром фокус пока не понял, но у меня с 32-bit такой древний gcc, что думаю, что проще посыпать голову пеплом, чем всерьёз разбираться.

vodz ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.