Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

GNU Linker equivalent command in OS X

Tags:

macos

linker

ld

I'm reading the following book about operating systems. In Page 43, they use the following command to convert annotated machine code into a raw machine code file:

$ ld -o basic.bin -Ttext 0x0 --oformat binary basic.o

When running that command in my MacBook Pro (running Mavericks), I get:

ld: unknown option: -Ttext

I've did some research and found out that OS X's linker doesn't allow using a script file as the linker script.

Some other posts on the internet recommend using the following "correct" format:

$ ld -T text 0x0 --o format binary -o basic.bin basic.o

Although it didn't work for me neither.

I also tried installing binutils via homebrew, but it doesn't seems to ship with GNU linker.

The command correctly runs in Ubuntu 14.04, but I'd like to continue developing in OS X if possible.

Is there a way to obtain the same results with OS X's linker, potentially with different flags?

UPDATE:

I was able to generate a bin with the following command, using gobjcopy from binutils:

$ gobjcopy -j .text -O binary basic.o basic.bin

However I couldn't find a way to offset label addresses in the code, as I could with GNU ld with -Ttext 0x1000 for example.

I tried with --set-start <hex> without any luck:

$ gobjcopy -j .text --set-start 0x1000 -O binary basic.o basic.bin
like image 289
jviotti Avatar asked Sep 03 '14 01:09

jviotti


People also ask

Does macOS use GNU?

The macOS doesn't contain some GNU programs ( watch , wget , wdiff , gdb , autoconf ) and comes with BDS counterpart programs ( sed , tar , which , grep , awk , to name a few). Also, some GNU programs installed on macOS are outdated (e.g. bash , emacs , less , nano , etc.).

Is GCC a linker?

GCC uses a separate linker program (called ld.exe ) to perform the linking.

What is Ld macOS?

The ld command combines several object files and libraries, resolves references, and produces an ouput file. ld can produce a final linked image (executable, dylib, or bundle), or with the -r option, produce another object file. If the -o option is not used, the output file pro- duced is named "a.out".


2 Answers

I am following the same os-dev.pdf guide and encountered the same problem as you.

The bottom of the issue is that we need to compile a cross-compiled gcc anyway, so the solution is just to do so.

There is a good guide at OSDev but if you're running a recent version of OSX I prepared a specific guide for this on Github

Here are the commands, though please test them before pasting the whole wall of text on your computer! At the Github link you will find the full explanations, but since Stack Overflow seems to like the solution embedded on the answer, here it is.

Also, if you encounter any error, please report it back to me (here or with a Github issue) so that I can fix it for other people.

brew install gmp
brew install mpfr
brew install libmpc
brew install gcc

export CC=/usr/local/bin/gcc-4.9
export LD=/usr/local/bin/gcc-4.9

export PREFIX="/usr/local/i386elfgcc"
export TARGET=i386-elf
export PATH="$PREFIX/bin:$PATH"

mkdir /tmp/src
cd /tmp/src
curl -O http://ftp.gnu.org/gnu/binutils/binutils-2.24.tar.gz # If the link 404's, look for a more recent version
tar xf binutils-2.24.tar.gz
mkdir binutils-build
cd binutils-build
../binutils-2.24/configure --target=$TARGET --enable-interwork --enable-multilib --disable-nls --disable-werror --prefix=$PREFIX 2>&1 | tee configure.log
make all install 2>&1 | tee make.log

cd /tmp/src
curl -O http://mirror.bbln.org/gcc/releases/gcc-4.9.1/gcc-4.9.1.tar.bz2
tar xf gcc-4.9.1.tar.bz2
mkdir gcc-build
cd gcc-build
../gcc-4.9.1/configure --target=$TARGET --prefix="$PREFIX" --disable-nls --disable-libssp --enable-languages=c --without-headers
make all-gcc 
make all-target-libgcc 
make install-gcc 
make install-target-libgcc 

You will find GNU's binutils and your cross-compiled gcc at /usr/local/i386elfgcc/bin

like image 116
Carlos F. Avatar answered Oct 21 '22 00:10

Carlos F.


manually install binutils always throw errors in my macOS.

The solution is to use homebrew:

brew tap nativeos/i386-elf-toolchain 
brew install i386-elf-binutils i386-elf-gcc

then, you can use i386-elf-ld command instead of ld

like image 45
S.K. Avatar answered Oct 21 '22 02:10

S.K.