dpdk/devtools/check-symbol-change.sh
<<
>>
Prefs
   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 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
  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 insuficient 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