Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why do I have to use ld to link my binary

Tags:

linux

elf

nasm

I'm doing a little "Hello World" program in NASM to run on my Ubuntu machine (uname -a output included below):

 $uname -a
Linux desk069 4.15.0-66-generic #75-Ubuntu SMP Tue Oct 1 05:24:09 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux

Now after saving this to a file, I have to run

nasm -f elf64 ./test. ./test.nasm -o test.o
ld -o test test.o -m elf_x86_64

In order for my code to work. Attempting to run test.o gives me

bash: ./test.o: cannot execute binary file: Exec format error

and attempting to make NASM generate a bin file gives me:

$nasm -f bin ./test.nasm -o test.bin
$chmod +x ./test.bin
$./test.bin
bash: ./test.bin: cannot execute binary file: Exec format error

My question is, I'm not using any libraries. Why do I have to use the linker ld? What exactly is wrong with the bin file? Can I do something to make it run without ld?

My code is included below.

section .text
    global _start

section .data
msg db 'Hello, world!', 0xa 
len equ $- msg 

section .text

_start:

    mov edx, len 
    mov ecx, msg 
    mov ebx, 1
    mov eax, 4
    int 0x80

    mov ebx, 0
    mov eax, 1
    int 0x80
like image 818
Cedar Avatar asked Sep 20 '25 00:09

Cedar


1 Answers

Why do I have to use the linker ld?

You don't have to use ld, but it's much easier to use it than not (see below).

What exactly is wrong with the bin file?

Nothing in the .bin file tells the OS how to load and run it.

At what address should the OS map this file into memory? Where should it set the RIP register to start executing it?

When you create a program which will run on a "bare metal" system, you can arrange for this program to be loaded at exactly the processor reset address, and the processor will start fetching and executing instructions from that address when it is powered on.

But you aren't trying to do that -- you are using Linux, and it needs to be told where to load the program and how to start it.

Usually this info is supplied by the ELF file header and program headers (which the linker prepares), although Linux can execute other file formats as well.

Can I do something to make it run without ld?

Sure. You can supply all the ELF header and program header bits without involving a linker at all. Example. It's just much harder to do correctly, and to debug when things go wrong.

like image 162
Employed Russian Avatar answered Sep 22 '25 19:09

Employed Russian