| 1 | #!/bin/bash |
|---|
| 2 | set -u |
|---|
| 3 | |
|---|
| 4 | # This script generates symbol lists from all tested/testable artefacts (libraries). |
|---|
| 5 | # These lists are stored in subdirectories ./tests or ./tests.slow. |
|---|
| 6 | # |
|---|
| 7 | # Format of generated symbol lists (SYMLIST_FORMAT): |
|---|
| 8 | # |
|---|
| 9 | # each line contains one symbol definition as semicolon-separated list |
|---|
| 10 | # containing the following fields: |
|---|
| 11 | # |
|---|
| 12 | # Index Content Description |
|---|
| 13 | # ----- ------- ----------- |
|---|
| 14 | # 1 scope 'ref' = reference to symbol; 'def' = definition of symbol |
|---|
| 15 | # 2 type 'sub' = subroutine; 'var' = variable; 'unk' = unknown |
|---|
| 16 | # 3 symbol demangled linkage name of symbol |
|---|
| 17 | # 4 location [optional] location of symbol definition in the form 'file:line[:column]' |
|---|
| 18 | # |
|---|
| 19 | # Notes: |
|---|
| 20 | # - location is present in DEBUG mode and for all defined symbols. |
|---|
| 21 | # - symbol references always have unknown type. |
|---|
| 22 | # - only external symbols are listed. |
|---|
| 23 | |
|---|
| 24 | TEMPDIR=$(mktemp -d) |
|---|
| 25 | trap 'rm -rf "$TEMPDIR"' EXIT |
|---|
| 26 | |
|---|
| 27 | filt_od_out() { |
|---|
| 28 | ./filter_objdump_syms.pl |
|---|
| 29 | } |
|---|
| 30 | |
|---|
| 31 | filt_od_err() { |
|---|
| 32 | # exitcode of this method is ignored. |
|---|
| 33 | |
|---|
| 34 | # grep -v 'hello' |
|---|
| 35 | sed 's/^/ERR: /' |
|---|
| 36 | } |
|---|
| 37 | |
|---|
| 38 | annotate_symlist() { |
|---|
| 39 | local SYMLIST="$1" |
|---|
| 40 | ./annotate_dwarf_locations.pl ${SYMLIST} |
|---|
| 41 | } |
|---|
| 42 | |
|---|
| 43 | TEEDWARFTO= |
|---|
| 44 | TEESYMSTO= |
|---|
| 45 | |
|---|
| 46 | EXTRACT_LOCATIONS=1 |
|---|
| 47 | if [ ${DARWIN} -eq 1 ]; then |
|---|
| 48 | echo "Note: symbol locations not supported under OSX" >&2 |
|---|
| 49 | EXTRACT_LOCATIONS=0 |
|---|
| 50 | fi |
|---|
| 51 | |
|---|
| 52 | # to test DARWIN behavior under LINUX uncommenct the next line: |
|---|
| 53 | # EXTRACT_LOCATIONS=0 |
|---|
| 54 | |
|---|
| 55 | extract_symbols() { |
|---|
| 56 | local artefact="$1" |
|---|
| 57 | |
|---|
| 58 | local syms_cmd="objdump --syms ${artefact} | c++filt" |
|---|
| 59 | local TEMPSYMS=${TEMPDIR}/syms.out |
|---|
| 60 | |
|---|
| 61 | local RESULT=0 |
|---|
| 62 | local result= # result contains exitcodes of: writer[0] reader[1] |
|---|
| 63 | set -o pipefail |
|---|
| 64 | |
|---|
| 65 | if [ -n "${TEESYMSTO}" ]; then |
|---|
| 66 | eval "$syms_cmd" 2> >(filt_od_err >&2) | tee "${TEESYMSTO}" | filt_od_out > ${TEMPSYMS} |
|---|
| 67 | result=( ${PIPESTATUS[0]} ${PIPESTATUS[2]} ) |
|---|
| 68 | else |
|---|
| 69 | eval "$syms_cmd" 2> >(filt_od_err >&2) | filt_od_out > ${TEMPSYMS} |
|---|
| 70 | result=( ${PIPESTATUS[0]} ${PIPESTATUS[1]} ) |
|---|
| 71 | fi |
|---|
| 72 | |
|---|
| 73 | if [ ${result[1]} -ne 0 ]; then |
|---|
| 74 | RESULT=${result[1]} |
|---|
| 75 | echo "Error: reader filt_od_out() failed with exit code ${RESULT}" >&2 |
|---|
| 76 | elif [ ${result[0]} -ne 0 ]; then |
|---|
| 77 | RESULT=${result[0]} |
|---|
| 78 | echo "Error: writer syms_cmd failed with exit code ${RESULT}: $syms_cmd" >&2 |
|---|
| 79 | fi |
|---|
| 80 | if [ ${RESULT} -eq 0 ]; then |
|---|
| 81 | if [ ${EXTRACT_LOCATIONS} -eq 0 ]; then |
|---|
| 82 | echo "Note: skipping symbol location extraction" >&2 |
|---|
| 83 | cat ${TEMPSYMS} |
|---|
| 84 | else |
|---|
| 85 | local dwarf_cmd="objdump --dwarf ${artefact} | c++filt" |
|---|
| 86 | if [ -n "${TEEDWARFTO}" ]; then |
|---|
| 87 | eval "$dwarf_cmd" 2> >(filt_od_err >&2) | tee "${TEEDWARFTO}" | annotate_symlist ${TEMPSYMS} |
|---|
| 88 | result=( ${PIPESTATUS[0]} ${PIPESTATUS[2]} ) |
|---|
| 89 | else |
|---|
| 90 | eval "$dwarf_cmd" 2> >(filt_od_err >&2) | annotate_symlist ${TEMPSYMS} |
|---|
| 91 | result=( ${PIPESTATUS[0]} ${PIPESTATUS[1]} ) |
|---|
| 92 | fi |
|---|
| 93 | if [ ${result[1]} -ne 0 ]; then |
|---|
| 94 | RESULT=${result[1]} |
|---|
| 95 | echo "Error: reader annotate_symlist() failed with exit code ${RESULT}" >&2 |
|---|
| 96 | elif [ ${result[0]} -ne 0 ]; then |
|---|
| 97 | RESULT=${result[0]} |
|---|
| 98 | echo "Error: writer dwarf_cmd failed with exit code ${RESULT}: $dwarf_cmd" >&2 |
|---|
| 99 | fi |
|---|
| 100 | fi |
|---|
| 101 | fi |
|---|
| 102 | wait |
|---|
| 103 | set +o pipefail |
|---|
| 104 | exit ${RESULT} |
|---|
| 105 | } |
|---|
| 106 | |
|---|
| 107 | # ---------------------------------------- |
|---|
| 108 | |
|---|
| 109 | FULLLIB=${1:-} |
|---|
| 110 | SYMLIST=${2:-} |
|---|
| 111 | |
|---|
| 112 | if [ -z ${SYMLIST} ]; then |
|---|
| 113 | echo "Usage: $0 <fulllib> <symlist>"; |
|---|
| 114 | exit 1 |
|---|
| 115 | fi |
|---|
| 116 | |
|---|
| 117 | # For debugging you may tee the output from one or both objdump calls to files, |
|---|
| 118 | # by un-commenting the following lines: |
|---|
| 119 | # TEEDWARFTO=${SYMLIST/.sym/.dwarf_sym} |
|---|
| 120 | # TEESYMSTO=${SYMLIST/.sym/.syms_sym} |
|---|
| 121 | |
|---|
| 122 | echo "[extracting with objdump ..]" |
|---|
| 123 | extract_symbols "$FULLLIB" > "$SYMLIST" |
|---|
| 124 | RESULT=$? |
|---|
| 125 | |
|---|
| 126 | echo "[done]" |
|---|
| 127 | exit $RESULT |
|---|