xref: /dpdk/devtools/check-symbol-change.sh (revision 7564d550)
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