Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 26 Oct 2002 15:14:45 -0700 (PDT)
From:      John Polstra <jdp@polstra.com>
To:        sparc@freebsd.org
Subject:   Is the sparc64 stack segment executable?
Message-ID:  <XFMail.20021026151445.jdp@polstra.com>

next in thread | raw e-mail | index | archive | help
Is the stack segment on FreeBSD/sparc64 executable?

Here's the background.  In my continuing quest to get CVSup running
on that platform, I'm now dealing with a problem involving indirect
calls to nested functions.  As you may or may not know, a nested
function can access the locals of surrounding functions by means
of the so-called static link, which is a pointer to a surrounding
function's stack frame.

To set up the static link properly when indirect calls are involved,
gcc builds a trampoline on the stack and passes the address of the
trampoline instead of the actual nested function.  The trampoline is
a tiny bit of code which sets the static link properly and then jumps
to the target function.  The reason it is done this way is because
the address of a trampoline has the same shape as the address of a
function, avoiding the need to handle a bunch of special cases.

Anyway, ... this is dying with a bus error on FreeBSD/sparc64 when it
tries to execute the very first instruction that is on the stack.

Below I will append an example of a C program using gcc's nested
function extension.  It works on i386 and on Alpha, but not on
Sparc64.  This is just for illustration, so don't groan at me about
using gcc extensions.  Remember, it's Modula-3 I'm trying to fix, not
a C program.

Next question: Assuming the stack is not executable by default, would
it work for the application to make it executable using mprotect?  I
noticed that GCC tries to arrange that on certain Sparc platforms.

John

#include <stdio.h>

static void
invoke(void (*fp)(void))
{
    (*fp)();
}

static void
outer(int first, int last)
{
    int i;
    void
    inner(void)
    {
        printf("%d\n", i);
    }
    for (i = first; i <= last; i++)
        invoke(inner);
}

int
main(int argc, char **argv)
{
    outer(1, 10);
    return 0;
}

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-sparc" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?XFMail.20021026151445.jdp>