Loading...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 | #!/bin/sh # build id cache operations # SPDX-License-Identifier: GPL-2.0 # skip if there's no readelf if ! [ -x "$(command -v readelf)" ]; then echo "failed: no readelf, install binutils" exit 2 fi # skip if there's no compiler if ! [ -x "$(command -v cc)" ]; then echo "failed: no compiler, install gcc" exit 2 fi # check what we need to test windows binaries add_pe=1 run_pe=1 if ! perf version --build-options | grep -q 'libbfd: .* on '; then echo "WARNING: perf not built with libbfd. PE binaries will not be tested." add_pe=0 run_pe=0 fi if ! which wine > /dev/null; then echo "WARNING: wine not found. PE binaries will not be run." run_pe=0 fi # set up wine if [ ${run_pe} -eq 1 ]; then wineprefix=$(mktemp -d /tmp/perf.wineprefix.XXX) export WINEPREFIX=${wineprefix} # clear display variables to prevent wine from popping up dialogs unset DISPLAY unset WAYLAND_DISPLAY fi ex_md5=$(mktemp /tmp/perf.ex.MD5.XXX) ex_sha1=$(mktemp /tmp/perf.ex.SHA1.XXX) ex_pe=$(dirname $0)/../pe-file.exe echo 'int main(void) { return 0; }' | cc -Wl,--build-id=sha1 -o ${ex_sha1} -x c - echo 'int main(void) { return 0; }' | cc -Wl,--build-id=md5 -o ${ex_md5} -x c - echo "test binaries: ${ex_sha1} ${ex_md5} ${ex_pe}" check() { case $1 in *.exe) # We don't have a tool that can pull a nicely formatted build-id out of # a PE file, but we can extract the whole section with objcopy and # format it ourselves. The .buildid section is a Debug Directory # containing a CodeView entry: # https://docs.microsoft.com/en-us/windows/win32/debug/pe-format#debug-directory-image-only # https://github.com/dotnet/runtime/blob/da94c022576a5c3bbc0e896f006565905eb137f9/docs/design/specs/PE-COFF.md # The build-id starts at byte 33 and must be rearranged into a GUID. id=`objcopy -O binary --only-section=.buildid $1 /dev/stdout | \ cut -c 33-48 | hexdump -ve '/1 "%02x"' | \ sed 's@^\(..\)\(..\)\(..\)\(..\)\(..\)\(..\)\(..\)\(..\)\(.*\)0a$@\4\3\2\1\6\5\8\7\9@'` ;; *) id=`readelf -n ${1} 2>/dev/null | grep 'Build ID' | awk '{print $3}'` ;; esac echo "build id: ${id}" link=${build_id_dir}/.build-id/${id:0:2}/${id:2} echo "link: ${link}" if [ ! -h $link ]; then echo "failed: link ${link} does not exist" exit 1 fi file=${build_id_dir}/.build-id/${id:0:2}/`readlink ${link}`/elf echo "file: ${file}" if [ ! -x $file ]; then echo "failed: file ${file} does not exist" exit 1 fi diff ${file} ${1} if [ $? -ne 0 ]; then echo "failed: ${file} do not match" exit 1 fi ${perf} buildid-cache -l | grep ${id} if [ $? -ne 0 ]; then echo "failed: ${id} is not reported by \"perf buildid-cache -l\"" exit 1 fi echo "OK for ${1}" } test_add() { build_id_dir=$(mktemp -d /tmp/perf.debug.XXX) perf="perf --buildid-dir ${build_id_dir}" ${perf} buildid-cache -v -a ${1} if [ $? -ne 0 ]; then echo "failed: add ${1} to build id cache" exit 1 fi check ${1} rm -rf ${build_id_dir} } test_record() { data=$(mktemp /tmp/perf.data.XXX) build_id_dir=$(mktemp -d /tmp/perf.debug.XXX) log=$(mktemp /tmp/perf.log.XXX) perf="perf --buildid-dir ${build_id_dir}" echo "running: perf record $@" ${perf} record --buildid-all -o ${data} $@ &> ${log} if [ $? -ne 0 ]; then echo "failed: record $@" echo "see log: ${log}" exit 1 fi check ${@: -1} rm -f ${log} rm -rf ${build_id_dir} rm -rf ${data} } # add binaries manual via perf buildid-cache -a test_add ${ex_sha1} test_add ${ex_md5} if [ ${add_pe} -eq 1 ]; then test_add ${ex_pe} fi # add binaries via perf record post processing test_record ${ex_sha1} test_record ${ex_md5} if [ ${run_pe} -eq 1 ]; then test_record wine ${ex_pe} fi # cleanup rm ${ex_sha1} ${ex_md5} if [ ${run_pe} -eq 1 ]; then rm -r ${wineprefix} fi exit ${err} |