genoffset: simplify and rewrite in sh
genoffset used the fully generic ASSYM macro to generate the offsets needed for the thread_lite structure. However, since these are offsets into a structure, they will always be necessarily small and positive. As such, just create a simple character array of the right size and use a naming convention such that we can recover the field name, structure name and type. Use nm -t d and sort -n to sort these into order, then loop over the resutls to generate the thread_lite structure. MFC After: 2 weeks Reviewed by: kib, markj (earlier versions) Sponsored by: Netflix Differential Revision: https://reviews.freebsd.org/D31203
This commit is contained in:
parent
46dd3ef033
commit
824897a3ae
@ -34,84 +34,43 @@ usage()
|
||||
exit 1
|
||||
}
|
||||
|
||||
|
||||
work()
|
||||
{
|
||||
echo "#ifndef _OFFSET_INC_"
|
||||
echo "#define _OFFSET_INC_"
|
||||
echo "#if !defined(GENOFFSET) && (!defined(KLD_MODULE) || defined(KLD_TIED))"
|
||||
${NM:='nm'} ${NMFLAGS} "$1" | ${AWK:='awk'} '
|
||||
/ C .*_datatype_*/ {
|
||||
type = substr($3, match($3, "_datatype_") + length("_datatype_"))
|
||||
}
|
||||
/ C .*_parenttype_*/ {
|
||||
parent = substr($3, match($3, "_parenttype_") + length("_parenttype_"))
|
||||
}
|
||||
/ C .*sign$/ {
|
||||
sign = substr($1, length($1) - 3, 4)
|
||||
sub("^0*", "", sign)
|
||||
if (sign != "")
|
||||
sign = "-"
|
||||
}
|
||||
/ C .*w0$/ {
|
||||
w0 = substr($1, length($1) - 3, 4)
|
||||
}
|
||||
/ C .*w1$/ {
|
||||
w1 = substr($1, length($1) - 3, 4)
|
||||
}
|
||||
/ C .*w2$/ {
|
||||
w2 = substr($1, length($1) - 3, 4)
|
||||
}
|
||||
/ C .*w3$/ {
|
||||
w3 = substr($1, length($1) - 3, 4)
|
||||
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)
|
||||
(
|
||||
local last off x1 x2 x3 struct field type lastoff lasttype
|
||||
|
||||
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 "#ifndef _OFFSET_INC_"
|
||||
echo "#define _OFFSET_INC_"
|
||||
echo "#if !defined(GENOFFSET) && (!defined(KLD_MODULE) || defined(KLD_TIED))"
|
||||
last=
|
||||
temp=$(mktemp -d genoffset.XXXXX)
|
||||
trap "rm -rf ${temp}" EXIT
|
||||
# Note: we need to print symbol values in decimal so the numeric sort works
|
||||
${NM:='nm'} ${NMFLAGS} -t d "$1" | grep __assym_offset__ | sed -e 's/__/ /g' | sort -k 4 -k 1 -n |
|
||||
while read off x1 x2 struct field type x3; do
|
||||
off=$(echo "$off" | sed -E 's/^0+//')
|
||||
if [ "$last" != "$struct" ]; then
|
||||
if [ -n "$last" ]; then
|
||||
echo "};"
|
||||
fi
|
||||
echo "struct ${struct}_lite {"
|
||||
last=$struct
|
||||
printf "%b" "\tu_char\tpad_${field}[${off}];\n"
|
||||
else
|
||||
printf "%b" "\tu_char\tpad_${field}[${off} - (${lastoff} + sizeof(${lasttype}))];\n"
|
||||
fi
|
||||
printf "%b" "\t${type}\t${field};\n"
|
||||
lastoff="$off"
|
||||
lasttype="$type"
|
||||
echo "_SA(${struct}, ${field}, ${off});" >> "$temp/asserts"
|
||||
done
|
||||
echo "};"
|
||||
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'
|
||||
cat "$temp/asserts"
|
||||
echo "#undef _SA"
|
||||
echo "#endif"
|
||||
echo "#endif"
|
||||
)
|
||||
|
||||
|
||||
#
|
||||
@ -126,7 +85,7 @@ do
|
||||
*) usage;;
|
||||
esac
|
||||
done
|
||||
shift $(($OPTIND - 1))
|
||||
shift $((OPTIND - 1))
|
||||
case $# in
|
||||
1) ;;
|
||||
*) usage;;
|
||||
@ -134,8 +93,8 @@ esac
|
||||
|
||||
if [ "$use_outfile" = "yes" ]
|
||||
then
|
||||
work $1 3>"$outfile" >&3 3>&-
|
||||
work "$1" 3>"$outfile" >&3 3>&-
|
||||
else
|
||||
work $1
|
||||
work "$1"
|
||||
fi
|
||||
|
||||
|
@ -51,9 +51,7 @@ char name ## w3[((ASSYM_ABS(value) & 0xFFFF000000000000ULL) >> 48) + ASSYM_BIAS]
|
||||
#endif
|
||||
|
||||
#define OFFSYM(name, parenttype, datatype) \
|
||||
ASSYM(name, offsetof(struct parenttype, name)); \
|
||||
char name ## _datatype_ ## datatype [1]; \
|
||||
char name ## _parenttype_ ## parenttype [1]; \
|
||||
char __assym_offset__ ## parenttype ## __ ## name ## __ ## datatype [offsetof(struct parenttype, name)]; \
|
||||
CTASSERT(__builtin_types_compatible_p(__typeof(((struct parenttype *)(0x0))-> name), datatype)); \
|
||||
OFFSET_CTASSERT(offsetof(struct parenttype, name) == offsetof(struct parenttype ## _lite, name))
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user