17c478bd9Sstevel@tonic-gate/* 27c478bd9Sstevel@tonic-gate * CDDL HEADER START 37c478bd9Sstevel@tonic-gate * 47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5b71d513aSedp * Common Development and Distribution License (the "License"). 6b71d513aSedp * You may not use this file except in compliance with the License. 77c478bd9Sstevel@tonic-gate * 87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 117c478bd9Sstevel@tonic-gate * and limitations under the License. 127c478bd9Sstevel@tonic-gate * 137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 187c478bd9Sstevel@tonic-gate * 197c478bd9Sstevel@tonic-gate * CDDL HEADER END 207c478bd9Sstevel@tonic-gate */ 217c478bd9Sstevel@tonic-gate/* 22b71d513aSedp * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 237c478bd9Sstevel@tonic-gate * Use is subject to license terms. 247c478bd9Sstevel@tonic-gate */ 257c478bd9Sstevel@tonic-gate 26*9a70fc3bSMark J. Nelson .file "sbcp.s" 277c478bd9Sstevel@tonic-gate 287c478bd9Sstevel@tonic-gate#include <sys/asm_linkage.h> 29b71d513aSedp#include <sys/link.h> 307c478bd9Sstevel@tonic-gate#include <sys/syscall.h> 317c478bd9Sstevel@tonic-gate 327c478bd9Sstevel@tonic-gate#define PIC_SETUP(r) \ 337c478bd9Sstevel@tonic-gate mov %o7, %g1; \ 347c478bd9Sstevel@tonic-gate9: call 8f; \ 357c478bd9Sstevel@tonic-gate sethi %hi(_GLOBAL_OFFSET_TABLE_ - (9b - .)), %r; \ 367c478bd9Sstevel@tonic-gate8: or %r, %lo(_GLOBAL_OFFSET_TABLE_ - (9b - .)), %r; \ 377c478bd9Sstevel@tonic-gate add %r, %o7, %r; \ 387c478bd9Sstevel@tonic-gate mov %g1, %o7 397c478bd9Sstevel@tonic-gate 407c478bd9Sstevel@tonic-gate#define FUNC(x) \ 417c478bd9Sstevel@tonic-gate .section ".text"; \ 427c478bd9Sstevel@tonic-gate .align 4; \ 437c478bd9Sstevel@tonic-gate .type x, #function; \ 447c478bd9Sstevel@tonic-gatex: 457c478bd9Sstevel@tonic-gate 467c478bd9Sstevel@tonic-gate#define ENOSYS 90 /* 4.x ENOSYS */ 477c478bd9Sstevel@tonic-gate 487c478bd9Sstevel@tonic-gate/* derived from <sys/exechdr.h>, which we can't include */ 497c478bd9Sstevel@tonic-gate#define A_MAGIC 0x02 /* offset of a_magic field */ 507c478bd9Sstevel@tonic-gate#define A_ENTRY 0x14 /* offset of a_entry field */ 517c478bd9Sstevel@tonic-gate#define ZMAGIC 0413 /* magic number for demand paged executable */ 527c478bd9Sstevel@tonic-gate 537c478bd9Sstevel@tonic-gate .global atexit, errno 547c478bd9Sstevel@tonic-gate 557c478bd9Sstevel@tonic-gate! 567c478bd9Sstevel@tonic-gate! _start - execution starts here (after the runtime linker runs) 577c478bd9Sstevel@tonic-gate! 587c478bd9Sstevel@tonic-gate! The SPARC ABI defines our "environment" at this point, see page 3-34. 597c478bd9Sstevel@tonic-gate! Register the exit handler, register the trap0 handler, find the 607c478bd9Sstevel@tonic-gate! entry point, and jump to it. We depend on the stack (argv, envp) 617c478bd9Sstevel@tonic-gate! being compatible between 4.x and 5.x. We also depend on the 627c478bd9Sstevel@tonic-gate! runtime linker to set up ``environ''. 637c478bd9Sstevel@tonic-gate! 647c478bd9Sstevel@tonic-gate 657c478bd9Sstevel@tonic-gateENTRY_NP(_start) 667c478bd9Sstevel@tonic-gate tst %g1 ! is there a handler to register? 677c478bd9Sstevel@tonic-gate bz 1f ! no 687c478bd9Sstevel@tonic-gate nop 697c478bd9Sstevel@tonic-gate mov %g1, %o0 707c478bd9Sstevel@tonic-gate call atexit ! yes, register it with atexit() 717c478bd9Sstevel@tonic-gate nop 727c478bd9Sstevel@tonic-gate1: 737c478bd9Sstevel@tonic-gate 74b71d513aSedp ! 75b71d513aSedp ! Aside from a value in %g1, there were no arguments explicitly 76b71d513aSedp ! passed to this routine, but we do know how our initial stack has 77b71d513aSedp ! been setup by the kernel. The stack format is documented in: 78b71d513aSedp ! usr/src/cmd/sgs/rtld/sparc/boot.s 79b71d513aSedp ! usr/src/cmd/sgs/rtld/sparcv9/boot.s 80b71d513aSedp ! 81b71d513aSedp ! Since we want to invoke the following c initalization routine: 82b71d513aSedp ! sbcp_init(int argc, char *argv[], char *envp[])) 83b71d513aSedp ! we need to troll through the stack to setup it's argument values. 84b71d513aSedp ! 85b71d513aSedp save %sp, -SA(MINFRAME + EB_MAX_SIZE32), %sp 86b71d513aSedp 87b71d513aSedp ldn [%fp + WINDOWSIZE + STACK_BIAS], %o0 ! get argc 88b71d513aSedp add %fp, + WINDOWSIZE + CPTRSIZE + STACK_BIAS, %o1 ! get argv 89b71d513aSedp 90b71d513aSedp add %o0, 1, %l0 ! add 1 to argc for last element of 0 91b71d513aSedp sll %l0, CPTRSHIFT, %l0 ! multiply argc by pointer size 92b71d513aSedp add %o1, %l0, %o2 ! and add to argv to get envp 93b71d513aSedp 94b71d513aSedp call sbcp_init ! Call our c initalization routine 95b71d513aSedp nop 96b71d513aSedp restore 977c478bd9Sstevel@tonic-gate 987c478bd9Sstevel@tonic-gate PIC_SETUP(g2) 997c478bd9Sstevel@tonic-gate ld [%g2+trap0], %g1 1007c478bd9Sstevel@tonic-gate ta 9 1017c478bd9Sstevel@tonic-gate 1027c478bd9Sstevel@tonic-gate ! jump to the main program's entry point 1037c478bd9Sstevel@tonic-gate 1047c478bd9Sstevel@tonic-gate sethi %hi(0x2000), %o0 1057c478bd9Sstevel@tonic-gate lduh [%o0 + A_MAGIC], %g1 1067c478bd9Sstevel@tonic-gate cmp %g1, ZMAGIC ! is it a ZMAGIC executable? 1077c478bd9Sstevel@tonic-gate be,a 1f ! yes, 1087c478bd9Sstevel@tonic-gate ld [%o0 + A_ENTRY], %o0 ! get entry point 1097c478bd9Sstevel@tonic-gate1: ! else, assume entry point is 0x2000 1107c478bd9Sstevel@tonic-gate jmp %o0 1117c478bd9Sstevel@tonic-gate nop 1127c478bd9Sstevel@tonic-gate SET_SIZE(_start) 1137c478bd9Sstevel@tonic-gate 1147c478bd9Sstevel@tonic-gate! 1157c478bd9Sstevel@tonic-gate! trap0 - glue between 4.x syscall trap and 5.x BCP routine 1167c478bd9Sstevel@tonic-gate! 1177c478bd9Sstevel@tonic-gate! enter with: 1187c478bd9Sstevel@tonic-gate! %g1 syscall number 1197c478bd9Sstevel@tonic-gate! %g6 return address (after trap instruction) 1207c478bd9Sstevel@tonic-gate! 1217c478bd9Sstevel@tonic-gate! We used to use %g7, but that conflicts with threading code 1227c478bd9Sstevel@tonic-gate! which uses %g7 as the curthread pointer. That is why we 1237c478bd9Sstevel@tonic-gate! changed to using %g6 instead. 1247c478bd9Sstevel@tonic-gate! 1257c478bd9Sstevel@tonic-gate! We use an extra window to save the %o registers we're entered 1267c478bd9Sstevel@tonic-gate! with (which the 4.x system call stubs depend on) and to allow 1277c478bd9Sstevel@tonic-gate! recursive traps (e.g., from a signal handler). 1287c478bd9Sstevel@tonic-gate! 1297c478bd9Sstevel@tonic-gate 1307c478bd9Sstevel@tonic-gateFUNC(trap0) 1317c478bd9Sstevel@tonic-gate save %sp, -SA(MINFRAME), %sp 1327c478bd9Sstevel@tonic-gate tst %g1 1337c478bd9Sstevel@tonic-gate be 1f 1347c478bd9Sstevel@tonic-gate nop 1357c478bd9Sstevel@tonic-gate mov %i0, %o0 1367c478bd9Sstevel@tonic-gate mov %i1, %o1 1377c478bd9Sstevel@tonic-gate mov %i2, %o2 1387c478bd9Sstevel@tonic-gate mov %i3, %o3 1397c478bd9Sstevel@tonic-gate mov %i4, %o4 1407c478bd9Sstevel@tonic-gate mov %i5, %o5 1417c478bd9Sstevel@tonic-gate ba,a 2f 1427c478bd9Sstevel@tonic-gate1: 1437c478bd9Sstevel@tonic-gate ! indir syscall 1447c478bd9Sstevel@tonic-gate mov %i0, %g1 1457c478bd9Sstevel@tonic-gate mov %i1, %o0 1467c478bd9Sstevel@tonic-gate mov %i2, %o1 1477c478bd9Sstevel@tonic-gate mov %i3, %o2 1487c478bd9Sstevel@tonic-gate mov %i4, %o3 1497c478bd9Sstevel@tonic-gate mov %i5, %o4 1507c478bd9Sstevel@tonic-gate ld [%fp + MINFRAME], %o5 1517c478bd9Sstevel@tonic-gate2: 1527c478bd9Sstevel@tonic-gate sll %g1, 4, %l1 1537c478bd9Sstevel@tonic-gate PIC_SETUP(l0) 1547c478bd9Sstevel@tonic-gate ld [%l0+sysent], %l0 1557c478bd9Sstevel@tonic-gate add %l1, %l0, %l1 1567c478bd9Sstevel@tonic-gate jmp %l1 ! jump into branch table 1577c478bd9Sstevel@tonic-gate nop 1587c478bd9Sstevel@tonic-gate SET_SIZE(trap0) 1597c478bd9Sstevel@tonic-gate 1607c478bd9Sstevel@tonic-gateFUNC(trap0rtn) 1617c478bd9Sstevel@tonic-gate cmp %o0, -1 1627c478bd9Sstevel@tonic-gate bne 1f 1637c478bd9Sstevel@tonic-gate addcc %g0, %g0, %g0 ! psr &= ~C 1647c478bd9Sstevel@tonic-gate PIC_SETUP(o1) 1657c478bd9Sstevel@tonic-gate ld [%o1+errno], %o1 1667c478bd9Sstevel@tonic-gate ld [%o1], %o0 1677c478bd9Sstevel@tonic-gate subcc %g0, 1, %g0 ! psr |= C 1687c478bd9Sstevel@tonic-gate1: 1697c478bd9Sstevel@tonic-gate mov %o0, %i0 1707c478bd9Sstevel@tonic-gate restore 1717c478bd9Sstevel@tonic-gate jmp %g6 1727c478bd9Sstevel@tonic-gate nop 1737c478bd9Sstevel@tonic-gate SET_SIZE(trap0rtn) 1747c478bd9Sstevel@tonic-gate 1757c478bd9Sstevel@tonic-gate! 1767c478bd9Sstevel@tonic-gate! nullsys 1777c478bd9Sstevel@tonic-gate! 1787c478bd9Sstevel@tonic-gateFUNC(nullsys) 1797c478bd9Sstevel@tonic-gate clr %o0 1807c478bd9Sstevel@tonic-gate b,a trap0rtn 1817c478bd9Sstevel@tonic-gate SET_SIZE(nullsys) 1827c478bd9Sstevel@tonic-gate 1837c478bd9Sstevel@tonic-gate! 1847c478bd9Sstevel@tonic-gate! nosys 1857c478bd9Sstevel@tonic-gate! 1867c478bd9Sstevel@tonic-gateFUNC(nosys) 1877c478bd9Sstevel@tonic-gate set ENOSYS, %o1 1887c478bd9Sstevel@tonic-gate PIC_SETUP(g2) 1897c478bd9Sstevel@tonic-gate ld [%g2+errno], %g2 1907c478bd9Sstevel@tonic-gate st %o1, [%g2] 1917c478bd9Sstevel@tonic-gate set -1, %o0 1927c478bd9Sstevel@tonic-gate b,a trap0rtn 1937c478bd9Sstevel@tonic-gate SET_SIZE(nosys) 1947c478bd9Sstevel@tonic-gate 1957c478bd9Sstevel@tonic-gate! 1967c478bd9Sstevel@tonic-gate! Have to #include the sysent table and stubs so that all 1977c478bd9Sstevel@tonic-gate! symbols referenced between here and there are "static" 1987c478bd9Sstevel@tonic-gate! to this module so the assembler can resolve them without 1997c478bd9Sstevel@tonic-gate! the linker needing to deal with them at run time. 2007c478bd9Sstevel@tonic-gate! 2017c478bd9Sstevel@tonic-gate#include "sysent.s" 202