1

Function __libc_start_main is defined in libc.so with below function signature

void __libc_start_main(  int (*main) (int, char * *, char * *),
                    int argc, char * * ubp_av,
                    void (*init) (void),
                    void (*fini) (void),
                    void (*rtld_fini) (void),
                    void (* stack_end)); 

In normal usage, this function is called by function _start which is defined in C RunTime object crt1.o.

Questions:

  1. Is it possible to call __libc_start_main in C code?

Difficulties:

  1. I could not find a way to determine the value of last argument stack_end in C code. The implementation of crt1.o is in assembly, which is able to determine stack_end.

PS: I am just curious if we are able to call __libc_start_main in C code.

Zhongkun Ma
  • 421
  • 2
  • 9

1 Answers1

0

In general, this is not possible because __libc_start_main must only be called once per process, and if you try to call it from C code, it will already have run or will be invoked later, a second time. Neither will work reliably, and future glibc changes may break such code.

You should post a new question with the actual problem you are trying to solve.

Florian Weimer
  • 32,022
  • 3
  • 48
  • 92
  • As mentioned in my question, it is only for my curiosity and I am not solving any problem, mainly for education purpose. I agree with you ```__libc_start_main``` must only be called once per process. In my test case, I also provider function ```_start``` myself instead of using the ```_start``` from C run time. Function ```__libc_start_main``` is called from my ```_start```, I hope this make sure function ```__libc_start_main``` is only called once in my process. Thanks for your reply. – Zhongkun Ma Mar 22 '20 at 09:48
  • Oh. You should not replace the `_start` with glibc, such changes may break with future glibc version. You really have to link with the CRT files that come with glibc. – Florian Weimer Mar 22 '20 at 11:19
  • Thanks for your reply, but there is one thing I do not agree with what you say. The ```_start``` does not belong to ```libc```. ```_start``` is the entry point of the application, which can be provided by the user. Most implementation of ```_start``` is purely to call ``` __libc_start_main``` from ```libc```. If we can call ```__libc_start_main``` correctly, I do not see any problem of to use the customized ```_start```. However, it is not recommended to do so in practice. I ask the question manly for my education purpose. – Zhongkun Ma Mar 22 '20 at 12:08
  • In current glibc, the CRT file which contains the definition of `_start` does more than just calling `__libc_start_main`. It also runs the ELF constructors for the main program (for historic reasons). Overriding `_start` will have to adapted if glibc behavior changes (for new binaries, old binaries will continue to keep running unchanged). – Florian Weimer Mar 22 '20 at 12:41
  • Sorry about what I said, based on https://stackoverflow.com/questions/29694564/what-is-the-use-of-start-in-c, the ELF constructors are called by function ```__libc_start_main```, is this changed in the ```current glibc```? – Zhongkun Ma Mar 22 '20 at 12:54
  • The startup file contains a callback function which invokes the ELF constructors, and passes its address to `__libc_start_main`. – Florian Weimer Mar 22 '20 at 12:59