xref: /dpdk/devtools/check-symbol-change.sh (revision f00d0d5fb652504ad6af2ab1a8b146b1cb86fe38)
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		/[-+] 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			if (in_map == 1) {
35				sec=$(NF-1); in_sec=1;
36			}
37		}
38
39		# This rule idenfies the end of a section, and disables the
40		# symbol rule
41		/.*}/ {in_sec=0}
42
43		# This rule matches on a + followed by any characters except a :
44		# (which denotes a global vs local segment), and ends with a ;.
45		# The semicolon is removed and the symbol is printed with its
46		# association file name and version section, along with an
47		# indicator that the symbol is a new addition.  Note this rule
48		# only works if we have found a version section in the rule
49		# above (hence the in_sec check) And found a map file (the
50		# in_map check).  If we are not in a map chunk, do nothing.  If
51		# we are in a map chunk but not a section chunk, record it as
52		# unknown.
53		/^+[^}].*[^:*];/ {gsub(";","");sym=$2;
54			if (in_map == 1) {
55				if (in_sec == 1) {
56					print map " " sym " " sec " add"
57				} else {
58					print map " " sym " unknown add"
59				}
60			}
61		}
62
63		# This is the same rule as above, but the rule matches on a
64		# leading - rather than a +, denoting that the symbol is being
65		# removed.
66		/^-[^}].*[^:*];/ {gsub(";","");sym=$2;
67			if (in_map == 1) {
68				if (in_sec == 1) {
69					print map " " sym " " sec " del"
70				} else {
71					print map " " sym " unknown del"
72				}
73			}
74		}' > "$mapdb"
75
76		sort -u "$mapdb" > "$mapdb.2"
77		mv -f "$mapdb.2" "$mapdb"
78
79}
80
81check_for_rule_violations()
82{
83	local mapdb="$1"
84	local mname
85	local symname
86	local secname
87	local ar
88	local ret=0
89
90	while read mname symname secname ar
91	do
92		if [ "$ar" = "add" ]
93		then
94
95			if [ "$secname" = "unknown" ]
96			then
97				# Just inform the user of this occurrence, but
98				# don't flag it as an error
99				echo -n "INFO: symbol $syname is added but "
100				echo -n "patch has insuficient context "
101				echo -n "to determine the section name "
102				echo -n "please ensure the version is "
103				echo "EXPERIMENTAL"
104				continue
105			fi
106
107			if [ "$secname" != "EXPERIMENTAL" ]
108			then
109				# Symbols that are getting added in a section
110				# other than the experimental section
111				# to be moving from an already supported
112				# section or its a violation
113				grep -q \
114				"$mname $symname [^EXPERIMENTAL] del" "$mapdb"
115				if [ $? -ne 0 ]
116				then
117					echo -n "ERROR: symbol $symname "
118					echo -n "is added in a section "
119					echo -n "other than the EXPERIMENTAL "
120					echo "section of the version map"
121					ret=1
122				fi
123			fi
124		else
125
126			if [ "$secname" != "EXPERIMENTAL" ]
127			then
128				# Just inform users that non-experimenal
129				# symbols need to go through a deprecation
130				# process
131				echo -n "INFO: symbol $symname is being "
132				echo -n "removed, ensure that it has "
133				echo "gone through the deprecation process"
134			fi
135		fi
136	done < "$mapdb"
137
138	return $ret
139}
140
141trap clean_and_exit_on_sig EXIT
142
143mapfile=`mktemp -t dpdk.mapdb.XXXXXX`
144patch=$1
145exit_code=1
146
147clean_and_exit_on_sig()
148{
149	rm -f "$mapfile"
150	exit $exit_code
151}
152
153build_map_changes "$patch" "$mapfile"
154check_for_rule_violations "$mapfile"
155exit_code=$?
156rm -f "$mapfile"
157
158exit $exit_code
159