5a5f4676eb
The regex to determine the end of the map file chunk in a patch seems to
be wrong, It was using perl regex syntax, which awk doesn't appear to
support (I'm still not sure how it was working previously). Regardless,
it wasn't triggering and as a result symbols were getting added to the
mapdb that shouldn't be there.
Fix it by converting the regex to use traditional posix syntax, matching
only on the negation of the character class [^map]
Tested and shown to be working on the ip_frag patch set provided by
doucette@bu.edu
Fixes: 4bec48184e
("devtools: add checks for ABI symbol addition")
Cc: stable@dpdk.org
Reported-by: Cody Doucette <doucette@bu.edu>
Signed-off-by: Neil Horman <nhorman@tuxdriver.com>
159 lines
4.1 KiB
Bash
Executable File
159 lines
4.1 KiB
Bash
Executable File
#!/bin/sh
|
|
# SPDX-License-Identifier: BSD-3-Clause
|
|
# Copyright(c) 2018 Neil Horman <nhorman@tuxdriver.com>
|
|
|
|
build_map_changes()
|
|
{
|
|
local fname="$1"
|
|
local mapdb="$2"
|
|
|
|
cat "$fname" | awk '
|
|
# Initialize our variables
|
|
BEGIN {map="";sym="";ar="";sec=""; in_sec=0; in_map=0}
|
|
|
|
# Anything that starts with + or -, followed by an a
|
|
# and ends in the string .map is the name of our map file
|
|
# This may appear multiple times in a patch if multiple
|
|
# map files are altered, and all section/symbol names
|
|
# appearing between a triggering of this rule and the
|
|
# next trigger of this rule are associated with this file
|
|
/[-+] a\/.*\.map/ {map=$2; in_map=1}
|
|
|
|
# Same pattern as above, only it matches on anything that
|
|
# does not end in 'map', indicating we have left the map chunk.
|
|
# When we hit this, turn off the in_map variable, which
|
|
# supresses the subordonate rules below
|
|
/[-+] a\/.*\.[^map]/ {in_map=0}
|
|
|
|
# Triggering this rule, which starts a line and ends it
|
|
# with a { identifies a versioned section. The section name is
|
|
# the rest of the line with the + and { symbols remvoed.
|
|
# Triggering this rule sets in_sec to 1, which actives the
|
|
# symbol rule below
|
|
/^.*{/ {
|
|
if (in_map == 1) {
|
|
sec=$(NF-1); in_sec=1;
|
|
}
|
|
}
|
|
|
|
# This rule idenfies the end of a section, and disables the
|
|
# symbol rule
|
|
/.*}/ {in_sec=0}
|
|
|
|
# This rule matches on a + followed by any characters except a :
|
|
# (which denotes a global vs local segment), and ends with a ;.
|
|
# The semicolon is removed and the symbol is printed with its
|
|
# association file name and version section, along with an
|
|
# indicator that the symbol is a new addition. Note this rule
|
|
# only works if we have found a version section in the rule
|
|
# above (hence the in_sec check) And found a map file (the
|
|
# in_map check). If we are not in a map chunk, do nothing. If
|
|
# we are in a map chunk but not a section chunk, record it as
|
|
# unknown.
|
|
/^+[^}].*[^:*];/ {gsub(";","");sym=$2;
|
|
if (in_map == 1) {
|
|
if (in_sec == 1) {
|
|
print map " " sym " " sec " add"
|
|
} else {
|
|
print map " " sym " unknown add"
|
|
}
|
|
}
|
|
}
|
|
|
|
# This is the same rule as above, but the rule matches on a
|
|
# leading - rather than a +, denoting that the symbol is being
|
|
# removed.
|
|
/^-[^}].*[^:*];/ {gsub(";","");sym=$2;
|
|
if (in_map == 1) {
|
|
if (in_sec == 1) {
|
|
print map " " sym " " sec " del"
|
|
} else {
|
|
print map " " sym " unknown del"
|
|
}
|
|
}
|
|
}' > "$mapdb"
|
|
|
|
sort -u "$mapdb" > "$mapdb.2"
|
|
mv -f "$mapdb.2" "$mapdb"
|
|
|
|
}
|
|
|
|
check_for_rule_violations()
|
|
{
|
|
local mapdb="$1"
|
|
local mname
|
|
local symname
|
|
local secname
|
|
local ar
|
|
local ret=0
|
|
|
|
while read mname symname secname ar
|
|
do
|
|
if [ "$ar" = "add" ]
|
|
then
|
|
|
|
if [ "$secname" = "unknown" ]
|
|
then
|
|
# Just inform the user of this occurrence, but
|
|
# don't flag it as an error
|
|
echo -n "INFO: symbol $syname is added but "
|
|
echo -n "patch has insuficient context "
|
|
echo -n "to determine the section name "
|
|
echo -n "please ensure the version is "
|
|
echo "EXPERIMENTAL"
|
|
continue
|
|
fi
|
|
|
|
if [ "$secname" != "EXPERIMENTAL" ]
|
|
then
|
|
# Symbols that are getting added in a section
|
|
# other than the experimental section
|
|
# to be moving from an already supported
|
|
# section or its a violation
|
|
grep -q \
|
|
"$mname $symname [^EXPERIMENTAL] del" "$mapdb"
|
|
if [ $? -ne 0 ]
|
|
then
|
|
echo -n "ERROR: symbol $symname "
|
|
echo -n "is added in a section "
|
|
echo -n "other than the EXPERIMENTAL "
|
|
echo "section of the version map"
|
|
ret=1
|
|
fi
|
|
fi
|
|
else
|
|
|
|
if [ "$secname" != "EXPERIMENTAL" ]
|
|
then
|
|
# Just inform users that non-experimenal
|
|
# symbols need to go through a deprecation
|
|
# process
|
|
echo -n "INFO: symbol $symname is being "
|
|
echo -n "removed, ensure that it has "
|
|
echo "gone through the deprecation process"
|
|
fi
|
|
fi
|
|
done < "$mapdb"
|
|
|
|
return $ret
|
|
}
|
|
|
|
trap clean_and_exit_on_sig EXIT
|
|
|
|
mapfile=`mktemp -t dpdk.mapdb.XXXXXX`
|
|
patch=$1
|
|
exit_code=1
|
|
|
|
clean_and_exit_on_sig()
|
|
{
|
|
rm -f "$mapfile"
|
|
exit $exit_code
|
|
}
|
|
|
|
build_map_changes "$patch" "$mapfile"
|
|
check_for_rule_violations "$mapfile"
|
|
exit_code=$?
|
|
rm -f "$mapfile"
|
|
|
|
exit $exit_code
|