diff --git a/kernel/Makefile b/kernel/Makefile index 4752efee0..8b54d2c56 100644 --- a/kernel/Makefile +++ b/kernel/Makefile @@ -91,7 +91,7 @@ SRCS+= profile.c do_sprofile.c debug.d: extracted-errno.h extracted-mfield.h extracted-mtype.h -CLEANFILES+=extracted-errno.h extracted-mfield.h extracted-mtype.h +CLEANFILES+=extracted-errno.h extracted-mfield.h extracted-mtype.h procoffsets.h extracted-errno.h: extract-errno.sh ../include/errno.h ${_MKTARGET_CREATE} diff --git a/kernel/arch/i386/Makefile.inc b/kernel/arch/i386/Makefile.inc index 28acb0457..407ea69b8 100644 --- a/kernel/arch/i386/Makefile.inc +++ b/kernel/arch/i386/Makefile.inc @@ -2,7 +2,8 @@ # Makefile for arch-dependent kernel code .include -.PATH: ${.CURDIR}/arch/${ARCH} +HERE=${.CURDIR}/arch/${ARCH} +.PATH: ${HERE} SRCS+= arch_do_vmctl.c \ arch_clock.c \ do_int86.c \ @@ -27,6 +28,20 @@ SRCS+= arch_do_vmctl.c \ arch_system.c \ pre_init.c +apic_asm.d klib.d mpx.d: procoffsets.h + +# It's OK to hardcode the arch as i386 here as this and procoffsets.cf +# are i386-specific. +TMP=procoffsets.h.tmp +INCLS=../include/arch/i386/include/ +PROCOFFSETSCF=procoffsets.cf + +procoffsets.h: $(PROCOFFSETSCF) kernel.h proc.h $(INCLS)/stackframe.h $(INCLS)/archtypes.h + ${_MKTARGET_CREATE} + cat ${HERE}/$(PROCOFFSETSCF) | \ + ${TOOL_GENASSYM} -- ${CC} ${CFLAGS} ${CPPFLAGS} ${PROF} >$TMP && \ + mv -f $TMP $@ + .ifdef CONFIG_SMP SRCS += arch_smp.c trampoline.S .endif diff --git a/kernel/arch/i386/procoffsets.cf b/kernel/arch/i386/procoffsets.cf new file mode 100644 index 000000000..9584de24b --- /dev/null +++ b/kernel/arch/i386/procoffsets.cf @@ -0,0 +1,29 @@ + +include "kernel.h" +include "proc.h" + +struct proc +member GSREG p_reg.gs +member FSREG p_reg.fs +member ESREG p_reg.es +member DSREG p_reg.ds +member DIREG p_reg.di +member SIREG p_reg.si +member BPREG p_reg.fp +member STREG p_reg.st +member BXREG p_reg.bx +member DXREG p_reg.dx +member CXREG p_reg.cx +member AXREG p_reg.retreg +member RETADR p_reg.retadr +member PCREG p_reg.pc +member CSREG p_reg.cs +member PSWREG p_reg.psw +member SPREG p_reg.sp +member SSREG p_reg.ss +member FP_SAVE_AREA_P p_fpu_state +member P_LDT_SEL p_seg.p_ldt_sel +member P_CR3 p_seg.p_cr3 +member P_CR3_V p_seg.p_cr3_v +member P_LDT p_seg.p_ldt + diff --git a/kernel/arch/i386/sconst.h b/kernel/arch/i386/sconst.h index 5f2bd6e09..c0108185e 100644 --- a/kernel/arch/i386/sconst.h +++ b/kernel/arch/i386/sconst.h @@ -2,39 +2,7 @@ #define __SCONST_H__ #include "kernel/const.h" - -/* Miscellaneous constants used in assembler code. */ - W = _WORD_SIZE /* Machine word size. */ - -/* Offsets in struct proc. They MUST match proc.h. */ - P_STACKBASE = 0 - GSREG = P_STACKBASE - FSREG = GSREG+2 /* 386 introduces FS and GS segments*/ - ESREG = FSREG+2 - DSREG = ESREG+2 - DIREG = DSREG+2 - SIREG = DIREG+W - BPREG = SIREG+W - STREG = BPREG+W /* hole for another SP*/ - BXREG = STREG+W - DXREG = BXREG+W - CXREG = DXREG+W - AXREG = CXREG+W - RETADR = AXREG+W /* return address for save() call*/ - PCREG = RETADR+W - CSREG = PCREG+W - PSWREG = CSREG+W - SPREG = PSWREG+W - SSREG = SPREG+W - P_STACKTOP = SSREG+W - FP_SAVE_AREA_P = P_STACKTOP - P_LDT_SEL = FP_SAVE_AREA_P + 532 - P_CR3 = P_LDT_SEL+W - P_CR3_V = P_CR3+4 - P_LDT = P_CR3_V+W - P_MISC_FLAGS = P_LDT + 50 - Msize = 9 /* size of a message in 32-bit words*/ - +#include "kernel/procoffsets.h" /* * offset to current process pointer right after trap, we assume we always have diff --git a/tools/nbsd_ports b/tools/nbsd_ports index b3ed779e1..e23b85638 100644 --- a/tools/nbsd_ports +++ b/tools/nbsd_ports @@ -2,6 +2,7 @@ # Timestamp in UTC,minixpath,netbsdpath # minixpath: path in Minix source tree (starting from /usr/src/) # netbsdpath: path in BSD source tree (starting from src/) +2011/01/17 18:11:10,usr.bin/genassym 2012/02/10 16:16:12,usr.bin/su 2011/12/25 06:09:09,sys/arch/i386/stand 2012/02/10 16:16:12,share/zoneinfo diff --git a/usr.bin/Makefile b/usr.bin/Makefile index a301a2f68..a7a987e19 100644 --- a/usr.bin/Makefile +++ b/usr.bin/Makefile @@ -4,7 +4,7 @@ # NetBSD imports SUBDIR= indent m4 stat tic sed mkdep uniq seq du man \ - apropos chpass newgrp passwd bzip2 bzip2recover gzip su + apropos chpass newgrp passwd bzip2 bzip2recover gzip su genassym # Non-NetBSD imports SUBDIR+= ministat diff --git a/usr.bin/genassym/Makefile b/usr.bin/genassym/Makefile new file mode 100644 index 000000000..74de3c7e0 --- /dev/null +++ b/usr.bin/genassym/Makefile @@ -0,0 +1,6 @@ +# $NetBSD: Makefile,v 1.1 2005/06/05 18:19:54 thorpej Exp $ + +MAN= genassym.1 +SCRIPTS= genassym.sh + +.include diff --git a/usr.bin/genassym/genassym.1 b/usr.bin/genassym/genassym.1 new file mode 100644 index 000000000..701284926 --- /dev/null +++ b/usr.bin/genassym/genassym.1 @@ -0,0 +1,92 @@ +.\" $NetBSD: genassym.1,v 1.5 2010/04/13 09:01:10 jruoho Exp $ +.\" +.\" Copyright (c) 1997 Matthias Pfaller. +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +.\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd April 13, 2010 +.Dt GENASSYM 1 +.Os +.Sh NAME +.Nm genassym +.Nd emit an assym.h file +.Sh SYNOPSIS +.Nm genassym +.Op Fl c +.Op Fl f +.Ar C compiler invocation +.Sh DESCRIPTION +.Nm +is a shell script normally used during the kernel build process to +create an assym.h file. +This file defines a number of cpp constants derived from the configuration +information +.Nm +reads from stdin. The generated file is used by kernel sources +written in assembler to gain access to information (e.g. structure +offsets and sizes) normally only known to the C compiler. +.Pp +Arguments to +.Nm +are usually of the form +.Ar ${CC} ${CFLAGS} ${CPPFLAGS} +where +.Ar ${CC} +is the C compiler used to compile the kernel, while +.Ar ${CFLAGS} +and +.Ar ${CPPFLAGS} +are flag arguments to the C compiler. The script creates a C source file +from its input. Then the C compiler is called according to the script's +arguments to compile this file. +.Pp +Normally +.Nm +instructs the C compiler to create an assembler source from the constructed +C source. The resulting file is then processed to extract the information +needed to create the assym.h file. The +.Fl c +flag instructs +.Nm +to create slightly different code, generate an executable from this code +and run it. In both cases the assym.h file is written to stdout. +The +.Fl f +flag instructs +.Nm +to create forth code. +.Sh DIAGNOSTICS +Either self-explanatory, or generated by one of the programs +called from the script. +.Sh SEE ALSO +.Xr genassym.cf 5 +.Sh HISTORY +The +.Nm +command appeared in +.Nx 1.3 +as +.Dq genassym.sh +in +.Pa /usr/src/sys/kern . +It became a userland utility in +.Nx 4.0 . diff --git a/usr.bin/genassym/genassym.sh b/usr.bin/genassym/genassym.sh new file mode 100644 index 000000000..1cf2166b8 --- /dev/null +++ b/usr.bin/genassym/genassym.sh @@ -0,0 +1,207 @@ +#!/bin/sh - +# $NetBSD: genassym.sh,v 1.6 2009/11/28 20:30:01 dsl Exp $ +# +# Copyright (c) 1997 Matthias Pfaller. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# + +progname=${0} +: ${AWK:=awk} + +ccode=0 # generate temporary C file, compile it, execute result +fcode=0 # generate Forth code + +usage() +{ + + echo "usage: ${progname} [-c | -f] -- compiler command" >&2 +} + +while getopts cf i +do + case "$i" in + c) + ccode=1 + ;; + f) + fcode=1 + ;; + esac +done +shift $(($OPTIND - 1)) +if [ $# -eq 0 ]; then + usage + exit 1 +fi + +# Deal with any leading environment settings.. + +while [ "$1" ] +do + case "$1" in + *=*) + eval export "$1" + shift + ;; + *) + break + ;; + esac +done + +genassym_temp=/tmp/genassym.$$ + +if ! mkdir $genassym_temp; then + echo "${progname}: unable to create temporary directory" >&2 + exit 1 +fi +trap "rm -rf $genassym_temp" 0 1 2 3 15 + +$AWK ' +BEGIN { + printf("#define offsetof(type, member) ((size_t)(&((type *)0)->member))\n"); + defining = 0; + type = "long"; + asmtype = "n"; + asmprint = ""; +} + +{ + doing_member = 0; +} + +$0 ~ /^[ \t]*#.*/ || $0 ~ /^[ \t]*$/ { + # Just ignore comments and empty lines + next; +} + +$0 ~ /^config[ \t]/ { + type = $2; + asmtype = $3; + asmprint = $4; + next; +} + +/^include[ \t]/ { + if (defining != 0) { + defining = 0; + printf("}\n"); + } + printf("#%s\n", $0); + next; +} + +$0 ~ /^if[ \t]/ || +$0 ~ /^ifdef[ \t]/ || +$0 ~ /^ifndef[ \t]/ || +$0 ~ /^else/ || +$0 ~ /^elif[ \t]/ || +$0 ~ /^endif/ { + printf("#%s\n", $0); + next; +} + +/^struct[ \t]/ { + structname = $2; + $0 = "define " structname "_SIZEOF sizeof(struct " structname ")"; + # fall through +} + +/^member[ \t]/ { + if (NF > 2) + $0 = "define " $2 " offsetof(struct " structname ", " $3 ")"; + else + $0 = "define " $2 " offsetof(struct " structname ", " $2 ")"; + doing_member = 1; + # fall through +} + +/^export[ \t]/ { + $0 = "define " $2 " " $2; + # fall through +} + +/^define[ \t]/ { + if (defining == 0) { + defining = 1; + printf("void f" FNR "(void);\n"); + printf("void f" FNR "(void) {\n"); + if (ccode) + call[FNR] = "f" FNR; + defining = 1; + } + value = $0 + gsub("^define[ \t]+[A-Za-z_][A-Za-z_0-9]*[ \t]+", "", value) + if (ccode) + printf("printf(\"#define " $2 " %%ld\\n\", (%s)" value ");\n", type); + else if (fcode) { + if (doing_member) + printf("__asm(\"XYZZY : %s d# %%%s0 + ;\" : : \"%s\" (%s));\n", $2, asmprint, asmtype, value); + else + printf("__asm(\"XYZZY d# %%%s0 constant %s\" : : \"%s\" (%s));\n", asmprint, $2, asmtype, value); + } else + printf("__asm(\"XYZZY %s %%%s0\" : : \"%s\" (%s));\n", $2, asmprint, asmtype, value); + next; +} + +/^quote[ \t]/ { + gsub("^quote[ \t]+", ""); + print; + next; +} + +{ + printf("syntax error in line %d\n", FNR) >"/dev/stderr"; + exit(1); +} + +END { + if (defining != 0) { + defining = 0; + printf("}\n"); + } + if (ccode) { + printf("int main(int argc, char **argv) {"); + for (i in call) + printf(call[i] "();"); + printf("return(0); }\n"); + } +} +' ccode=$ccode fcode=$fcode > ${genassym_temp}/assym.c || exit 1 + +if [ $ccode = 1 ] ; then + "$@" ${genassym_temp}/assym.c -o ${genassym_temp}/genassym && \ + ${genassym_temp}/genassym +elif [ $fcode = 1 ]; then + # Kill all of the "#" and "$" modifiers; locore.s already + # prepends the correct "constant" modifier. + "$@" -S ${genassym_temp}/assym.c -o - | sed -e 's/\$//g' | \ + sed -n 's/.*XYZZY//gp' +else + # Kill all of the "#" and "$" modifiers; locore.s already + # prepends the correct "constant" modifier. + "$@" -S ${genassym_temp}/assym.c -o - > \ + ${genassym_temp}/genassym.out && \ + sed -e 's/#//g' -e 's/\$//g' < ${genassym_temp}/genassym.out | \ + sed -n 's/.*XYZZY/#define/gp' +fi