bug-glibc
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

can't use __libc_start_main() to redirect call to main()


From: Gary Funck
Subject: can't use __libc_start_main() to redirect call to main()
Date: Tue, 13 May 2003 21:46:39 -0700

While developing support for an experimental C language dialect, intended
for use in parallel computation applications, I ran into a problem with the
way __libc_start_main() calls the main program. The language definition
requires that certain runtime code be run ahead of the user's main program.
There are various ways this can be implemented. On the initial target
platform, SGI Irix, we used the linker's facility to specify an alternate
entry point via the -e switch. On Irix, this entry is apparently called
*after* the C runtime has been initialized, and is thus called with the
familiar (argc, argv, env) interface. Thus, it is easy to impose the runtime
system's "main" program ahead of the user's actual main program. On Linux,
and probably other Unix systems, the situation isn't so straightforward,
because -e <entry> appears to call <entry> as the first code to be run when
the process begins execution, before the C library environment has been
initialized. In Linux, this routine is known as _start and is located in
start.S, which in turn is incorporated in gcrt1.o.

My first cut at obtaining similar behavior to that on SGI was to modify
start.S,
in sysdeps/i386/elf/start.S, in a simple way:

        pushl %ecx              /* Push second argument: argv.  */
        pushl %esi              /* Push first argument: argc.  */

        pushl $BP_SYM (main)

        /* Call the user's main function, and exit with its value.
           But let the libc call main.    */
        call BP_SYM (__libc_start_main)

        hlt                     /* Crash if somehow `exit' does return.  */

by changing the reference from $BP_SYM (main) above to $BP_SYM (rts_main),
where rts_main
is the runtime code that must run, I'd hoped that this alternate main
program would
be called by __libc_start_main(). Note that I'm not trying to rebuild glibc
from scratch, but had simply planned on substituting my own gcrt1.o file.

However, it seems that __libc_start_main() ignores its parameter, "main",
and instead
calls "main" directly, by name:

  if (init)
    (*init) ();

#ifdef SHARED
  if (__builtin_expect (GL(dl_debug_mask) & DL_DEBUG_IMPCALLS, 0))
    _dl_debug_printf ("\ntransferring control: %s\n\n", argv[0]);
#endif

#ifdef HAVE_CANCELBUF
  if (setjmp (THREAD_SELF->cancelbuf) == 0)
#endif
    {
      /* XXX This is where the try/finally handling must be used.  */

      result = main (argc, argv, __environ);
    }
#ifdef HAVE_CANCELBUF
  else
    /* Not much left to do but to exit the thread, not the process.  */
    __exit_thread (0);
#endif

--------------------------------------------

if __libc_start_main() were to use a similar protocol that it used for the
init routine, then code above might appear as follows:

  if (main)
    result = (*main) (argc, argv, __environ);

It is certainly be possible for me to change libc-start.c to call the
runtime's main routine directly rather than modifying start.S, but the logic
in __libc_start_main() is more glibc specific, while start.S depends only
upon the OS's API, and the calling sequence of __libc_start_main (); that's
why it seemed a safer choice to make a simple mod to
gcrt.o and incorporate that into my app.

Netting it out, I'm curious, why doesn't __libc_start_main () [in glibc-2.3]
use the main program pointer?

Alternatively, I would've found it helpful if ld had, in cooperation with
glibc() had
a method for letting the user substitute their own main entry point, which
is called
in the conventional fashion, after the C library has initialized. Does such
a facility
exist in Linux?






reply via email to

[Prev in Thread] Current Thread [Next in Thread]