6

Each program has a main() and the program execution starts from there. Is it possible to write a program without main()and make another function as the entry point? If so, can any one please tell me how can that be done? I am using Linux?

4
  • 7
    What are you trying to accomplish by not having main as your entry point? Commented Mar 13, 2012 at 1:55
  • 1
    @eduffy was reading a book on C where it had mention main() is just a function as many other functions so got this doubt, Commented Mar 14, 2012 at 4:48
  • Check out this article, linuxgazette.net/issue84/hawk.html, to see what happens before main() is called. Commented Mar 14, 2012 at 13:04
  • Check here. You can also go crazy and write your own assembly, if you want to have fun. Commented Jul 27, 2020 at 3:24

3 Answers 3

6

If you're compiling with gcc, specifying -e <symbol> option will let you change the entry point to a function symbol().

Sign up to request clarification or add additional context in comments.

3 Comments

This will likely badly break things since it will bypass startup code that the standard library will assume has already run...
Sure, but this answers the question "is it possible to write a function without main() and make other function as entry point ? if so can any one pls tell me how can tht be done. I am using linux", not "how can I change the entry point to a C program and avoid breaking things badly".
Fair enough. It's more a comment to OP not to do this than a critique of your answer.
0

There is a solution for build executable shared library that you can build a program use another function as entry point.

The code looks like:

#include <stdio.h>
#include <stdlib.h>
const char __invoke_dynamic_linker[] __attribute__ ((section (".interp"))) 
    = "/lib/ld-linux.so.2";
void fun()
{
    printf("This is fun./n");
    exit(0);
}

Then build your program as an shared library and specify func as entry point:

$ gcc -fpic -shared -o fun.so -Wl,-e,fun fun.c
$ ./fun.so

The problem of this way is that the func can't have the normal arguments as we have in main function, this is because we don't have the c library to initialize the main arguments stuff.

3 Comments

Your suggestion seems even more vague than the question. Do you mean to say that the entry function should be in a dynamically linked library, so that its address can be looked up by name?
@GeorgeSkoptsov it needs not to be a dynamically linked library, it could be in the program itself only if you need not remove the symbols info or you can hard code to compares the argument with some known functions symbols. I think Manu just want the program to call different functions.
Not sure why this got a down vote. If I'd found this answer, it wouldn't have taken me so long to figure this out: stackoverflow.com/a/68339111/14760867
0

You can do this in a portable way, simply by including this header file in your main program:

int nomDePlume(int argc, char *argv[]);
int main(int argc, char *argv[]) { return nomDePlume(argc, argv); }

Then provide your own variant of main:

int nomDePlume(int argc, char *argv[]) {
    weaveYourMagic();
    return 42;
}

That doesn't actually change the entry point of the executable (something that's very much implementation specific) but it does let you call your program entry point whatever you wish (within the bounds of legal identifiers, of course).


If you don't want a main at all (even in a header file), it becomes a little tricky.

That's because the entry pount for an executable generally isn't main - there's quite a bit of activity happening before main is called, to do with environment setup and other things (and some tear-down stuff after main exits, such as your atexit handlers).

In other words, while the main function may be where your C program starts, that's not the same thing as where your executable starts.

As one example, in Linux, the ELF executable format contains an entry point address in the e_entry field of a header block, and that's where the program loader jumps to when it's ready to run the executable.

What usually happens to set this up is that you link (implicitly) with some start-up code like crt0 and the linker populates the e_entry field with the address of a known symbol. An example of which is (from that link, with comments slightly modified):

.text
.globl _start
_start:                       # Entry point known to linker.
    xor %ebp, %ebp            # RBP <- 0, mark end of stack frames.
    mov (%rsp), %edi          # Get argc from stack (implicitly
                              #   zero-extended to 64-bit).
    lea 8(%rsp), %rsi         # Take address of argv from stack.
    lea 16(%rsp,%rdi,8), %rdx # Take address of envp from stack.
    xor %eax, %eax            # Per ABI and compatibility with icc.

    call main                 # Three args %edi/%rsi/%rdx (first
                              #   two are C standard).

    mov %eax, %edi            # Effectively set up _exit(main()).
    xor %eax, %eax            # Per ABI and compatibility with icc.
    call _exit                # Terminate the program.

You can see there the start-up and tear-down stuff happening on either side of the main call, and therein lies a possible solution for you.

By creating your own crt0, replacing the text main with whatever you want to call, and ensuring the linker uses your crt0 rather than the default one, you can have it call whatever function you want to provide as the main one.


However, it's not really clear what you gain from being able to use an arbitrarily-named main function, other than to obtain job security or annoy your colleague when they can't find where your code begins :-)

If it's an educational thing, that's fine - I just wouldn't do this in a real-world situation.

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.