#! /usr/bin/perl
# 
# $Id$
# Captive project doc Calling Types page Perl template.
# Copyright (C) 2003 Jan Kratochvil <project-www.jankratochvil.net@jankratochvil.net>
# 
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; exactly version 2 of June 1991 is required
# 
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
# 
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA


package project::captive::doc::CallType;
require 5.6.0;	# at least 'use warnings;' but we need some 5.6.0+ modules anyway
our $VERSION=do { my @r=(q$Revision$=~/\d+/g); sprintf "%d.".("%03d"x$#r),@r; };
our $CVS_ID=q$Id$;
use strict;
use warnings;

BEGIN{ open F,"Makefile"; our $top_dir=pop @{[split /\s/,(grep /^top_srcdir/,<F>)[0]]}; eval "use lib '$top_dir'"; close F; }
use My::Web;
require CGI;
BEGIN { Wuse 'project::captive::doc::Macros'; }


project::captive::doc::Macros->init(
		"__PACKAGE__"=>__PACKAGE__,
		"title"=>'Captive NTFS Developer Documentation: API Calling Conventions',
		"rel_prev"=>'APITypes.html.pl',
		"rel_next"=>'TODO.html.pl',
		);


print <<"HERE";


<a name="calltype"><h1>API Function Calling Conventions</h1></a>

	<p>Standard UNIX code compiled by GCC (GNU C&nbsp;Compiler) running on host
	$gnulinux always uses @{[ a_href 'CallType.html.pl#calltype_cdecl','cdecl' ]} ABI (Application
	Binary Interface) calling convention. This calling convention is also the
	default declaration type of UNIX functions.</p>

	<p>W32 uses three different calling conventions in its ABI. They are all
	described in the
	<a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vclang/html/_core_argument_passing_and_naming_conventions.asp"><span class="productname">Microsoft</span> documentation</a>.
	There is always necessary to have the proper function declaration
	(prototype) in the caller scope to prevent all sorts of unexpected
	crashes.</p>

	<p>Unfortunately some non-matching combinations of calling conventions
	result in hard to debug bugs: the caller gets back an unexpected stack
	pointer from the callee and upon return it will restore registers from the
	wrong stack pointer place. Since the caller will finally reclaim its stack
	frame from its (uncorrupted) <span class="constant">EBP</span> stack frame
	pointer the caller will return to the caller of the caller correctly. Just
	the registers remain corrupted causing crashes of completely unrelated code
	executed far, far away...</p>

	<p><span class="constant">EDI</span>, <span class="constant">ESI</span> and
	<span class="constant">EBX</span> registers are always saved on the stack.
	They are stored on the stack in this particular order from bottom to top
	addresses (using the <span class="instruction">push EBX</span>,
	<span class="instruction">push ESI</span>,
	<span class="instruction">push EDI</span> sequence). Fortunately $gnulinux
	GCC has the same register saving behaviour. If some register corruption
	occurs the calling type presented between the caller and callee should be
	checked.</p>

	<a name="calltype_cdecl"><h2>W32 Calling Convention &quot;cdecl&quot;</h2></a>

		<p>The only calling convention in the UNIX world. The default one for all
		the compilers. All the arguments are passed on the stack, no arguments
		are cleaned by the callee. Possible inconsistencies in the number of
		function arguments with the function prototype used by the caller is
		harmless. Variable arguments lists can be passed by this convention.</p>

		@{[ doc_img 'fig/calltype_cdecl',
				'W32 Calling Convention <span class="constant">cdecl</span> Scheme' ]}

		<table border="1" align="center">
			<tr><td>Arguments freed by         </td><td>caller</td></tr>
			<tr><td>Arguments on the stack     </td><td>#0 ... #(n-1)</td></tr>
			<tr><td>Arguments in the registers </td><td>none</td></tr>
			<tr><td>GCC attribute              </td><td><span class="command">__attribute__((__cdecl__))</span> (default)</td></tr>
			<caption>Calling Convention <span class="constant">cdecl</span> Characteristics</caption>
		</table>

	<a name="calltype_stdcall"><h2>W32 Calling Convention &quot;stdcall&quot;</h2></a>

		@{[ doc_img 'fig/calltype_stdcall',
				'W32 Calling Convention <span class="constant">stdcall</span> Scheme' ]}

		<p>Convention never used in the UNIX world. It needs to be specified for
		W32 compilers. All the arguments are passed on the stack, all the
		arguments are cleaned by the callee. Possible inconsistencies in the
		number of function arguments with the function prototype used by the
		caller will result in fatal crash. Variable arguments lists cannot be
		passed by this convention &ndash; use @{[ a_href 'CallType.html.pl#calltype_cdecl','cdecl' ]}
		instead.</p>

		<table border="1" align="center">
			<tr><td>Arguments freed by         </td><td>callee</td></tr>
			<tr><td>Arguments on the stack     </td><td>#0 ... #(n-1)</td></tr>
			<tr><td>Arguments in the registers </td><td>none</td></tr>
			<tr><td>GCC attribute              </td><td><span class="command">__attribute__((__stdcall__))</span></td></tr>
			<caption>Calling Convention <span class="constant">stdcall</span> Characteristics</caption>
		</table>

	<a name="calltype_fastcall"><h2>W32 Calling Convention &quot;fastcall&quot;</h2></a>

		<p>Convention never used in the UNIX world. It needs to be specified for
		W32 compilers. Convention used in the W32 world for its low calling
		overhead. All but the first two arguments are passed on the stack, such
		arguments are cleaned by the callee. First two arguments are passed in
		the registers <span class="constant">ECX</span> and
		<span class="constant">EDX</span> respectively. Possible inconsistencies
		in the number of function arguments with the function prototype used by
		the caller will result in fatal crash. Variable arguments lists cannot be
		passed by this convention &ndash; use @{[ a_href 'CallType.html.pl#calltype_cdecl','cdecl' ]}
		instead.</p>

		<p>GCC (GNU C&nbsp;Compiler) native support for this calling convention
		is pretty fresh and it is currently present only in the recent CVS
		versions since 21st December of 2002 which should get released as GCC
		version 3.4. This project solved the unsupported calling convention by
		declaration of arguments passed in registers by
		<span class="command">__attribute__((__regparm__(3)))</span>.
		W32 passes the arguments in registers in the order
		<span class="constant">ECX</span>, <span class="constant">EDX</span> but
		GCC passes them in registers <span class="constant">EAX</span>,
		<span class="constant">EDX</span>, <span class="constant">ECX</span>.
		This incompatibility is compensated at C&nbsp;source level in the
		@{[ a_href '#functype','relaying code' ]} generated by
		<span class="fname">captivesym</span> relay generator.</p>

		@{[ doc_img 'fig/calltype_fastcall',
				'W32 Calling Convention <span class="constant">fastcall</span> Scheme' ]}

		<table border="1" align="center">
			<tr><td>Arguments freed by         </td><td>callee</td></tr>
			<tr><td>Arguments on the stack     </td><td>#2 ... #(n-1)</td></tr>
			<tr><td>Arguments in the registers </td><td><span class="constant">ECX</span>=#0,
																									<span class="constant">EDX</span>=#1</td></tr>
			<tr><td>GCC &ge;3.4 attribute      </td><td><span class="command">__attribute__((__fastcall__))</span></td></tr>
			<tr><td>GCC &lt;3.4 attr. emulation</td><td><span class="command">__attribute__((__stdcall__))</span></td></tr>
			<tr><td>                           </td><td><span class="command">__attribute__((__regparm__(3) /* EAX,EDX,ECX */))</span></td></tr>
			<caption>Calling Convention <span class="constant">fastcall</span> Characteristics</caption>
		</table>


HERE


project::captive::doc::Macros->footer();
