]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/kern/genoffset.sh
THIS BRANCH IS OBSOLETE, PLEASE READ:
[FreeBSD/FreeBSD.git] / sys / kern / genoffset.sh
1 #!/bin/sh
2
3 # SPDX-License-Identifier: BSD-2-Clause-FreeBSD
4 #
5 # Copyright (c) 2000, Bruce Evans <bde@freebsd.org>
6 # Copyright (c) 2018, Jeff Roberson <jeff@freebsd.org>
7 #
8 # Redistribution and use in source and binary forms, with or without
9 # modification, are permitted provided that the following conditions
10 # are met:
11 # 1. Redistributions of source code must retain the above copyright
12 #    notice, this list of conditions and the following disclaimer.
13 # 2. Redistributions in binary form must reproduce the above copyright
14 #    notice, this list of conditions and the following disclaimer in the
15 #    documentation and/or other materials provided with the distribution.
16 #
17 # THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18 # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 # ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21 # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 # OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 # SUCH DAMAGE.
28 #
29 # $FreeBSD$
30
31 usage()
32 {
33         echo "usage: genoffset [-o outfile] objfile"
34         exit 1
35 }
36
37
38 work()
39 {
40         echo "#ifndef _OFFSET_INC_"
41         echo "#define _OFFSET_INC_"
42         echo "#if !defined(GENOFFSET) && (!defined(KLD_MODULE) || defined(KLD_TIED))"
43         ${NM:='nm'} ${NMFLAGS} "$1" | ${AWK:='awk'} '
44         / C .*_datatype_*/ {
45                 type = substr($3, match($3, "_datatype_") + length("_datatype_"))
46         }
47         / C .*_parenttype_*/ {
48                 parent = substr($3, match($3, "_parenttype_") + length("_parenttype_"))
49         }
50         / C .*sign$/ {
51                 sign = substr($1, length($1) - 3, 4)
52                 sub("^0*", "", sign)
53                 if (sign != "")
54                         sign = "-"
55         }
56         / C .*w0$/ {
57                 w0 = substr($1, length($1) - 3, 4)
58         }
59         / C .*w1$/ {
60                 w1 = substr($1, length($1) - 3, 4)
61         }
62         / C .*w2$/ {
63                 w2 = substr($1, length($1) - 3, 4)
64         }
65         / C .*w3$/ {
66                 w3 = substr($1, length($1) - 3, 4)
67                 w = w3 w2 w1 w0
68                 sub("^0*", "", w)
69                 if (w == "")
70                         w = "0"
71                 hex = ""
72                 if (w != "0")
73                         hex = "0x"
74                 sub("w3$", "", $3)
75                 member = tolower($3)
76                 # This still has minor problems representing INT_MIN, etc. 
77                 # E.g.,
78                 # with 32-bit 2''s complement ints, this prints -0x80000000,
79                 # which has the wrong type (unsigned int).
80                 offset = sprintf("%s%s%s", sign, hex, w)
81
82                 structures[parent] = sprintf("%s%s %s %s\n",
83                     structures[parent], offset, type, member)
84         }
85         END {
86                 for (struct in structures) {
87                         printf("struct %s_lite {\n", struct);
88                         n = split(structures[struct], members, "\n")
89                         for (i = 1; i < n; i++) {
90                                 for (j = i + 1; j < n; j++) {
91                                         split(members[i], ivar, " ")
92                                         split(members[j], jvar, " ")
93                                         if (jvar[1] < ivar[1]) {
94                                                 tmp = members[i]
95                                                 members[i] = members[j]
96                                                 members[j] = tmp
97                                         }
98                                 }
99                         }
100                         off = "0"
101                         for (i = 1; i < n; i++) {
102                                 split(members[i], m, " ")
103                                 printf "\tu_char\tpad_%s[%s - %s];\n", m[3], m[1], off
104                                 printf "\t%s\t%s;\n", m[2], m[3]
105                                 off = sprintf("(%s + sizeof(%s))", m[1], m[2])
106                         }
107                         printf("};\n");
108                 }
109         }
110         '
111
112         echo "#endif"
113         echo "#endif"
114 }
115
116
117 #
118 #MAIN PROGGRAM
119 #
120 use_outfile="no"
121 while getopts "o:" option
122 do
123         case "$option" in
124         o)      outfile="$OPTARG"
125                 use_outfile="yes";;
126         *)      usage;;
127         esac
128 done
129 shift $(($OPTIND - 1))
130 case $# in
131 1)      ;;
132 *)      usage;;
133 esac
134
135 if [ "$use_outfile" = "yes" ]
136 then
137         work $1  3>"$outfile" >&3 3>&-
138 else
139         work $1
140 fi
141