ld Линкер под MinGW

Тема в разделе "WASM.BEGINNERS", создана пользователем ENRIX, 11 июл 2007.

  1. ENRIX

    ENRIX New Member

    Публикаций:
    0
    Регистрация:
    30 мар 2007
    Сообщения:
    10
    Пытаюсь собрать два .o файла(c.o и kernel.o первый это ELF формат собранный в fasm, второй это "C" сорц собранный на gcc(тоже из MinGW) с параметром --ffreestanding)

    Почему-то под Linux все нормально собирается, а программа из MinGW - ld(Linker Dynamic) не пашет.
    В чем дело?

    вот сборка кода

    ..\fasm c.asm -m 65536
    C:\MinGW\bin\gcc -ffreestanding -c -o kernel.o kernel.c
    C:\MinGW\bin\ld --oformat binary --section-start ".text"=0x200000 -o kernel1.bin c.o kernel.o

    ld пишет следующие
    C:\MinGW\bin\ld: cannot perform PE operations on non PE output file 'kernel.bin'

    если вместо binary формата указать pei-i386

    c.o: In function 'go':
    (.flat+0x6): undefined reference to 'k_main'

    Хотя все это прекрасно линкуется под Linux(на родном ld)
     
  2. Mika0x65

    Mika0x65 New Member

    Публикаций:
    0
    Регистрация:
    30 июл 2005
    Сообщения:
    1.384
    Чтобы ld мог собирать не PE файлы его необходимо скомпилировать с соотвествующими опциями. Подробнее можно прочитать здесь.
    Скорее всего, ф-ии kernel.c были скомпилированы с конвенцией stdcall, которая помещает символ '_' в начале имени ф-ии + кое-что в конце. Чтобы этого не происходило ей необходимо дать конвенцию cdecl (и при этом учесть, что стек нужно почистить самому), либо использовать кросс-компилятор (по ссылке выше). nm поможет посмотреть, как именно названа ф-ия в файле kernel.o.
     
  3. ENRIX

    ENRIX New Member

    Публикаций:
    0
    Регистрация:
    30 мар 2007
    Сообщения:
    10
    Спасибо что ответили на мой вопрос...

    Интересно где можно взять сорцы ld который под винду... если он шел в пакете binutils под MinGW

    Пишет что названа _k_main(а в сорцах просто k_main) видимо оно и значит что там stdcall(вроде как ето значит что параметры пихаются в стек в другом порядке, но что ето еще значит раз компил ругается).

    Что же вы предлагаете....? использовать кросс компилятор? а что же с ld(как мне линковать)

    Кстати получается что в Linux версии того же gcc компиляция идет без stdcall по дефолту? или как?
     
  4. Mika0x65

    Mika0x65 New Member

    Публикаций:
    0
    Регистрация:
    30 июл 2005
    Сообщения:
    1.384
    Взять binutils можно здесь.

    Как компилировать описано в статье.

    Можно попробовать применить опцию gcc '-fno-leading-underscore', но мне она когда-то не помогла, не знаю почему. stdcall кладет параметры в стек в том же порядке, что и cdecl, разница между ними в том, что в stdcall вызываемая ф-ия сама чистит стек с помощью инструкции 'ret N', а в cdecl стек чистит вызывающая ф-ия.

    Да, самое простое -- использовать кросс компилятор, и вместе с ним перекомпилировать ld.

    В Linux gcc был скомпилирован с опцией другой целевой платформы -- 'elf32-i386'. Почему mingw ld не может собирать файлы для другой целевой платформы, я не очень понимаю, это вопрос скорее в WASM.UNIX, но знаю, что проблема решается с помощью кросс-компилятора и перекомпилированных binutils (в состав которого входит ld).