1#!/bin/sh 2# SPDX-License-Identifier: BSD-3-Clause 3# Copyright(c) 2018 Neil Horman <[email protected]> 4 5build_map_changes() 6{ 7 local fname="$1" 8 local mapdb="$2" 9 10 cat "$fname" | awk ' 11 # Initialize our variables 12 BEGIN {map="";sym="";ar="";sec=""; in_sec=0; in_map=0} 13 14 # Anything that starts with + or -, followed by an a 15 # and ends in the string .map is the name of our map file 16 # This may appear multiple times in a patch if multiple 17 # map files are altered, and all section/symbol names 18 # appearing between a triggering of this rule and the 19 # next trigger of this rule are associated with this file 20 /[-+] a\/.*\.map/ {map=$2; in_map=1} 21 22 # Same pattern as above, only it matches on anything that 23 # does not end in 'map', indicating we have left the map chunk. 24 # When we hit this, turn off the in_map variable, which 25 # supresses the subordonate rules below 26 /[-+] a\/.*\.[^map]/ {in_map=0} 27 28 # Triggering this rule, which starts a line and ends it 29 # with a { identifies a versioned section. The section name is 30 # the rest of the line with the + and { symbols remvoed. 31 # Triggering this rule sets in_sec to 1, which actives the 32 # symbol rule below 33 /^.*{/ { 34 gsub("+", ""); 35 if (in_map == 1) { 36 sec=$(NF-1); in_sec=1; 37 } 38 } 39 40 # This rule idenfies the end of a section, and disables the 41 # symbol rule 42 /.*}/ {in_sec=0} 43 44 # This rule matches on a + followed by any characters except a : 45 # (which denotes a global vs local segment), and ends with a ;. 46 # The semicolon is removed and the symbol is printed with its 47 # association file name and version section, along with an 48 # indicator that the symbol is a new addition. Note this rule 49 # only works if we have found a version section in the rule 50 # above (hence the in_sec check) And found a map file (the 51 # in_map check). If we are not in a map chunk, do nothing. If 52 # we are in a map chunk but not a section chunk, record it as 53 # unknown. 54 /^+[^}].*[^:*];/ {gsub(";","");sym=$2; 55 if (in_map == 1) { 56 if (in_sec == 1) { 57 print map " " sym " " sec " add" 58 } else { 59 print map " " sym " unknown add" 60 } 61 } 62 } 63 64 # This is the same rule as above, but the rule matches on a 65 # leading - rather than a +, denoting that the symbol is being 66 # removed. 67 /^-[^}].*[^:*];/ {gsub(";","");sym=$2; 68 if (in_map == 1) { 69 if (in_sec == 1) { 70 print map " " sym " " sec " del" 71 } else { 72 print map " " sym " unknown del" 73 } 74 } 75 }' > "$mapdb" 76 77 sort -u "$mapdb" > "$mapdb.2" 78 mv -f "$mapdb.2" "$mapdb" 79 80} 81 82check_for_rule_violations() 83{ 84 local mapdb="$1" 85 local mname 86 local symname 87 local secname 88 local ar 89 local ret=0 90 91 while read mname symname secname ar 92 do 93 if [ "$ar" = "add" ] 94 then 95 96 if [ "$secname" = "unknown" ] 97 then 98 # Just inform the user of this occurrence, but 99 # don't flag it as an error 100 echo -n "INFO: symbol $symname is added but " 101 echo -n "patch has insuficient context " 102 echo -n "to determine the section name " 103 echo -n "please ensure the version is " 104 echo "EXPERIMENTAL" 105 continue 106 fi 107 108 oldsecname=$(sed -n \ 109 "s#$mname $symname \(.*\) del#\1#p" "$mapdb") 110 111 # A symbol can not enter a non experimental 112 # section directly 113 if [ -z "$oldsecname" ] 114 then 115 if [ "$secname" = 'EXPERIMENTAL' ] 116 then 117 echo -n "INFO: symbol $symname has " 118 echo -n "been added to the " 119 echo -n "EXPERIMENTAL section of the " 120 echo "version map" 121 continue 122 else 123 echo -n "ERROR: symbol $symname " 124 echo -n "is added in the $secname " 125 echo -n "section, but is expected to " 126 echo -n "be added in the EXPERIMENTAL " 127 echo "section of the version map" 128 ret=1 129 continue 130 fi 131 fi 132 133 # This symbol is moving between two sections (the 134 # original section is not experimental). 135 # This can be legit, just warn. 136 if [ "$oldsecname" != 'EXPERIMENTAL' ] 137 then 138 echo -n "INFO: symbol $symname is being " 139 echo -n "moved from $oldsecname to $secname. " 140 echo -n "Ensure that it has gone through the " 141 echo "deprecation process" 142 continue 143 fi 144 else 145 146 if ! grep -q "$mname $symname .* add" "$mapdb" && \ 147 [ "$secname" != "EXPERIMENTAL" ] 148 then 149 # Just inform users that non-experimenal 150 # symbols need to go through a deprecation 151 # process 152 echo -n "INFO: symbol $symname is being " 153 echo -n "removed, ensure that it has " 154 echo "gone through the deprecation process" 155 fi 156 fi 157 done < "$mapdb" 158 159 return $ret 160} 161 162trap clean_and_exit_on_sig EXIT 163 164mapfile=`mktemp -t dpdk.mapdb.XXXXXX` 165patch=$1 166exit_code=1 167 168clean_and_exit_on_sig() 169{ 170 rm -f "$mapfile" 171 exit $exit_code 172} 173 174build_map_changes "$patch" "$mapfile" 175check_for_rule_violations "$mapfile" 176exit_code=$? 177rm -f "$mapfile" 178 179exit $exit_code 180