3

There are only two files, main.c and kernel.asm, and I tried to make a program with them using NASM and GCC. contents are as follows:

main.c

#include <stdio.h>

void Print_String() {
    printf("Hello World!\n");
}

kernle.asm

extern Print_String

[section .text]
global _start
_start:
    call Print_String

Compile and Link:

nasm -f elf -o kernel.o kernel.asm
gcc -c -o main.o main.c
ld -s -lc -o final kernel.o main.o

Then I run the final file with the command: ./final, but the result is depressing:

bash: ./final: No such file or directory

However, the current directory does have the file final, for the command ls, it displays:

final  kernel.asm  kernel.o  main.c  main.o

So why it cannot find the file final? Is there anything wrong? Any help appreciated!

4
  • 1
    Are you sure it's not a directory? "ls -l" will give you more info. It will tell you if it's a file or not, its size, its read/write/execute permissions. Commented Feb 14, 2013 at 3:46
  • @enhzflep It's really an executable file. ls -l displays:-rwxrwxr-x 1 mycityofsky mycityofsky 1584 Feb 14 11:15 final, mycityofsky is my user name. Commented Feb 14, 2013 at 3:52
  • the libc is expecting that a main is called, and is expecting that some tricky startup things are done (by crt0.o code). You should not use it without linking with gcc Commented Feb 14, 2013 at 6:49
  • You should consider using gdb and/or strace Commented Feb 14, 2013 at 20:50

3 Answers 3

4

It is not that it cannot find it, per se. The error message is somewhat misleading. The dynamic linker cannot resolve its dependencies, and thus your program image is not loadable (and not executable)

The problem is that you are dynamically linking against libc without any other of the paraphernalia to make dynamic linking actually work. Thus you are left with a binary image that cannot be loaded.

You might find that it's easier to statically link against libc. This can be done as follows:

ld -Bstatic -o final kernel.o main.o -lc

Notice you have to move the '-lc' bit after the code module main.o which uses it.

If you try this, you'll get a whole bunch of unresolved symbols. That's because you will also need to link against libgcc and libgcc_eh.

The following got me fairly close (apologies, working on a 64-bit system here):

ld -L/usr/lib/gcc/x86_64-linux-gnu/4.4.3/32/ -melf_i386 -Bstatic -lc -o final kernel.o main.o -lc -lgcc -lgcc_eh

This failed for me with

/usr/lib/gcc/x86_64-linux-gnu/4.4.3/32//libgcc_eh.a(unwind-dw2-fde-glibc.o): In function `_Unwind_Find_FDE':
(.text+0x193b): undefined reference to `dl_iterate_phdr'

Which doesn't make much sense. You may have more luck linking 32-bit on a 32-bit system.

Update

Apologies for the ramble above. I had a think about this again, and, of course, it is possible to make dynamic linking work. The missing piece is to specify the dynamic linker:

In my case, this was:

ld -dynamic-linker /lib32/ld-linux.so.2 -melf_i386 -o final kernel.o main.o -lc

So for you the following should work:

ld -dynamic-linker /lib/ld-linux.so.2 -o final kernel.o main.o -lc

Update again

In response to markzar's comment - you have to make a syscall to cleanly exit. This has the effect of doing something similar to exit(0) in C:

mov eax,1  ; Syscall #1       
mov ebx,0  ; Return code 0 = success
int 80H
Sign up to request clarification or add additional context in comments.

2 Comments

Thanks for your detail answer! It works! but it seems a little different with what I thought before. It displays two Hello World! and a message Segmentation fault (core dumped) :)
The issue there is that you are falling off the end of the world without cleanly exiting. Do a syscall like this to exit your program: mov eax,1 mov ebx,0 int 80H
1

Try this. First change kernel.asm as follows:

extern Print_String

[section .text]
global main
main:
    call Print_String

Then use the following commands to create the executable (instead of the linker).

nasm -f elf -o kernel.o kernel.asm
gcc -c -o main.o main.c
gcc -o final kernel.o main.o

Comments

0

Very simple: there is no main() to call in the program... thus whatever you do, the C-program-startup machinery doesn't get a hold.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.