|
From: KJK::Hyperion <no...@li...> - 2002-05-15 00:00:47
|
... that I forgot to ask:
- is there some --do-exactly-what-i-say-and-not-what-you-think-i-need
switch? because no matter how many -no this and -fno that I put in the
command line, if a program happens to have a procedure called main, a big,
annoying static library is linked to the executable, adding an unnecessary
dependency from MSVCRT. That's why I had to call mymain() the main
procedure for testfork
- is it true that GCC creates a frame for all functions? because fork()
works like this:
clone current process
clone current thread
set clone thread's eip to point to a thunk routine that returns 0
run clone process
return clone process pid
Here's the thunk routine:
static const char * pcMsg = "I'm alive! I'm alive!\n";
/* child branch of fork() */
pid_t __PdxForkChildThunk(void)
{
__asm__
(
/* leave the current (superfluous) frame */
"leave\n"
/* hello world */
"pushl _pcMsg\n"
"call _DbgPrint\n"
"subl $4,%esp\n"
);
/* fork() returns 0 to the child */
return (0);
}
The rationale for that "leave" is that the (indirect) call to
__PdxForkChildThunk should act as a mere branch of fork(). I can't get a
label's address (can I?), so I had to stick with an extra function - but
that means that a second frame is created on top of fork()'s, right?. Does
this make sense to you? I'm not very good with assembly
|
|
From: Patrick M. <ox...@st...> - 2002-05-15 05:00:23
|
On Wed, May 15, 2002 at 01:33:11AM +0200, KJK::Hyperion wrote: > ... that I forgot to ask: > - is there some --do-exactly-what-i-say-and-not-what-you-think-i-need > switch? because no matter how many -no this and -fno that I put in the > command line, if a program happens to have a procedure called main, a big, > annoying static library is linked to the executable, adding an unnecessary doesn't "gcc -nostartfiles" work (probably with -nostdlibs or something like that? if not, it seems you have found a bug in the gcc-win32 port as that is how it should work... patrick mauritz -- ,------------------------------------------------------------------------. > In the Beginning there was nothing, which exploded - Yeah right... < |------------------------------------------------------------------------| > Moonlight 3D Resurrected | www.moonlight3d.net < `------------------------------------------------------------------------' Your right to swing your fist ends where my nose begins |
|
From: KJK::Hyperion <no...@li...> - 2002-05-18 17:13:43
|
At 07.00 15/05/2002, you wrote:
>On Wed, May 15, 2002 at 01:33:11AM +0200, KJK::Hyperion wrote:
> > ... that I forgot to ask:
> > - is there some --do-exactly-what-i-say-and-not-what-you-think-i-need
> > switch? because no matter how many -no this and -fno that I put in the
> > command line, if a program happens to have a procedure called main, a big,
> > annoying static library is linked to the executable, adding an unnecessary
>doesn't "gcc -nostartfiles" work (probably with -nostdlibs or something
>like that? if not, it seems you have found a bug in the gcc-win32 port as
>that is how it should work...
here's the build log:
gcc -I../../../include -nostdinc -fno-builtin -I./ -I../../../../../include
-pipe -march=i386 -c crthybrid.c -o crthybrid.o
gcc -I../../../include -nostdinc -fno-builtin -I./ -I../../../../../include
-pipe -march=i386 -c testfork.c -o testfork.o
gcc -nostartfiles -Wl,--subsystem,console \
-Wl,--entry,___PdxLdrEntry@4 \
-o testfork.nostrip.exe \
crthybrid.o testfork.o ../../../../../dk/w32/lib/ntdll.a
../../../../../dk/w32/lib/kernel32.a ../../../lib/psxdll/psxdll.a
../../../../../tools/rdel temp.exp
nm --numeric-sort testfork.nostrip.exe > testfork.sym
../../../../../tools/rcopy testfork.nostrip.exe testfork.exe
If testfork.c contains a function named main, testfork.exe is 15.7 KB, and
it imports MSVCRT!atexit. If the function is named, for example, mymain,
testfork.exe is 7.44 KB, and imports only functions I actually use. If I
use -nostdlib, that doesn't stop gcc from trying to slip in its static
library, but the compilation fails:
gcc -I../../../include -nostdinc -fno-builtin -I./ -I../../../../../include
-pipe -march=i386 -c crthybrid.c -o crthybrid.o
gcc -I../../../include -nostdinc -fno-builtin -I./ -I../../../../../include
-pipe -march=i386 -c testfork.c -o testfork.o
gcc -nostartfiles -nostdlib -Wl,--subsystem,console \
-Wl,--entry,___PdxLdrEntry@4 \
-o testfork.nostrip.exe \
crthybrid.o testfork.o ../../../../../dk/w32/lib/ntdll.a
../../../../../dk/w32/lib/kernel32.a ../../../lib/psxdll/psxdll.a
testfork.o(.text+0x43):testfork.c: undefined reference to `__main'
make: *** [testfork.nostrip.exe] Error 1
|
|
From: Patrick M. <ox...@st...> - 2002-05-18 17:19:02
|
On Sat, May 18, 2002 at 07:15:11PM +0200, KJK::Hyperion wrote: > At 07.00 15/05/2002, you wrote: > >On Wed, May 15, 2002 at 01:33:11AM +0200, KJK::Hyperion wrote: > >> ... that I forgot to ask: > >> - is there some --do-exactly-what-i-say-and-not-what-you-think-i-need > >> switch? because no matter how many -no this and -fno that I put in the > >> command line, if a program happens to have a procedure called main, a > gcc -I../../../include -nostdinc -fno-builtin -I./ -I../../../../../include > -pipe -march=i386 -c crthybrid.c -o crthybrid.o > gcc -I../../../include -nostdinc -fno-builtin -I./ -I../../../../../include > -pipe -march=i386 -c testfork.c -o testfork.o > gcc -nostartfiles -nostdlib -Wl,--subsystem,console \ > -Wl,--entry,___PdxLdrEntry@4 \ > -o testfork.nostrip.exe \ > crthybrid.o testfork.o ../../../../../dk/w32/lib/ntdll.a > ../../../../../dk/w32/lib/kernel32.a ../../../lib/psxdll/psxdll.a > testfork.o(.text+0x43):testfork.c: undefined reference to `__main' > make: *** [testfork.nostrip.exe] Error 1 well, you need your custom __main function then. usually it is in libgcc.a or crt0.o (dunno for sure and it depends on the version of gcc) and it sets up some stack and calls main(). and it seems like it uses atexit on mingw32 patrick mauritz -- ,------------------------------------------------------------------------. > In the Beginning there was nothing, which exploded - Yeah right... < |------------------------------------------------------------------------| > Moonlight 3D Resurrected | www.moonlight3d.net < `------------------------------------------------------------------------' do what thou whilst shall be the whole of the law love is the law, love under will there is no law beyond do what thou whilst |
|
From: KJK::Hyperion <no...@li...> - 2002-05-18 20:40:11
|
At 19.17 18/05/2002, you wrote:
> > testfork.o(.text+0x43):testfork.c: undefined reference to `__main'
> > make: *** [testfork.nostrip.exe] Error 1
>well, you need your custom __main function then.
erm... why exactly? I checked, and it's the damn *compiler* that inserts a
"call ___main" just after the stack frame setup in main():
.file "testmain.c"
gcc2_compiled.:
___gnu_compiled_c:
.def ___main; .scl 2; .type 32; .endef
.text
.align 4
.globl _main
.def _main; .scl 2; .type 32; .endef
_main:
pushl %ebp
movl %esp,%ebp
subl $8,%esp
call ___main
xorl %eax,%eax
jmp L2
.align 4
L2:
leave
ret
Why the hell does it do this? Why does the compiler try to be smarter than
me? How can I tell the compiler to compile *exactly* what I say, and not
generate useless/superfluous code? Borland C++ doesn't do it, for example:
.386p
ifdef ??version
if ??version GT 500H
.mmx
endif
endif
model flat
ifndef ??version
?debug macro
endm
endif
?debug S "testmain.c"
?debug T "testmain.c"
_TEXT segment dword public use32 'CODE'
_TEXT ends
_DATA segment dword public use32 'DATA'
_DATA ends
_BSS segment dword public use32 'BSS'
_BSS ends
DGROUP group _BSS,_DATA
_TEXT segment dword public use32 'CODE'
_main proc near
?live1@0:
;
; int main(void)
;
push ebp
mov ebp,esp
;
; {
; return (0);
;
@1:
xor eax,eax
;
; }
;
@3:
@2:
pop ebp
ret
_main endp
_TEXT ends
public _main
?debug D "testmain.c" 11442 44081
end
|
|
From: Casper H. <ch...@us...> - 2002-05-18 21:05:43
|
l=F8r, 2002-05-18 kl. 21:42 skrev KJK::Hyperion: > At 19.17 18/05/2002, you wrote: > > > testfork.o(.text+0x43):testfork.c: undefined reference to `__main' > > > make: *** [testfork.nostrip.exe] Error 1 > >well, you need your custom __main function then. >=20 > erm... why exactly? I checked, and it's the damn *compiler* that inserts = a=20 > "call ___main" just after the stack frame setup in main(): Try examining the way drivers on ReactOS are built. They have no main symbol. smss.exe is a native application and has no gcc runtime library linked with it. It's entry point is NtProcessStartup. |
|
From: KJK::Hyperion <no...@li...> - 2002-05-18 22:23:18
|
At 23.02 18/05/2002, you wrote: > > > > testfork.o(.text+0x43):testfork.c: undefined reference to `__main' > > > > make: *** [testfork.nostrip.exe] Error 1 > > >well, you need your custom __main function then. > > erm... why exactly? I checked, and it's the damn *compiler* that inserts a > > "call ___main" just after the stack frame setup in main(): >Try examining the way drivers on ReactOS are built. They have no main >symbol. smss.exe is a native application and has no gcc runtime library >linked with it. It's entry point is NtProcessStartup. That's not the problem. crthybrid.c, in my case, implements the entry point (__PdxLdrEntry, with the same signature as NtProcessStartup), then calls exit() with the return value of main() as parameter, because it's, as the name suggests, a static CRT for Win32-POSIX+ hybrids, that converts/imports the Win32 environment, invocation, standard file descriptors, current directory, etc. and then calls main() The idea is to have something clean and self-contained, and containing exactly what the code says, no more no less, because it's easier to debug The problem is that the C frontend of GCC *always* inserts a call to _main() at the beginning of all functions called main(), without me asking for, or even *wanting* it. I'll just insert a dummy _main() in crthybrid.c until it's fixed, but I *really* hate this |
|
From: Casper H. <ch...@us...> - 2002-05-19 10:04:03
|
s=F8n, 2002-05-19 kl. 00:13 skrev KJK::Hyperion: > That's not the problem. crthybrid.c, in my case, implements the entry poi= nt=20 > (__PdxLdrEntry, with the same signature as NtProcessStartup), then calls=20 > exit() with the return value of main() as parameter, because it's, as the= =20 > name suggests, a static CRT for Win32-POSIX+ hybrids, that converts/impor= ts=20 > the Win32 environment, invocation, standard file descriptors, current=20 > directory, etc. and then calls main() >=20 > The idea is to have something clean and self-contained, and containing=20 > exactly what the code says, no more no less, because it's easier to debug >=20 > The problem is that the C frontend of GCC *always* inserts a call to=20 > _main() at the beginning of all functions called main(), without me askin= g=20 > for, or even *wanting* it. I'll just insert a dummy _main() in crthybrid.= c=20 > until it's fixed, but I *really* hate this Try bringing this up on the gcc mailing lists. They probably have a reason for doing it. |
|
From: Rick P. <rfm...@sw...> - 2002-05-18 20:51:56
|
KJK::Hyperion wrote:
> Why the hell does it do this? Why does the compiler try to be smarter
> than me? How can I tell the compiler to compile *exactly* what I say,
> and not generate useless/superfluous code? Borland C++ doesn't do it,
> for example:
Just add an "extern int _main() { return 0; };" (or whatever the call
signature is). Would not suprise me if there is a switch to turn this off.
Only happens once per process activation so its not really a
performance issue
-rick
|
|
From: KJK::Hyperion <no...@li...> - 2002-05-18 22:23:22
|
At 22.47 18/05/2002, you wrote:
>>Why the hell does it do this? Why does the compiler try to be smarter
>>than me? How can I tell the compiler to compile *exactly* what I say, and
>>not generate useless/superfluous code? Borland C++ doesn't do it, for example:
>Just add an "extern int _main() { return 0; };" (or whatever the call
>signature is).
I'll do that, then. But I hate this
>Would not suprise me if there is a switch to turn this off.
AFAIK, no. I've examined the whole output of gcc -v --help, found nothing
useful
>Only happens once per process activation so its not really a performance issue
Of course no. But I can't accept a C compiler doing this
|
|
From: Rex J. <re...@lv...> - 2002-05-19 00:09:32
|
At 12:20 AM 5/19/02 +0200, you wrote: >At 22.47 18/05/2002, you wrote: > >>Would not suprise me if there is a switch to turn this off. > >AFAIK, no. I've examined the whole output of gcc -v --help, found nothing >useful You should check the info page for gcc to be sure there is not a flag. Also, just name your entry point something besides main perhaps? And by the way, I've had my share of problems with Borland's C compiler. >>Only happens once per process activation so its not really a performance >>issue > >Of course no. But I can't accept a C compiler doing this You should see about getting some drugs for this stress before you have a stroke. Rex Jolliff re...@lv... |
|
From: Steven E. <Ste...@ya...> - 2002-05-19 00:21:58
|
> You should see about getting some drugs for this stress > before you have a > stroke. Or laying off the drugs before your have a stroke =P "Every revolution was once a thought in one man's mind" - Ralph Waldo Emerson |
|
From: KJK::Hyperion <no...@li...> - 2002-05-19 18:26:16
|
At 02.09 19/05/2002, you wrote: >>>Would not suprise me if there is a switch to turn this off. >>AFAIK, no. I've examined the whole output of gcc -v --help, found nothing >>useful >You should check the info page for gcc to be sure there is not a flag. Negative. I had to explore the internals manual. I found out that, for executable formats not supporting initialization sections, __main calls the constructors for static C++ objects at startup, and the destructors before shutdown. I knew of this requirement for static CRTs (I read an article of Pietrek on MSDN Magazine on rolling your own CRT), but GCC is the only compiler I know of that inserts an explicit call to the initializator, instead of simply doing the initialization before calling main() >Also, just name your entry point something besides main perhaps? That's what I did. But this doesn't make the problem go away: sometime in the future, we'll need to provide a static CRT for POSIX+ programs. I'll try to add -lgcc, like the documents suggest, and implement atexit() in psxdll. That should do the trick >And by the way, I've had my share of problems with Borland's C compiler. We're not talking about Borland C |