From owner-freebsd-hackers@FreeBSD.ORG Thu Dec 20 13:48:39 2007 Return-Path: Delivered-To: freebsd-hackers@FreeBSD.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 60BA916A419 for ; Thu, 20 Dec 2007 13:48:39 +0000 (UTC) (envelope-from tataz@tataz.chchile.org) Received: from smtp5-g19.free.fr (smtp5-g19.free.fr [212.27.42.35]) by mx1.freebsd.org (Postfix) with ESMTP id F38A513C4CC for ; Thu, 20 Dec 2007 13:48:38 +0000 (UTC) (envelope-from tataz@tataz.chchile.org) Received: from smtp5-g19.free.fr (localhost.localdomain [127.0.0.1]) by smtp5-g19.free.fr (Postfix) with ESMTP id 4EFE43F61BF for ; Thu, 20 Dec 2007 14:48:37 +0100 (CET) Received: from tatooine.tataz.chchile.org (tataz.chchile.org [82.233.239.98]) by smtp5-g19.free.fr (Postfix) with ESMTP id 24FFE3F616F for ; Thu, 20 Dec 2007 14:48:37 +0100 (CET) Received: from obiwan.tataz.chchile.org (unknown [192.168.1.25]) by tatooine.tataz.chchile.org (Postfix) with ESMTP id 2EC7D9B497 for ; Thu, 20 Dec 2007 13:45:57 +0000 (UTC) Received: by obiwan.tataz.chchile.org (Postfix, from userid 1000) id 1ADB1405B; Thu, 20 Dec 2007 14:45:57 +0100 (CET) Date: Thu, 20 Dec 2007 14:45:57 +0100 From: Jeremie Le Hen To: freebsd-hackers@FreeBSD.org Message-ID: <20071220134557.GB35586@obiwan.tataz.chchile.org> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.5.15 (2007-04-06) Cc: Subject: GCC generated assembly X-BeenThere: freebsd-hackers@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Technical Discussions relating to FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 20 Dec 2007 13:48:39 -0000 Hi list, This mail is slightly off-topic because probably not FreeBSD-centric. I've looked at the assembly code generated by GCC, but I am not able to understand the point of every instruction. I've written the following useless program: % #include % % int % main(int ac, char *av[]) % { % char buf[16]; % % if (ac < 2) % return 0; % strcpy(buf, av[1]); % return 1; % } Theorically, the main() function should be something like this: % push %ebp % mov %esp, %ebp % sub $16, %esp % cmp $1, 8(%ebp) % jle .byebye % mov 12(%ebp), %eax % push 4(%eax) % push -16(%ebp) % call strcpy % byebye: % leave % ret So the stack would look like this when calling strcpy() : | av | | ac | | ret | | old ebp| <- ebp [ ] [ ] [ buf ] [ ] | av[1] | | &buf | <- esp On RELENG_6, with GCC 3.4.6, I get the following assembly: % aristote# gcc -S -O vuln.c % aristote# cat vuln.s % .file "vuln.c" % .text % .p2align 2,,3 % .globl main % .type main, @function % main: % pushl %ebp % movl %esp, %ebp % subl $24, %esp % andl $-16, %esp % subl $16, %esp % movl $0, %eax % cmpl $1, 8(%ebp) % jle .L1 % subl $8, %esp % movl 12(%ebp), %eax % pushl 4(%eax) % leal -24(%ebp), %eax % pushl %eax % call strcpy % movl $1, %eax % .L1: % leave % ret % .size main, .-main % .ident "GCC: (GNU) 3.4.6 [FreeBSD] 20060305" While it works, it seems to waste much space on the stack : | av | | ac | | ret | | old ebp| <- ebp { } { } {24 bytes} { (buf1) } { } { } # There could be more space between the two [ ] # buffers because of alignment on 16 bytes. [16 bytes] [ (buf2) ] [ ] { 8 bytes} { (buf3) } | av[1] | | &buf1 | <- esp Is someone able to explain this please? Interestingly, if I change the buffer size from 16 to 32 bytes, buf1 is 40 bytes wide while the two others keep the same size. I've tried with GCC 2.95.3 from ports. Stackwise the differences are: - buf2 doesn't exist - while buf1 is still 24 bytes long, the value passed to strcpy() is buf1 + 8: % leal -16(%ebp),%eax % pushl %eax I will follow up with RELENG_7 GCC 4.2.1 output. Thank you. Regards, -- Jeremie Le Hen < jeremie at le-hen dot org >< ttz at chchile dot org >