/* * This header implements the macro 'argcargv(int argc, char **argv)' that * sets its two arguments to the argument count and the argument vector, * respectively, regardless of: * * 1) the main function having been declared with or without (argc, argv). * 2) the location 'argcargv' is being called from. * * Thus, in a situation where main is declared as 'main() { ... }' and * we are in a function 'foo()' called from 'bar()' called from 'baz()' * ... called from 'main()', argcargv() will retrieve argc and argv. * * Caveat: valid only for the x86 architecture and needs GNU C. */ #ifndef _ARGCARGV_H #define _ARGCARGV_H 1 #if (!(defined(__i386__) && defined(__GNUC__))) #error "valid only for GNU C on the x86 architecture" #endif #define aa_EBP(r) __asm __volatile( \ "movl %%ebp, %0;" \ : "=g" (r) : \ ); #define aa_XREG(r, a) __asm __volatile( \ "movl (%1), %0;" \ : "=g" (a) : "g" (r) \ ); #define aa_AA(argc, argv, base) __asm __volatile( \ "movl 8(%2), %0;" \ "movl 12(%2), %1;" \ : "=g" (argc), "=g" (argv) : "g" (base) \ ); inline int __find_main_frame() { int base = 0, _base = 0, __base = 0; aa_EBP(__base); base = __base; DOXREG: aa_XREG(__base, _base); if (_base == 0x0) return base; else { base = __base; __base = _base; goto DOXREG; } } #define argcargv(argc, argv) aa_AA(argc, argv, __find_main_frame()) #endif /* _ARGCARGV_H */