#! /bin/sh # Script to test that all the symbols of a shared object are as expected. set -e # Ensure stable ordering of `sort` output LANG=C LC_ALL=C export LANG LC_ALL if [ "$1" = "" -o "$2" = "" ] ; then echo "Usage: $0 " >&2 exit 1 fi input_dir="$1" manifest_dir="$2" sed=sed grep=grep # Helpers for Solaris if [ -f /usr/bin/gsed ] ; then sed=/usr/bin/gsed fi if [ -f /usr/bin/ggrep ] ; then grep=/usr/bin/ggrep fi nm="nm -B -D" if [ "`uname -s`" = "Linux" ]; then nm="$nm --with-symbol-versions" elif [ "`uname -s`" = "FreeBSD" ]; then # Use llvm-nm to get symbol version information nm="llvm-nm -B -D" elif [ "`uname -s`" = "SunOS" ]; then # Highly annoyingly, Solaris' nm doesn't show symbol versions, so here is a # laborious way to reformat the output of elfdump to be as we require. #nm="nm -p -h -D -g" nm=emulated_nm emulated_nm() { # Grab the versions from the version table, and convert into a sed script. VERSUB=`elfdump -v "$1" | \ $grep -E '^\s*\[[0-9]+\]' | \ $sed -E -e 's/\s+/,/g' | \ tr -d '\[\]' | \ cut -d',' -f 2,3 | \ $sed -E -e 's/([0-9]+),(.*)/s\/@@\1\/@@\2\/;/'` # Then grab the symbols and heavily reformat the output to match nm. elfdump -T SHT_DYNSYM "$1" | \ $grep -E '^\s*\[[0-9]+\]' | \ $sed -E -e 's/\s+/ /g' | \ cut -d' ' -f 3,8,9,10 | \ $sed -E -e 's/^0x//;s/([^ ]*) ([^ ]*) ([^ ]*) ([^ ]*)/\1 \3 \4@@\2/;' | \ $sed -E -e 's/^([^ ]*) .text /\1 T /' | \ $sed -E -e 's/^([^ ]*) ([UA])(NDEF|BS) /\1 \2 /' | \ $sed -E -e "$VERSUB" } elif [ "`uname -s`" = "Darwin" ]; then nm="nm -B -g" fi supports_versions=1 if [ "`uname -s`" = "Darwin" ]; then supports_versions=0 fi so_ext=so so_mangling() { cat; } if [ "`uname -s`" = "Darwin" ]; then so_ext=dylib so_mangling() { $sed -E -e 's/_([_0-9a-zA-Z]+)$/\1/g' } fi for so_name in "libpcre2-8" "libpcre2-16" "libpcre2-32" "libpcre2-posix"; do expected_file="$manifest_dir/manifest-$so_name.so" so_file="$input_dir/$so_name.$so_ext" base=`basename $expected_file` $nm "$so_file" | \ $sed -E -e 's/^[0-9a-fA-F]* *//g' | \ $grep -E -v '^[Uw] ' | \ $grep -E -v '^A PCRE2_' | \ $grep -E -v ' (_init|_fini)($|@)' | \ $grep -E -v ' (_end|_DYNAMIC|_GLOBAL_OFFSET_TABLE_|_PROCEDURE_LINKAGE_TABLE_|_edata|_etext)($|@)' | \ so_mangling | \ sort \ > "$base.actual" if [ $supports_versions -eq 0 ]; then $sed -E -e 's/@.*$//' "$expected_file" \ > "$base.expected" else cp "$expected_file" "$base.expected" fi if ! diff -u "$base.expected" "$base.actual"; then echo "Shared object contents for $so_file differ from expected" echo "===Actual===" cat "$base.actual" echo "===End===" exit 1 fi echo "Shared object contents for $so_file match expected" rm -f "$base.expected" "$base.actual" done