From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 18521 invoked by alias); 23 Jan 2015 21:40:35 -0000 Mailing-List: contact overseers-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: , Sender: overseers-owner@sourceware.org Received: (qmail 18506 invoked by uid 89); 23 Jan 2015 21:40:35 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-2.6 required=5.0 tests=BAYES_00,FREEMAIL_FROM,RCVD_IN_DNSWL_LOW,SPF_PASS autolearn=ham version=3.3.2 X-HELO: mail-lb0-f170.google.com Received: from mail-lb0-f170.google.com (HELO mail-lb0-f170.google.com) (209.85.217.170) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES128-GCM-SHA256 encrypted) ESMTPS; Fri, 23 Jan 2015 21:40:33 +0000 Received: by mail-lb0-f170.google.com with SMTP id w7so9268607lbi.1 for ; Fri, 23 Jan 2015 13:40:30 -0800 (PST) MIME-Version: 1.0 X-Received: by 10.112.30.71 with SMTP id q7mr9604869lbh.41.1422049230312; Fri, 23 Jan 2015 13:40:30 -0800 (PST) Received: by 10.25.21.3 with HTTP; Fri, 23 Jan 2015 13:40:30 -0800 (PST) In-Reply-To: References: Date: Fri, 23 Jan 2015 21:40:00 -0000 Message-ID: Subject: Re: gcc x64 linux code generation (passing pointer var-args) bug From: Andrew Pinski To: Reuben Hawkins Cc: "overseers@gcc.gnu.org" Content-Type: text/plain; charset=UTF-8 X-SW-Source: 2015-q1/txt/msg00027.txt.bz2 On Fri, Jan 23, 2015 at 1:36 PM, Reuben Hawkins wrote: > Hi Overseers, > > I ran into an issue with all versions of gcc which support x64 which > *could* be considered a bug. At the very least, it's a pitfall. I'm > not really sure to whom I should bring this problem to. Bugzilla? > Mailing list? Not sure... It is not a bug because ... > > Anyway, the gist of the bug is this... > > printf("%p %p %p %p %p %p\n", 0, 0, 0, 0, 0, 0); You are passing 32bit values where 64bit values are expected. If you used -Wformat, it would have warned you about this issue. > > The first 5 zero ints are copied into the esi, edx, ecx, r8d and r9d, > (as the linux x64 calling convention mandates) with the movl > instruction. The movl instruction will zero out the upper 32-bits of > those registers. The last zero int, however is copied to (%rsp) with > movl, which does *not* zero out the upper 32 bits because (%rsp) is > not a register, so the last 0 is not promoted to a 64-bit zero, but > the rest of the zeros are. If I were to add another zero, that zero > would be copied to 8(%rsp), so the upper 32-bits of (%rsp) are skipped > and whatever garbage happens to be there is passed to the called > function. > > printf("%p %p %p %p %p %p\n", 0, 0, 0, 0, 0, (void*)0); > > ...works because the (void*) causes gcc to emit a movq instruction. > > I'm wondering if there's a possibility to change this unexpected > behavior in gcc such that it always uses movq on stack args. it is not unexpected because the ABI says something different from what you are trying to work with. > > I realize all the zeros are technically wrong, they should be either > NULL or (void*) casts, but it's a huge pain that '0' works for the > first 6 args, then doesn't on the 7th when the args start going on the > stack. So this is undefined in C and will never work on most other targets too. Thanks, Andrew > > Thanks in advance, > Reuben Hawkins