Линковка двух объектников

Тема в разделе "WASM.BEGINNERS", создана пользователем Aoizora, 24 окт 2017.

  1. Aoizora

    Aoizora Active Member

    Публикаций:
    0
    Регистрация:
    29 янв 2017
    Сообщения:
    351
    Изучая системные вызовы, решил написать свою обертку для вызова write на Си. Получился вот такой код:

    write.c
    Код (C):
    1.  
    2. #include <stddef.h>
    3.  
    4. void write(void *data, size_t size)
    5. {
    6.     asm("mov $4, %eax");
    7.     asm("mov $1, %ebx");
    8.     asm("mov data, %ecx");
    9.     asm("mov size, %edx");
    10.     asm("int $0x80");
    11. }
    main.c
    Код (C):
    1.  
    2. #include <stddef.h>
    3.  
    4. extern void write(const void *, size_t);
    5.  
    6. int main(void)
    7. {
    8.     const char *msg = "hello";
    9.     const size_t size = 5;
    10.  
    11.     write(msg, size);
    12. }
    Генерирую объектники: gcc -c write.c и gcc -c main.c, потом линкую: ld main.o write.o, однако я получаю ошибку:

    Что я делаю не так?
     
  2. Rel

    Rel Well-Known Member

    Публикаций:
    2
    Регистрация:
    11 дек 2008
    Сообщения:
    5.242
    не используй ld на прямую, юзай gcc обертку... он не может у тебя найти точку входа, которая формально объявлена в CRT, а она уже вызывает main функции в зависимости от того, какой исполняемый файл ты просишь получить... и опять же формально точка входа должна быть int main(int argc, char** argv) и возвращать 0 в случае успеха выполнения консольной программы... если хочешь не использовать CRT, а вызывать твою точку входа на прямую, то она должна быть вида int start() и ты должен указать "-nostdlib" параметр для gcc... имя функции (мангленное) можно указать параметром gcc "-E<имя_точки_входа>"...
     
  3. Aoizora

    Aoizora Active Member

    Публикаций:
    0
    Регистрация:
    29 янв 2017
    Сообщения:
    351
    Изменил сигнатуру точки входа на сишную:

    Код (C):
    1. #include <stddef.h>
    2.  
    3. extern void write(const void *, size_t);
    4.  
    5. int main(int argc, char **argv)
    6. {
    7.     const char *msg = "hello";
    8.     const size_t size = 5;
    9.  
    10.     write(msg, size);
    11. }
    Но теперь у меня другая ошибка:

     
  4. Rel

    Rel Well-Known Member

    Публикаций:
    2
    Регистрация:
    11 дек 2008
    Сообщения:
    5.242
    ну так тебе линкер уже все сказал, что не понятного то?
     
  5. Aoizora

    Aoizora Active Member

    Публикаций:
    0
    Регистрация:
    29 янв 2017
    Сообщения:
    351
    Эм, затрудняюсь интерпретировать вывод линкера. Я неправильно использую параметр функции write в ассемблерной вставке?
     
  6. Rel

    Rel Well-Known Member

    Публикаций:
    2
    Регистрация:
    11 дек 2008
    Сообщения:
    5.242
    "recompile with -fPIC" - перекомпилируй с ключем -fPIC... что тут интерпретировать?