I know that from the point of view of the C programming language
main() is the entry point of the program.
But from the point of view of the operating system is __start at ctrt0 startup routines which are linked into a program that performs any initialization work required before calling the program's main() function (correct me if wrong here).
So we have some attributes which we can use for our functions, one of them is
constructor attribute which is called before main(), who is responsible to call this function?
__attribute__((construtor))
void foo(void)
{
puts("Constructor called by ... ?\n");
}
and how would it look in step by step call stack? Thanks!
Functions marked as "constructor" are placed in a special section in the executable file. The "start" function will then invoke those functions one by one, before it calls main.
The same with "destructor" functions, they are again placed in a special section and called by the code executing after exit is called or main returns.
Related
I've been running into a minor problem with regards to seeing people, currently helping a teacher out through grading, and seeing people declaring functions within the scope of main, instead of within the global scope, as I was taught to do, I understand that this still works in itself, but I am kind of confused as to what happens with these functions, should a function be called, that was declared in main, in another function that is not declared inside said main, would this in itself work, and if it does, why. Isn't the function within only the scope of main, and as such shouldn't it remain local to it, or dies C just allocate the space in memory for the functions call at a global scope from the time it is declared, and subsequently defined? Know I was rambling a bit on this, trying to cover all possible questions within this scope.
Sample of what I mean.
int main(){
void foo(int bar);
int boo;
foo(boo);
return 0;
}
void foo(int bar){
...
}
The point that I was trying to stress is that the functions are usable due to the fact that they are related, through main if that makes any sense, but should a function be declared on the global scope such as
#include <stdio.h>
void roo(void);
int main(){} //Holds the same syntax as above with the function declared within it.
//Function foo is same as defined prior.
//Then function roo is defined but uses foo within itself.
void roo(void){
int boo;
foo(boo);
...
}
Shouldn't the codes being compounded, not work fully since the function roo technically has no way to access the function within the scope of main?
edit --
I somewhat saw a point that main would be, with the current lack of multiple functions to be called, would still be at the time used to call function roo, but should this contain multiple functions then wouldn't it be kind of weird or not syntax legal to call up foo from within roo, if it were scaled about 6 functions outside from main.
Declarations are needed for type checking and linking. They exist at compile-time only - they don't actually create an "object" (such as a function body) that exists in any way in the compiled program - all they do is put a name on it, so that other parts of the source can refer to that object without having it immediately to hand. Definitions create objects, but declarations create names.
Going through your example:
void roo(void); // roo becomes visible
int main(){ // main is defined, AND becomes visible
void foo(int bar); // foo becomes visible
foo(6);
roo();
} // foo is no longer visible
void foo(int bar){ /**/ } // foo is defined AND becomes visible
void roo(void){ // roo is defined, but was already visible
foo(6); // so this has no effect on other functions
}
roo can be called from any code in the program below where it was declared, because its name has been put in global scope and is visible from all nested scopes. The following code is aware that somewhere (no idea where), a function called roo exists and is available for use.
Moving down into main, a new scope is opened, and foo made visible within it. main uses this information to call to foo. It uses the information in the global scope to call to roo. The scope closes with the end of main and foo ceases to be visible to the following code; it is not aware that any such function exists.
foo is the simultaneously defined and declared in the global scope. All following code is aware that a function called foo is available for use.
Similarly for roo.
The only places anything is given space in memory are at the three points of definition. None of the declarations cause anything to be allocated, statically or otherwise. All they do is make the code aware of an allocation elsewhere (to be resolved by the linker).
So to (what I think was) the original point of confusion: main calls roo, and roo calls foo, but the declaration of foo in main is not visible to roo. (It sounds like you're confusing static and dynamic semantics: C has static scope only.)
This isn't a problem, because main doesn't know the content of roo, and doesn't need to know its content (some compilers perform inlining; we don't care about that). Control leaves the body code of main and goes to a different point in the program. The body of a function is a black box to every other function; what happens within the code of roo is completely unknown to every other function. roo also doesn't inherit the scope of main, so it has no knowledge of anything that was declared at that time (globally, locally, or otherwise) - it uses the scope opened and closed by its own body further down for name lookups. In that scope, foo has already been declared globally (it inherits the global scope at a separate fixed point on the page), so roo can see foo of its own accord.
Each function exists in one (and exactly one) place. All declarations do is make that place visible to the code that uses it. Code that doesn't use it, doesn't need to be able to see it. main can't see the nested call to foo, so any declaration at that point isn't relevant to it.
Which functions are called prior to DllMain()? If more than one during the C runtime initialization, then the order is important.
From the source:-
If your DLL is linked with the C run-time library (CRT), the entry
point provided by the CRT calls the constructors and destructors for
global and static C++ objects. Therefore, these restrictions for
DllMain also apply to constructors and destructors and any code that
is called from them.
I think only _DllMainCRTStartup() is called, which in turns calls all constructors of global C++ objects (none in the case of C) and (I'm not sure of that last one) calls DllMain().
Of course, it also calls some Kernel32 functions to initialize the CRT (for starters, it needs to allocate some memory and a TLS slot).
This is very compiler dependent.
DllMain() has exactly the same calling convention as the DLL's entry point so for some compilers DllMain() is the entry point of the DLL!
Other compilers use their own entry point where some DLL initializations are done before entering DllMain().
In contrast to this the entry point of an EXE file does not have any arguments and the function must never return. Therefore the WinMain() or main() function cannot be the entry point of an EXE file but there must be some preparation code that is called before WinMain() or main().
Is it possible to conditionally replace a function at runtime in C (in particular, a function in a dynamically loaded library)?
I know that you can use LD_PRELOAD or just make a function of the same name, such as:
// Silly example intercepting exit
typedef void (*exit_func)(int code);
void exit(int code)
{
exit_func orig_exit = (exit_func)dlsym(RTLD_NEXT, "exit");
NSLog(#"EXIT CALLED WITH CODE %d!!!!", code);
orig_exit(code);
}
However, is it possible to CONDITIONALLY replace a function, at runtime, after the program has loaded and is running?
if(some_condition)
{
swap_impementations(exit, my_exit);
}
Edit: This is somewhat similar to Is it possible to swap C functions? but specifically, I am trying to intercept a call to a function from a different library that was loaded by the operating system.
What this means is that, for example, were I to intercept the exit() function from stdlib, ANY call to exit() from ANYWHERE would call my implementation instead of the original, much like my example above, except controllable at runtime.
There have been suggestions of hooking the call by overwriting the original with a jump instruction, but I was hoping for something that doesn't require stomping on executable memory, like perhaps there was something I could call in the dynamic linker to "re-link" the function after the program starts and point it somewhere else?
Use function pointer for this purpose.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
What should main() return in C/C++?
#include<stdio.h>
int main()
{
return 0;
}
In the code snippet given above, where does the return 0 returned by main go? Or in other words which function called the main function in the beginning.
main is called by some startup function in the C runtime library. The C language standard says that returning from main is equivalent to calling the exit function, so most C runtimes look something like this:
void _start(void) /* Exact function signature may vary */
{
/* Platform-specifi startup (e.g. fetch argc and argv from the OS) */
...
int status = main(argc, argv);
exit(status);
/* Never reached */
}
The exit status gets passed back to the operating system, and then what happens from there is OS-dependent.
When you compile and link your program, the executable file format (e.g. PE or ELF) contains a start address, which is the virtual address at which execution begins. That function is typically part of the C runtime library (like the example _start above). That function has to end by calling a system call such as exit, since if it just returned, it would have nowhere to go to: it would just pop an address off the stack and jump to that location, which would be garbage.
Depending on how the OS loader initializes processes, the program arguments argc, argv, and other data (such as the environment) might either come in as function parameters (either through registers or the stack), or they might require system calls (e.g. GetCommandLine on Windows) to retrieve them. But dealing with all of that is the job of the C runtime, and unless you're explicitly going out of your way to avoid using the C runtime, you needn't worry about those details.
Your compiler targets a certain platform, which includes operating-system specific mechanisms for starting processes. Part of that platform specific code contains the return value of main. When you link your program into an executable, there is an OS-specific piece of binary code that your linker adds which takes care of calling main and reporting the return value back to the operating system.
The return value goes to the hosted environment. Typically, operating system calls main and gets exits status of the program.
where does the return 0 returned by main go? Or in other words which function called the main function in the beginning.
It is called by the C startup library, a stub function that is called (almost) directly by the kernel. For example, on Linux and OS X, it's a function named _start. It has the same signature as main() and the operating system itself uses its return value.
I am building a debugging memory tool in a form of a shared library which I link against an executable at run time(includes overrided methods of malloc family). To handle initializations of my data structures I simple use a condition variable. Every time my malloc is called I check if the variable is not set and then I call a function responsible for initializing my structures. Now this works fine for programs running a single thread of execution but problems arise if a program includes more than 1 thread.
The only way (I can think of) to be sure that initialization happens before the user spawns any threads is to override _init as shown in this link.
Now this small example runs right but when I try to override _init on my own shared libary I get this error when trying to link it :
memory2.o: In function `_init':
memory2.c(.text+0x0): multiple definition of `_init'
/usr/lib/gcc/i686-linux-gnu/4.4.5/../../../../lib/crti.o(.init+0x0):
first defined here
collect2: ld returned 1 exit status
I use exactly the same steps as in the example from the link, it's just that my shared library also includes a set of global variables and overrided versions of malloc/free etc.
Anyone can give me a pointer of what's going wrong? Furthermore , is there anything else to take into consideration when overriding _init ( I am guessing it's not a very normal thing to do).
Thank you
Take a look at the following FAQ page:
http://www.faqs.org/docs/Linux-HOWTO/Program-Library-HOWTO.html#INIT-AND-CLEANUP
It describes _init/_fini as dangerous and obsolete, and recommends that __attribute__ ((constructor)) and __attribute__ ((destructor)) are used instead.
From the gcc manual:
constructor (priority)
destructor (priority)
The
constructor attribute causes the
function to be called automatically
before execution enters main().
Similarly, the destructor attribute
causes the function to be called
automatically after main() has
completed or exit() has been called.
Functions with these attributes are
useful for initializing data that will
be used implicitly during the
execution of the program. You may
provide an optional integer priority
to control the order in which
constructor and destructor functions
are run. A constructor with a smaller
priority number runs before a
constructor with a larger priority
number; the opposite relationship
holds for destructors. So, if you have
a constructor that allocates a
resource and a destructor that
deallocates the same resource, both
functions typically have the same
priority. The priorities for
constructor and destructor functions
are the same as those specified for
namespace-scope C++ objects (see C++
Attributes).
These attributes are not currently
implemented for Objective-C.
1) You can write your own _init or main:
GNU GCC allows you to define your own function of the same name as an existing symbol. When linking, you provide an argument of -Xlinker --wrap=<symName>. Pretending you did this to main, you can call the real main via __real_main(...):
int main(int argc, void *argv)
{
// any code you want here
return __real_main(argc,argv);
}
2) You can write your own dynamic linker. If you do this then set the .interp section to point to the shared object containing your dynamic linker/loader.
To overcome that error compile the code as gcc -nostartfiles memory2.c -o memory2, here we are skipping the constructor and destructor.
But it is not recommended to override these.