Невозможно связать файл сборки в Mac OS X с помощью ld - PullRequest
11 голосов
/ 05 августа 2011

Я пытаюсь запустить базовый файл сборки, используя 64-битную Mac OS X Lion, используя nasm и ld, которые по умолчанию устанавливаются вместе с Xcode.

Я написал файл сборки, который печатает символ, иЯ получил его для сборки, используя nasm.

nasm -f elf -o program.o main.asm

Однако, когда я иду связать его с ld, он терпит неудачу с довольно многими ошибками / предупреждениями:

ld -o program program.o

ld: warning: -arch not specified
ld: warning: -macosx_version_min not specificed, assuming 10.7
ld: warning: ignoring file program.o, file was built for unsupported file format which is not the architecture being linked (x86_64)
ld: warning: symbol dyld_stub_binder not found, normally in libSystem.dylib
ld: entry point (start) undefined.  Usually in crt1.o for inferred architecture x86_64

Итак, я попытался исправить некоторые из этих проблем и ничего не получил.

Вот одна из вещей, которые я пробовал:

ld -arch i386 -e _start -o program program.o

То, что я думал, сработает, но я ошибся.

Как сделать объектный файл совместимой архитектурой, с которой согласуются nasm и ld?Кроме того, как бы вы определили точку входа в программу (сейчас я использую global _start в .section text, что выше _start, что, кажется, не очень хорошо.)

Я немного сбит с толку относительно того, как вы могли бы успешно связать объектный файл с двоичным файлом, используя ld, и я думаю, что мне просто не хватает некоторого кода (или аргумента для nasm или ld), который заставит их согласиться.

Любая помощь приветствуется.

Ответы [ 4 ]

5 голосов
/ 15 сентября 2011

ОК, просматривая ваши образцы, я предполагаю, что вы использовали универсальное руководство по сборке nasm или linux.
Первое, о чем вам нужно позаботиться, это двоичный формат, созданный nasm.
Ваше сообщение гласит:

ld: warning: ignoring file program.o, file was built for unsupported file format which is not the architecture being linked (x86_64)

Это результат параметра ' -f elf ' , который сообщает nasm, что вы хотите 32-битный объект ELF (что, например, относится к linux),Но поскольку вы работаете в OSX, вам нужен объект Mach-O.

Попробуйте выполнить следующее:

nasm -f macho64 -o program.o main.asm
gcc -o program program.o

Или, если вы не хотите создавать 32-разрядный двоичный файл:

nasm -f macho32 -o program.o main.asm
gcc -m32 -o program program.o

Относительно _start символ - если вы не хотите создавать простую программу, которая сможет использовать предоставленные системные функции libc, вам не следует использовать _start в al.Это точка входа по умолчанию ld будет искать, и обычно она предоставляется в вашей libc / libsystem.

Я предлагаю вам попробовать заменить _start в вашем коде на что-тонапример '_ main' и связать его, как в приведенном выше примере.

Общий шаблон сборки на основе libc для nasm может выглядеть следующим образом:

;---------------------------------------------------
.section text
;---------------------------------------------------
use32             ; use64 if you create 64bit code
global _main      ; export the symbol so ld can find it

_main:
    push ebp
    mov  ebp, esp ; create a basic stack frame

    [your code here]

    pop ebp       ; restore original stack
    mov eax, 0    ; store the return code for main in eax
    ret           ; exit the program

В дополнение к этому я должен упомянуть, что при любых вызовах , которые вы делаете в OSX, необходимо использовать выровненный кадр стека, иначе ваш код просто рухнет.
Есть также несколько хороших руководств по этому вопросу.- попробуйте поискать руководство по сборке OSX.

5 голосов
/ 30 декабря 2011

Вам нужно использовать global start и start:, без подчеркивания . Кроме того, вы не должны использовать elf в качестве арки. Вот скрипт bash, который я использую для сборки своих программ NASM для x86-64 в Mac OS X:

#!/bin/bash

if [[ -n "$1" && -f "$1" ]]; then
    filename="$1"
    base="${filename%%.*}"
    ext="${filename##*.}"

    nasm -f macho64 -Ox "$filename" \
    && ld -macosx_version_min 10.7 "${base}.o" -o "$base"
fi

Если у вас есть файл с именем foo.s, этот скрипт сначала запустится

nasm -f macho64 -Ox foo.s

Который создаст foo.o. Флаг -Ox заставляет NASM выполнять дополнительную оптимизацию с помощью прыжков (то есть делать их короткими, ближними или дальними), чтобы вам не пришлось делать это самостоятельно. Я использую x86-64, поэтому мой код 64-битный, но похоже, что вы пытаетесь собрать 32-битный. В этом случае вы должны использовать -f macho32. См. nasm -hf для получения списка допустимых форматов вывода.

Теперь объектный файл будет связан:

ld -macosx_version_min 10.7 foo.o -o foo

Я установил параметр -macosx_version_min, чтобы отключить NASM и предотвратить предупреждение. Вам не нужно устанавливать его на Lion (10.7). Это создаст исполняемый файл с именем foo. Если вам повезет, наберите ./foo и нажмите Enter, чтобы запустить вашу программу.

Что касается предупреждения ld: warning: symbol dyld_stub_binder not found, normally in libSystem.dylib, я получаю его также каждый раз, и я не уверен, почему, но все выглядит нормально, когда я запускаю исполняемый файл.

2 голосов
/ 05 августа 2011

Вероятно, проще просто gcc сделать тяжелую работу за вас, а не пытаться управлять ld напрямую, например

$ gcc -m32 program.o -o program
1 голос
/ 03 декабря 2015

Компилятор Mac gcc не будет связывать объекты elf.Вам нужен кросс-компилятор ...

http://crossgcc.rts -software.org / doku.php? Id = compiling_for_linux

Затем вы можете приступить к чему-то похожему на это...

/usr/local/gcc-4.8.1-for-linux32/bin/i586-pc-linux-ld -m elf_i386 -T link.ld -o kernel kasm.o kc.o
...