12633Sahl /*
22633Sahl * CDDL HEADER START
32633Sahl *
42633Sahl * The contents of this file are subject to the terms of the
52633Sahl * Common Development and Distribution License (the "License").
62633Sahl * You may not use this file except in compliance with the License.
72633Sahl *
82633Sahl * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
92633Sahl * or http://www.opensolaris.org/os/licensing.
102633Sahl * See the License for the specific language governing permissions
112633Sahl * and limitations under the License.
122633Sahl *
132633Sahl * When distributing Covered Code, include this CDDL HEADER in each
142633Sahl * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
152633Sahl * If applicable, add the following below this CDDL HEADER, with the
162633Sahl * fields enclosed by brackets "[]" replaced with your own identifying
172633Sahl * information: Portions Copyright [yyyy] [name of copyright owner]
182633Sahl *
192633Sahl * CDDL HEADER END
202633Sahl */
212633Sahl
222633Sahl /*
23*3944Sahl * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
242633Sahl * Use is subject to license terms.
252633Sahl */
262633Sahl
272633Sahl #pragma ident "%Z%%M% %I% %E% SMI"
282633Sahl
292633Sahl #include <stdint.h>
30*3944Sahl #include <stdlib.h>
31*3944Sahl #include <strings.h>
322633Sahl
332633Sahl int
baz(void)342633Sahl baz(void)
352633Sahl {
362633Sahl return (8);
372633Sahl }
382633Sahl
392633Sahl static int
foo(void)402633Sahl foo(void)
412633Sahl {
422633Sahl /*
432633Sahl * In order to assure that our helper is properly employed to identify
442633Sahl * the frame, we're going to trampoline through data.
452633Sahl */
462633Sahl uint32_t instr[] = {
472633Sahl 0x9de3bfa0, /* save %sp, -0x60, %sp */
482633Sahl 0x40000000, /* call baz */
492633Sahl 0x01000000, /* nop */
502633Sahl 0x81c7e008, /* ret */
512633Sahl 0x81e80000 /* restore */
522633Sahl };
53*3944Sahl uint32_t *fp = malloc(sizeof (instr));
542633Sahl
55*3944Sahl /*
56*3944Sahl * Do our little relocation dance.
57*3944Sahl */
58*3944Sahl instr[1] |= ((uintptr_t)baz - (uintptr_t)&fp[1]) >> 2;
592633Sahl
60*3944Sahl /*
61*3944Sahl * Copy the code to the heap (it's a pain to build in ON with an
62*3944Sahl * executable stack).
63*3944Sahl */
64*3944Sahl bcopy(instr, fp, sizeof (instr));
65*3944Sahl
66*3944Sahl (*(int (*)(void))fp)();
67*3944Sahl
68*3944Sahl free(fp);
69*3944Sahl
70*3944Sahl return (0);
712633Sahl }
722633Sahl
732633Sahl int
main(int argc,char ** argv)742633Sahl main(int argc, char **argv)
752633Sahl {
762633Sahl for (;;) {
772633Sahl foo();
782633Sahl }
792633Sahl
802633Sahl return (0);
812633Sahl }
82