Manually creating and running an executable file

Just for fun, I want to compile and run the simplest C program,

//tc int main() { return 0; } 

So I want:

  • $ cpp tc : should not do anything in this case, since no preprocessing is done
  • $ cc1 tc : compile tc β†’ ts
  • $ as -o to tc : build ts β†’ to
  • $ ld to : should create the a.out executable (there's nothing to be done)

The problem I ran into is as , since executing the final command gives:

 ld: warning: cannot find entry symbol _start; defaulting to 00000000000400b0 

What's happening? I specifically left libc to make it as simple as possible, but I don't understand what is going on. What flags am I missing?

+4
source share
2 answers

There, a little more is loaded and the program runs. As you can guess from the linker’s output, the execution does not start with main , but in _start , which is provided by the CRT library (C runtime), which comes with the compiler and is linked to your code behind the scenes.

Here and here are some information about what happens when the program starts on Linux.

Make cc -v -Wall in your dummy source to see all the necessary steps in detail.

+4
source

Since you said the simplest program, here is a real hack.

This is for Ubuntu 12.04 by running x86_64. If you have something else, then this may give you a clue what to do.

 mkdir hack_code cd hack_code cp /usr/lib/ldscripts/elf_x86_64.x ldsimple.x 

Now modify ldsimple.x to say ENTRY(main) instead of ENTRY(_start) at the beginning.

Create this mymain.c :

 int main(void) { __asm__ __volatile__ ( "movq $60, %rax\n" /* call sys_exit */ "movq $2, %rdi\n" /* return code */ "syscall" /* call kernel to exit program */ ); return 0; } 

And then:

 gcc -c mymain.c ld -o mymain -T./ldsimple.x mymain.o 

Voila: You now have a program that does not use a library, etc.

+2
source

Source: https://habr.com/ru/post/1483587/


All Articles