1#!/bin/sh 2# SPDX-License-Identifier: BSD-3-Clause 3# Copyright(c) 2018 Neil Horman <nhorman@tuxdriver.com> 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 removed. 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 identifies 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 80is_stable_section() { 81 [ "$1" != 'EXPERIMENTAL' ] && [ "$1" != 'INTERNAL' ] 82} 83 84check_for_rule_violations() 85{ 86 local mapdb="$1" 87 local mname 88 local symname 89 local secname 90 local ar 91 local ret=0 92 93 while read mname symname secname ar 94 do 95 if [ "$ar" = "add" ] 96 then 97 98 if [ "$secname" = "unknown" ] 99 then 100 # Just inform the user of this occurrence, but 101 # don't flag it as an error 102 echo -n "INFO: symbol $symname is added but " 103 echo -n "patch has insufficient context " 104 echo -n "to determine the section name " 105 echo -n "please ensure the version is " 106 echo "EXPERIMENTAL" 107 continue 108 fi 109 110 oldsecname=$(sed -n \ 111 "s#$mname $symname \(.*\) del#\1#p" "$mapdb") 112 113 # A symbol can not enter a stable section directly 114 if [ -z "$oldsecname" ] 115 then 116 if ! is_stable_section $secname 117 then 118 echo -n "INFO: symbol $symname has " 119 echo -n "been added to the " 120 echo -n "$secname section of the " 121 echo "version map" 122 continue 123 else 124 echo -n "ERROR: symbol $symname " 125 echo -n "is added in the $secname " 126 echo -n "section, but is expected to " 127 echo -n "be added in the EXPERIMENTAL " 128 echo "section of the version map" 129 ret=1 130 continue 131 fi 132 fi 133 134 # This symbol is moving inside a section, nothing to do 135 if [ "$oldsecname" = "$secname" ] 136 then 137 continue 138 fi 139 140 # This symbol is moving between two sections (the 141 # original section is a stable section). 142 # This can be legit, just warn. 143 if is_stable_section $oldsecname 144 then 145 echo -n "INFO: symbol $symname is being " 146 echo -n "moved from $oldsecname to $secname. " 147 echo -n "Ensure that it has gone through the " 148 echo "deprecation process" 149 continue 150 fi 151 else 152 153 if ! grep -q "$mname $symname .* add" "$mapdb" && \ 154 is_stable_section $secname 155 then 156 # Just inform users that stable 157 # symbols need to go through a deprecation 158 # process 159 echo -n "INFO: symbol $symname is being " 160 echo -n "removed, ensure that it has " 161 echo "gone through the deprecation process" 162 fi 163 fi 164 done < "$mapdb" 165 166 return $ret 167} 168 169trap clean_and_exit_on_sig EXIT 170 171mapfile=`mktemp -t dpdk.mapdb.XXXXXX` 172patch=$1 173exit_code=1 174 175clean_and_exit_on_sig() 176{ 177 rm -f "$mapfile" 178 exit $exit_code 179} 180 181build_map_changes "$patch" "$mapfile" 182check_for_rule_violations "$mapfile" 183exit_code=$? 184rm -f "$mapfile" 185 186exit $exit_code 187