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