Changeset View
Changeset View
Standalone View
Standalone View
sys/kern/genoffset.sh
Show All 31 Lines | |||||||||||
{ | { | ||||||||||
echo "usage: genoffset [-o outfile] objfile" | echo "usage: genoffset [-o outfile] objfile" | ||||||||||
exit 1 | exit 1 | ||||||||||
} | } | ||||||||||
work() | work() | ||||||||||
{ | { | ||||||||||
local last off x1 x2 reset struct field type lastoff lasttype asserts | |||||||||||
markjUnsubmitted Not Done Inline Actions
markj: | |||||||||||
echo "#ifndef _OFFSET_INC_" | echo "#ifndef _OFFSET_INC_" | ||||||||||
echo "#define _OFFSET_INC_" | echo "#define _OFFSET_INC_" | ||||||||||
echo "#if !defined(GENOFFSET) && (!defined(KLD_MODULE) || defined(KLD_TIED))" | echo "#if !defined(GENOFFSET) && (!defined(KLD_MODULE) || defined(KLD_TIED))" | ||||||||||
${NM:='nm'} ${NMFLAGS} "$1" | ${AWK:='awk'} ' | last= | ||||||||||
/ C .*_datatype_*/ { | ${NM:='nm'} ${NMFLAGS} -t d "$1" | grep OfFsEt__ | sort -n | sed -e 's/__/ /g' | \ | ||||||||||
type = substr($3, match($3, "_datatype_") + length("_datatype_")) | while read off x1 x2 struct field type rest; do | ||||||||||
} | off=$(echo $off | sed -e 's/^00*//') | ||||||||||
/ C .*_parenttype_*/ { | if [ "$last" != "$struct" ]; then | ||||||||||
parent = substr($3, match($3, "_parenttype_") + length("_parenttype_")) | if [ -n "$last" ]; then | ||||||||||
} | echo "};" | ||||||||||
/ C .*sign$/ { | fi | ||||||||||
sign = substr($1, length($1) - 3, 4) | echo "struct ${struct}_lite {" | ||||||||||
sub("^0*", "", sign) | last=$struct | ||||||||||
if (sign != "") | printf "\tu_char\tpad_${field}[${off}];\n" | ||||||||||
sign = "-" | else | ||||||||||
} | printf "\tu_char\tpad_${field}[${off} - (${lastoff} + sizeof(${lasttype}))];\n" | ||||||||||
/ C .*w0$/ { | fi | ||||||||||
w0 = substr($1, length($1) - 3, 4) | printf "\t${type}\t${field};\n" | ||||||||||
} | lastoff=${off} | ||||||||||
/ C .*w1$/ { | lasttype=$type | ||||||||||
Not Done Inline ActionsCan drop the braces here, they're not needed in assignments. markj: Can drop the braces here, they're not needed in assignments. | |||||||||||
w1 = substr($1, length($1) - 3, 4) | asserts="${asserts}_SA(${struct}, ${field}, ${off});" | ||||||||||
} | done | ||||||||||
Not Done Inline ActionsDo all of these end up on one line? markj: Do all of these end up on one line? | |||||||||||
Done Inline ActionsYes. They do. Should I try to fix that? imp: Yes. They do. Should I try to fix that? | |||||||||||
Not Done Inline ActionsI think it'd be nice, at least since you take pains to format the rest of the code. We could write asserts=${asserts}\n...;" and print $asserts with printf or echo -e. markj: I think it'd be nice, at least since you take pains to format the rest of the code.
We could… | |||||||||||
/ C .*w2$/ { | echo "};" | ||||||||||
w2 = substr($1, length($1) - 3, 4) | echo "#define _SA(s,f,o) _Static_assert(__builtin_offsetof(struct s ## _lite, f) == o, \\" | ||||||||||
} | printf '\t"struct "#s"_lite field "#f" not at offset "#o)\n' | ||||||||||
/ C .*w3$/ { | echo $asserts | ||||||||||
w3 = substr($1, length($1) - 3, 4) | echo "#undef _SA" | ||||||||||
w = w3 w2 w1 w0 | |||||||||||
sub("^0*", "", w) | |||||||||||
if (w == "") | |||||||||||
w = "0" | |||||||||||
hex = "" | |||||||||||
if (w != "0") | |||||||||||
hex = "0x" | |||||||||||
sub("w3$", "", $3) | |||||||||||
member = tolower($3) | |||||||||||
# This still has minor problems representing INT_MIN, etc. | |||||||||||
# E.g., | |||||||||||
# with 32-bit 2''s complement ints, this prints -0x80000000, | |||||||||||
# which has the wrong type (unsigned int). | |||||||||||
offset = sprintf("%s%s%s", sign, hex, w) | |||||||||||
structures[parent] = sprintf("%s%s %s %s\n", | |||||||||||
structures[parent], offset, type, member) | |||||||||||
} | |||||||||||
END { | |||||||||||
for (struct in structures) { | |||||||||||
printf("struct %s_lite {\n", struct); | |||||||||||
n = split(structures[struct], members, "\n") | |||||||||||
for (i = 1; i < n; i++) { | |||||||||||
for (j = i + 1; j < n; j++) { | |||||||||||
split(members[i], ivar, " ") | |||||||||||
split(members[j], jvar, " ") | |||||||||||
if (jvar[1] < ivar[1]) { | |||||||||||
tmp = members[i] | |||||||||||
members[i] = members[j] | |||||||||||
members[j] = tmp | |||||||||||
} | |||||||||||
} | |||||||||||
} | |||||||||||
off = "0" | |||||||||||
for (i = 1; i < n; i++) { | |||||||||||
split(members[i], m, " ") | |||||||||||
printf "\tu_char\tpad_%s[%s - %s];\n", m[3], m[1], off | |||||||||||
printf "\t%s\t%s;\n", m[2], m[3] | |||||||||||
off = sprintf("(%s + sizeof(%s))", m[1], m[2]) | |||||||||||
} | |||||||||||
printf("};\n"); | |||||||||||
} | |||||||||||
} | |||||||||||
' | |||||||||||
echo "#endif" | echo "#endif" | ||||||||||
echo "#endif" | echo "#endif" | ||||||||||
} | } | ||||||||||
# | # | ||||||||||
#MAIN PROGGRAM | #MAIN PROGGRAM | ||||||||||
# | # | ||||||||||
use_outfile="no" | use_outfile="no" | ||||||||||
while getopts "o:" option | while getopts "o:" option | ||||||||||
Show All 20 Lines |