From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 37288 invoked by alias); 21 Jul 2015 17:07:28 -0000 Mailing-List: contact gcc-bugs-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-bugs-owner@gcc.gnu.org Received: (qmail 32992 invoked by uid 48); 21 Jul 2015 17:07:25 -0000 From: "hjl.tools at gmail dot com" To: gcc-bugs@gcc.gnu.org Subject: [Bug middle-end/66960] New: Add a builtin to get the address of the current stack frame Date: Tue, 21 Jul 2015 17:07:00 -0000 X-Bugzilla-Reason: CC X-Bugzilla-Type: new X-Bugzilla-Watch-Reason: None X-Bugzilla-Product: gcc X-Bugzilla-Component: middle-end X-Bugzilla-Version: 6.0 X-Bugzilla-Keywords: X-Bugzilla-Severity: normal X-Bugzilla-Who: hjl.tools at gmail dot com X-Bugzilla-Status: UNCONFIRMED X-Bugzilla-Resolution: X-Bugzilla-Priority: P3 X-Bugzilla-Assigned-To: unassigned at gcc dot gnu.org X-Bugzilla-Target-Milestone: --- X-Bugzilla-Flags: X-Bugzilla-Changed-Fields: bug_id short_desc product version bug_status bug_severity priority component assigned_to reporter target_milestone Message-ID: Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: 7bit X-Bugzilla-URL: http://gcc.gnu.org/bugzilla/ Auto-Submitted: auto-generated MIME-Version: 1.0 X-SW-Source: 2015-07/txt/msg01830.txt.bz2 https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66960 Bug ID: 66960 Summary: Add a builtin to get the address of the current stack frame Product: gcc Version: 6.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: middle-end Assignee: unassigned at gcc dot gnu.org Reporter: hjl.tools at gmail dot com Target Milestone: --- The initial i386 stack layout is: environ 4*argc + 4 + %esp 0 4 bytes envp 8 + 4*argc + %esp N * 4 bytes 0 4 + 4*argc + %esp 4 bytes argv %esp + 4 4*argc bytes argc %esp 4 bytes To get argc, argv and environ in C, we can use --- extern char **environ; extern void exit (int status); extern int main (int argc, char **argv, char **envp); void _start (void) { void *argc_p = __builtin_frame_address (0) + 4; char **argv = (char **) (argc_p + 4); int argc = *(int *) argc_p; int status; environ = argv + argc + 1; status = main (argc, argv, environ); exit (status); } --- With -O2 -m32 -miamcu, we generate _start: pushl %ebp movl %esp, %ebp movl 4(%ebp), %eax leal 8(%ebp), %edx leal 4(%edx,%eax,4), %ecx movl %ecx, environ call main call exit .size _start, .-_start %ebp is used since __builtin_frame_address always keeps the frame pointer. With a new builtin, __builtin_current_frame, which returns the top of the stack frame, we can use --- extern char **environ; extern void exit (int status); extern int main (int argc, char **argv, char **envp); void _start (void) { void *argc_p = __builtin_current_frame (); char **argv = (char **) (argc_p + 4); int argc = *(int *) argc_p; int status; environ = argv + argc + 1; status = main (argc, argv, environ); exit (status); } --- and generate _start: movl (%esp), %eax leal 4(%esp), %edx leal 8(%esp,%eax,4), %ecx movl %ecx, environ call main call exit .size _start, .-_start We can avoid using %ebp. __builtin_current_frame may not be the best name. We can use __builtin_stack_top, __builtin_top_of_stack, which gives us the stack address when the function is called.