git: 29e7ab4a3ad7 - stable/13 - genoffset: simplify and rewrite in sh

Warner Losh imp at FreeBSD.org
Sun Sep 12 16:35:23 UTC 2021


The branch stable/13 has been updated by imp:

URL: https://cgit.FreeBSD.org/src/commit/?id=29e7ab4a3ad7c9715a3d20b51836a91d66361c5c

commit 29e7ab4a3ad7c9715a3d20b51836a91d66361c5c
Author:     Warner Losh <imp at FreeBSD.org>
AuthorDate: 2021-07-28 19:47:05 +0000
Commit:     Warner Losh <imp at FreeBSD.org>
CommitDate: 2021-09-12 15:56:14 +0000

    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
    
    (cherry picked from commit 824897a3aea5ca22db8cb7d5b404697a1de1210a)
---
 sys/kern/genoffset.sh | 117 ++++++++++++++++----------------------------------
 sys/sys/assym.h       |   4 +-
 2 files changed, 39 insertions(+), 82 deletions(-)

diff --git a/sys/kern/genoffset.sh b/sys/kern/genoffset.sh
index 843c0cbcd862..f7185e7ae396 100644
--- a/sys/kern/genoffset.sh
+++ b/sys/kern/genoffset.sh
@@ -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
 
diff --git a/sys/sys/assym.h b/sys/sys/assym.h
index 858989fe505f..3cb4afd5803c 100644
--- a/sys/sys/assym.h
+++ b/sys/sys/assym.h
@@ -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))
 


More information about the dev-commits-src-all mailing list