xref: /dpdk/devtools/check-symbol-change.sh (revision af14b150)
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 inside a section, nothing to do
134			if [ "$oldsecname" = "$secname" ]
135			then
136				continue
137			fi
138
139			# This symbol is moving between two sections (the
140			# original section is not experimental).
141			# This can be legit, just warn.
142			if [ "$oldsecname" != 'EXPERIMENTAL' ]
143			then
144				echo -n "INFO: symbol $symname is being "
145				echo -n "moved from $oldsecname to $secname. "
146				echo -n "Ensure that it has gone through the "
147				echo "deprecation process"
148				continue
149			fi
150		else
151
152			if ! grep -q "$mname $symname .* add" "$mapdb" && \
153			   [ "$secname" != "EXPERIMENTAL" ]
154			then
155				# Just inform users that non-experimenal
156				# symbols need to go through a deprecation
157				# process
158				echo -n "INFO: symbol $symname is being "
159				echo -n "removed, ensure that it has "
160				echo "gone through the deprecation process"
161			fi
162		fi
163	done < "$mapdb"
164
165	return $ret
166}
167
168trap clean_and_exit_on_sig EXIT
169
170mapfile=`mktemp -t dpdk.mapdb.XXXXXX`
171patch=$1
172exit_code=1
173
174clean_and_exit_on_sig()
175{
176	rm -f "$mapfile"
177	exit $exit_code
178}
179
180build_map_changes "$patch" "$mapfile"
181check_for_rule_violations "$mapfile"
182exit_code=$?
183rm -f "$mapfile"
184
185exit $exit_code
186