Index: sys/kern/genoffset.sh =================================================================== --- sys/kern/genoffset.sh +++ sys/kern/genoffset.sh @@ -37,80 +37,37 @@ 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 reset struct field type lastoff lasttype asserts - 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= + ${NM:='nm'} ${NMFLAGS} -t d "$1" | grep OfFsEt__ | sort -n | sed -e 's/__/ /g' | \ + while read off x1 x2 struct field type rest; do + off=$(echo $off | sed -e 's/^00*//') + if [ "$last" != "$struct" ]; then + if [ -n "$last" ]; then + echo "};" + fi + echo "struct ${struct}_lite {" + last=$struct + printf "\tu_char\tpad_${field}[${off}];\n" + else + printf "\tu_char\tpad_${field}[${off} - (${lastoff} + sizeof(${lasttype}))];\n" + fi + printf "\t${type}\t${field};\n" + lastoff=${off} + lasttype=$type + asserts="${asserts}_SA(${struct}, ${field}, ${off});" + 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' + echo $asserts + echo "#undef _SA" + echo "#endif" + echo "#endif" } Index: sys/sys/assym.h =================================================================== --- sys/sys/assym.h +++ sys/sys/assym.h @@ -51,7 +51,7 @@ #endif #define OFFSYM(name, parenttype, datatype) \ -ASSYM(name, offsetof(struct parenttype, name)); \ +char OfFsEt__ ## parenttype ## __ ## name ## __ ## datatype [offsetof(struct parenttype, name)]; \ char name ## _datatype_ ## datatype [1]; \ char name ## _parenttype_ ## parenttype [1]; \ CTASSERT(__builtin_types_compatible_p(__typeof(((struct parenttype *)(0x0))-> name), datatype)); \