kernel-no-perl.patch (7753B)
1 --- a/lib/Makefile 2 +++ b/lib/Makefile 3 @@ -271,7 +271,7 @@ 4 $(call cmd,build_OID_registry) 5 6 quiet_cmd_build_OID_registry = GEN $@ 7 - cmd_build_OID_registry = perl $(srctree)/$(src)/build_OID_registry $< $@ 8 + cmd_build_OID_registry = $(CONFIG_SHELL) $(srctree)/$(src)/build_OID_registry <$< >$@ 9 10 clean-files += oid_registry_data.c 11 12 --- a/lib/build_OID_registry 13 +++ b/lib/build_OID_registry 14 @@ -1,4 +1,4 @@ 15 -#!/usr/bin/perl -w 16 +#!/bin/sh 17 # SPDX-License-Identifier: GPL-2.0-or-later 18 # 19 # Build a static ASN.1 Object Identified (OID) registry 20 @@ -7,197 +7,93 @@ 21 # Written by David Howells (dhowells@redhat.com) 22 # 23 24 -use strict; 25 - 26 -my @names = (); 27 -my @oids = (); 28 - 29 -if ($#ARGV != 1) { 30 - print STDERR "Format: ", $0, " <in-h-file> <out-c-file>\n"; 31 - exit(2); 32 -} 33 - 34 # 35 -# Open the file to read from 36 +# Read OID lines and determine the lengths of the encoded data arrays. 37 # 38 -open IN_FILE, "<$ARGV[0]" || die; 39 -while (<IN_FILE>) { 40 - chomp; 41 - if (m!\s+OID_([a-zA-z][a-zA-Z0-9_]+),\s+/[*]\s+([012][.0-9]*)\s+[*]/!) { 42 - push @names, $1; 43 - push @oids, $2; 44 - } 45 -} 46 -close IN_FILE || die; 47 +set -f -- # use "$@" array for data 48 +total_length=0 IFS='.' 49 +while IFS=' ' read -r line; do 50 + if [ "${line#OID_[a-z]}" != "$line" ]; then 51 + name="${line#*_}" name="${name%,*}" oid="${line#*/* }" oid="${oid% */}" 52 + # shellcheck disable=SC2086 53 + size="$(set -- $oid; printf '%u' "$(($# - 1))")" 54 + for c in $oid; do 55 + # We will base128 encode the number 56 + : "$((size += c ? $(awk "BEGIN{print int(log($c)/log(2)/7)}") : 0))" 57 + done 58 + set -- "$@" "$name:$oid:$total_length" 59 + : "$((total_length += size))" 60 + fi 61 +done 62 63 # 64 -# Open the files to write into 65 -# 66 -open C_FILE, ">$ARGV[1]" or die; 67 -print C_FILE "/*\n"; 68 -print C_FILE " * Automatically generated by ", $0, ". Do not edit\n"; 69 -print C_FILE " */\n"; 70 - 71 -# 72 -# Split the data up into separate lists and also determine the lengths of the 73 -# encoded data arrays. 74 -# 75 -my @indices = (); 76 -my @lengths = (); 77 -my $total_length = 0; 78 - 79 -for (my $i = 0; $i <= $#names; $i++) { 80 - my $name = $names[$i]; 81 - my $oid = $oids[$i]; 82 - 83 - my @components = split(/[.]/, $oid); 84 - 85 - # Determine the encoded length of this OID 86 - my $size = $#components; 87 - for (my $loop = 2; $loop <= $#components; $loop++) { 88 - my $c = $components[$loop]; 89 - 90 - # We will base128 encode the number 91 - my $tmp = ($c == 0) ? 0 : int(log($c)/log(2)); 92 - $tmp = int($tmp / 7); 93 - $size += $tmp; 94 - } 95 - push @lengths, $size; 96 - push @indices, $total_length; 97 - $total_length += $size; 98 -} 99 - 100 -# 101 # Emit the look-up-by-OID index table 102 # 103 -print C_FILE "\n"; 104 -if ($total_length <= 255) { 105 - print C_FILE "static const unsigned char oid_index[OID__NR + 1] = {\n"; 106 -} else { 107 - print C_FILE "static const unsigned short oid_index[OID__NR + 1] = {\n"; 108 -} 109 -for (my $i = 0; $i <= $#names; $i++) { 110 - print C_FILE "\t[OID_", $names[$i], "] = ", $indices[$i], ",\n" 111 -} 112 -print C_FILE "\t[OID__NR] = ", $total_length, "\n"; 113 -print C_FILE "};\n"; 114 +printf '/*\n * Automatically generated by %s. Do not edit\n */\n\n' "$0" 115 +if [ "$total_length" -le 255 ]; then 116 + printf 'static const unsigned char oid_index[OID__NR + 1] = {\n' 117 +else 118 + printf 'static const unsigned short oid_index[OID__NR + 1] = {\n' 119 +fi 120 +for i do 121 + printf '\t[OID_%s] = %u,\n' "${i%%:*}" "${i##*:}" 122 +done 123 +printf '\t[OID__NR] = %u\n};\n\n' "$total_length" 124 125 # 126 -# Encode the OIDs 127 +# Encode the OIDs and emit the OID data 128 # 129 -my @encoded_oids = (); 130 +printf 'static const unsigned char oid_data[%u] = {\n' "$total_length" 131 +for i do 132 + IFS='.' j=0 i="${i%:*}" 133 + for c in ${i##*:}; do 134 + case "$((j += 1))" in 135 + 1) o="$((c * 40))";; 136 + 2) : "$((o += c))";; 137 + *) 138 + # Base128 encode the number 139 + tmp="$((c ? $(awk "BEGIN{print int(log($c)/log(2)/7)+1}") : 1))" 140 + while [ "$((tmp -= 1))" -gt 0 ]; do 141 + o="$o.$((c >> tmp * 7 & 127 | 128))" 142 + done 143 + o="$o.$((c & 127))" 144 + esac 145 + done 146 147 -for (my $i = 0; $i <= $#names; $i++) { 148 - my @octets = (); 149 + set -- "$@" "${i%:*}:$o" 150 + shift 151 152 - my @components = split(/[.]/, $oids[$i]); 153 + printf '\t' 154 + printf '%s, ' $o 155 + printf '\t// %s\n' "${i%:*}" 156 +done 157 +printf '};\n\n' 158 159 - push @octets, $components[0] * 40 + $components[1]; 160 +printf 'static const struct {\n\tunsigned char hash;\n' 161 +printf '\tenum OID oid : %u;\n} oid_search_table[OID__NR] = {' \ 162 + "$(($# <= 255 ? 8 : 16))" 163 164 - for (my $loop = 2; $loop <= $#components; $loop++) { 165 - my $c = $components[$loop]; 166 - 167 - # Base128 encode the number 168 - my $tmp = ($c == 0) ? 0 : int(log($c)/log(2)); 169 - $tmp = int($tmp / 7); 170 - 171 - for (; $tmp > 0; $tmp--) { 172 - push @octets, (($c >> $tmp * 7) & 0x7f) | 0x80; 173 - } 174 - push @octets, $c & 0x7f; 175 - } 176 - 177 - push @encoded_oids, \@octets; 178 -} 179 - 180 # 181 -# Create a hash value for each OID 182 +# Create a hash value for each OID and build and emit the search index and hash 183 +# value table (ordered by length then hash then content) 184 # 185 -my @hash_values = (); 186 -for (my $i = 0; $i <= $#names; $i++) { 187 - my @octets = @{$encoded_oids[$i]}; 188 - 189 - my $hash = $#octets; 190 - foreach (@octets) { 191 - $hash += $_ * 33; 192 - } 193 - 194 - $hash = ($hash >> 24) ^ ($hash >> 16) ^ ($hash >> 8) ^ ($hash); 195 - 196 - push @hash_values, $hash & 0xff; 197 -} 198 - 199 -# 200 -# Emit the OID data 201 -# 202 -print C_FILE "\n"; 203 -print C_FILE "static const unsigned char oid_data[", $total_length, "] = {\n"; 204 -for (my $i = 0; $i <= $#names; $i++) { 205 - my @octets = @{$encoded_oids[$i]}; 206 - print C_FILE "\t"; 207 - print C_FILE $_, ", " foreach (@octets); 208 - print C_FILE "\t// ", $names[$i]; 209 - print C_FILE "\n"; 210 -} 211 -print C_FILE "};\n"; 212 - 213 -# 214 -# Build the search index table (ordered by length then hash then content) 215 -# 216 -my @index_table = ( 0 .. $#names ); 217 - 218 -@index_table = sort { 219 - my @octets_a = @{$encoded_oids[$a]}; 220 - my @octets_b = @{$encoded_oids[$b]}; 221 - 222 - return $hash_values[$a] <=> $hash_values[$b] 223 - if ($hash_values[$a] != $hash_values[$b]); 224 - return $#octets_a <=> $#octets_b 225 - if ($#octets_a != $#octets_b); 226 - for (my $i = $#octets_a; $i >= 0; $i--) { 227 - return $octets_a[$i] <=> $octets_b[$i] 228 - if ($octets_a[$i] != $octets_b[$i]); 229 - } 230 - return 0; 231 - 232 -} @index_table; 233 - 234 -# 235 -# Emit the search index and hash value table 236 -# 237 -print C_FILE "\n"; 238 -print C_FILE "static const struct {\n"; 239 -print C_FILE "\tunsigned char hash;\n"; 240 -if ($#names <= 255) { 241 - print C_FILE "\tenum OID oid : 8;\n"; 242 -} else { 243 - print C_FILE "\tenum OID oid : 16;\n"; 244 -} 245 -print C_FILE "} oid_search_table[OID__NR] = {\n"; 246 -for (my $i = 0; $i <= $#names; $i++) { 247 - my @octets = @{$encoded_oids[$index_table[$i]]}; 248 - printf(C_FILE "\t[%3u] = { %3u, OID_%-35s }, // ", 249 - $i, 250 - $hash_values[$index_table[$i]], 251 - $names[$index_table[$i]]); 252 - printf C_FILE "%02x", $_ foreach (@octets); 253 - print C_FILE "\n"; 254 -} 255 -print C_FILE "};\n"; 256 - 257 -# 258 -# Emit the OID debugging name table 259 -# 260 -#print C_FILE "\n"; 261 -#print C_FILE "const char *const oid_name_table[OID__NR + 1] = {\n"; 262 -# 263 -#for (my $i = 0; $i <= $#names; $i++) { 264 -# print C_FILE "\t\"", $names[$i], "\",\n" 265 -#} 266 -#print C_FILE "\t\"Unknown-OID\"\n"; 267 -#print C_FILE "};\n"; 268 - 269 -# 270 -# Polish off 271 -# 272 -close C_FILE or die; 273 +i=-1 274 +for j do 275 + IFS='.' 276 + # shellcheck disable=SC2086 277 + count="$(set -- ${j##*:}; printf '%u' "$(($# - 1))")" 278 + hash="$count" 279 + set -- # use as array for reversing octet set 280 + for k in ${j##*:}; do 281 + : "$((hash += k * 33))" 282 + set -- "$k" "$@" 283 + done 284 + hash="$((hash >> 24 ^ hash >> 16 ^ hash >> 8 ^ hash & 255))" 285 + IFS=':' 286 + printf '%u:%s:%s:%u:%s\n' "$hash" "${j##*:}" "${j%%:*}" "$count" "$*" 287 +done | sort -nt: -k1,1 -k4,4 -k5 | while IFS=':' read -r num octets name _; do 288 + printf '\n\t[%3u] = { %3u, OID_%-35s }, // ' "$((i += 1))" "$num" "$name" 289 + # shellcheck disable=SC2086 290 + printf '%02x' $octets 291 +done 292 +printf '\n};\n'