Project

General

Profile

find_global_symbol.sh

script for finding global symbols - Robert Hatcher, 02/07/2018 11:50 PM

 
1
#! /bin/sh
2

    
3
#    Find global symbol.
4

    
5
#    Contact    N. West
6

    
7
#    Invocation:-
8
#    ==========
9

    
10
#    find_global_symbol.sh options symbol.  See help message below for details.
11

    
12

    
13
#    Specification:-
14
#    =============
15

    
16
#    o    Search through all .so files in all directories defined
17
#         in LD_LIBRARY path for supplied symbol.
18

    
19
#    o    If located, attempt to demangle or mangle as appropriate..
20

    
21
#    Program Notes:-
22
#    =============
23

    
24
#    None.
25

    
26
symbol=""
27
all_libs=0
28
demangled=0
29
frag_search=0
30
print_types=0
31
verbose=0
32
textonly=1
33
print_help=0
34
for arg; do
35
  case $arg in
36
  -a) all_libs=1;;
37
  -d) demangled=1;;
38
  -f) frag_search=1;;
39
  -t) print_types=1;;
40
  -v) let verbose=${verbose}+1;;
41
  -u) textonly=0;;   # show U undefined as well (other than T W V )
42
  -h) print_help=1;;
43
   *) symbol="$arg"
44
  esac
45
done
46

    
47
sysname=`uname -s`
48

    
49
  if [ $print_types = 1 ] ; then
50
  echo ' '
51
  echo 'For Linux:'
52
  echo '   Symbol types are a single character from the following list:-'
53
  echo ' '
54
  echo '      A '
55
  echo '           The symbols value is absolute, and will not be changed by'
56
  echo '           further linking.'
57
  echo ' '
58
  echo '      B '
59
  echo '           The symbol is in the uninitialized data section (known as'
60
  echo '           BSS).'
61
  echo ' '
62
  echo '      C '
63
  echo '           The symbol is common.  Common symbols are uninitialized data.'
64
  echo '           When linking, multiple common symbols may appear with the'
65
  echo '           same name.  If the symbol is defined anywhere, the common'
66
  echo '           symbols are treated as undefined references.  For more'
67
  echo '           details on common symbols, see the discussion of -warn-common'
68
  echo '           in *Note Linker options: (ld.info)Options.'
69
  echo '           details on common symbols, see the discussion of -warn-common'
70
  echo '           in *Note Linker options: (ld.info)Options.'
71
  echo ' '
72
  echo '      D '
73
  echo '           The symbol is in the initialized data section.'
74
  echo ' '
75
  echo '      G '
76
  echo '           The symbol is in an initialized data section for small'
77
  echo '           objects.  Some object file formats permit more efficient'
78
  echo '           access to small data objects, such as a global int variable'
79
  echo '           as opposed to a large global array.'
80
  echo ' '
81
  echo '      I '
82
  echo '           The symbol is an indirect reference to another symbol.  This'
83
  echo '           is a GNU extension to the a.out object file format which is'
84
  echo '           rarely used.'
85
  echo ' '
86
  echo '      N '
87
  echo '           The symbol is a debugging symbol.'
88
  echo ' '
89
  echo '      R '
90
  echo '           The symbol is in a read only data section.'
91
  echo ' '
92
  echo '      S '
93
  echo '           The symbol is in an uninitialized data section for small'
94
  echo '           objects.'
95
  echo ' '
96
  echo '      T '
97
  echo '           The symbol is in the text (code) section.'
98
  echo ' '
99
  echo '      U '
100
  echo '           The symbol is undefined.'
101
  echo ' '
102
  echo '      V '
103
  echo '           The symbol is a weak object.  When a weak defined symbol is'
104
  echo '           linked with a normal defined symbol, the normal defined'
105
  echo '           symbol is used with no error.  When a weak undefined symbol'
106
  echo '           is linked and the symbol is not defined, the value of the'
107
  echo '           weak symbol becomes zero with no error.'
108
  echo ' '
109
  echo '      W '
110
  echo '           The symbol is a weak symbol that has not been specifically'
111
  echo '           tagged as a weak object symbol.  When a weak defined symbol'
112
  echo '           is linked with a normal defined symbol, the normal defined'
113
  echo '           symbol is used with no error.  When a weak undefined symbol'
114
  echo '           is linked and the symbol is not defined, the value of the'
115
  echo '           weak symbol becomes zero with no error.'
116
  echo ' '
117
  echo '      - '
118
  echo '           The symbol is a stabs symbol in an a.out object file.  In'
119
  echo '           this case, the next values printed are the stabs other field,'
120
  echo '           the stabs desc field, and the stab type.  Stabs symbols are'
121
  echo '           used to hold debugging information.  For more information,'
122
  echo '           see *Note Stabs: (stabs.info)Top.'
123
  echo ' '
124
  echo '      ? '
125
  echo '           The symbol type is unknown, or object file format specific.'
126
  echo ' '
127
  echo 'For Mac OS X:'
128
  echo '   U (undefined)'
129
  echo '   A (absolute)'
130
  echo '   T (text section symbol)'
131
  echo '   D (data section symbol)'
132
  echo '   B (bss section symbol)'
133
  echo '   C (common symbol)'
134
  echo '   - (for debugger  symbol  table  entries; see -a below)'
135
  echo '   S (symbol in a section other than those above), or'
136
  echo '   I (indirect symbol).'
137
  echo "  If the symbol is local (non-external), the symbol's type is instead"
138
  echo '  represented by the corresponding lowercase letter.  A lower case u'
139
  echo '  in a dynamic shared library indicates a undefined reference to a'
140
  echo '   private external in  another module in the same library.'
141
  exit 0
142
fi
143

    
144
if [ "$symbol" = "" -o $print_help -ne 0 ] ; then
145
  echo "  find_global_symbol finds mangled or demangled symbols in libraries"
146
  echo "  within LD_LIBRARY_PATH.  Invocation:-"
147
  echo ""
148
  echo "     find_global_symbol.sh options name"
149
  echo ""
150
  echo "   where options are none or more of the following:-"
151
  echo ""
152
  echo "   -a    All libs: search all libs."
153
  echo "         Default:  exclude /usr/lib"
154
  echo ""
155
  echo "   -d    Demangled: Force name to be treated as demangled"
156
  echo "         Default:  treat name as mangled unless it contains a ("
157
  echo ""
158
  echo "   -f    Fragment search: name is a fragment, match any symbol that"
159
  echo "         contains name."
160
  echo "         Default:  symbol must exactly match name."
161
  echo ""
162
  echo "   -u    Print all references, including undefined symbols."
163
  echo "         Default:  only print symbol types T, W or V"
164
  echo ""
165
  echo "   -v    Increase verbosity."
166
  echo "         -v prints each directory path as searched."
167
  echo "         -v -v for debugging."
168
  echo ""
169
  echo "   -t    Print list of symbol types (may not exactly match nm)"
170
  echo ""
171
  echo "   -h    Print this help message."
172
  echo ""
173
  exit 0;
174
fi
175

    
176
#  Escape puntuation characters.
177
search_string=`echo $symbol | awk                           \
178
   '{ ORS="";                                               \
179
      loc=1;                                                \
180
      while (loc <= length($0)) {                           \
181
        c = substr($0,loc,1);                               \
182
        if ( c < "0" || c == "[" || c == "]") print "\\\\"; \
183
        print c;                                            \
184
        loc++;                                              \
185
      }                                                     \
186
    } ' `
187
if [ $frag_search -eq 0 ] ; then search_string=" $search_string\$"; fi
188

    
189
#  Set demangle flag.
190
if [ $demangled -eq 0 ]; then
191
  demangled=`echo $symbol | awk '{ print index($0,"(") }'`
192
fi
193
if [ $demangled -eq 0 ]; then demangled=""; fi
194

    
195
if [ $sysname == "Darwin" ]; then
196
   #DEMANGLEFLG="--defined-only -g"
197
   DEMANGLEFLG="-g"
198

    
199
else
200
   DEMANGLEFLG=
201
   NODEMANGLE=""
202
fi
203

    
204
if [ $demangled ]
205
then
206
  echo "Searching for demangled symbol '$symbol'"
207
  case $sysname in
208
     Darwin ) transform1="c++filt"
209
              transform2="tr x x"
210
              opt1="-g"
211
              opt2="-g"
212
              ;;
213
     * ) transform1="tr x x"   # no-op pass through
214
         transform2="tr x x"
215
         opt1="--demangle"
216
         opt2=""
217
         ;;
218
  esac
219
else
220
  #opt1=""
221
  #opt2="${DEMANGLEFLG}"
222
  echo "Searching for mangled symbol '$symbol'"
223
  case $sysname in
224
     Darwin ) transform1="tr x x"
225
              transform2="c++filt"
226
              opt1="-g"
227
              opt2="-g"
228
              ;;
229
     * ) transform1="tr x x"   # no-op pass through
230
         transform2="tr x x"
231
         opt1=""
232
         opt2="--demangle"
233
         ;;
234
  esac
235
fi
236

    
237
list=`echo ${LD_LIBRARY_PATH}:${DYLD_LIBRARY_PATH} | \
238
                              awk ' { num_elem = split($1,list,":"); \
239
                                      i_elem = 1;                    \
240
                                      while (i_elem <= num_elem) {   \
241
                                        print list[i_elem];          \
242
                                        i_elem++;                    \
243
                                      }                              \
244
                                    }  '`
245

    
246
tried=":"
247
for path in $list
248
do
249
# Skip unwanted directories.
250
  if [    "$path" = "."         \
251
       -o ! -d $path  ]; then  echo "Skipping $path"; continue; fi
252
  if [  $all_libs -eq 0 -a "$path" = "/usr/lib" ]; then echo "Skipping $path"; continue; fi
253

    
254
# Skip duplicates
255
  tried_before=`echo $tried :$path: | awk ' { print index($1,$2) }'`
256
  if [ $tried_before -ne 0 ]; then continue; fi
257
  tried=$tried$path:
258

    
259
  cd $path
260
  if [ $verbose -gt 0 ]; then
261
    echo "Checking libraries in $path..."
262
  fi
263

    
264
  for file in `ls -1 *.so *.dylib 2>/dev/null`
265
  do
266
     # echo "nm $opt1 $file | $tranform1 | egrep -n \"$search_string\""
267
     resultmulti=`nm $opt1 $file | $transform1 | egrep -n "$search_string"`
268

    
269
    printpath=0
270
    if [ "$resultmulti"  != "" ]
271
    then
272
       if [ $verbose -gt 1 ]; then
273
          echo "-->>> start resultmulti"
274
          echo "$resultmulti"
275
          echo "--<<<   end resultmulti"
276
      fi
277
      while read -r result; do
278
         if [ $textonly -ne 0 ]; then
279
            # S = Mac OS X "other section" (where typeinfo might be found)
280
            nmatch=`echo $result | egrep -c -v ' U ' `
281
            if [ $nmatch -eq 0 ]; then continue; fi
282
         fi
283
         if [ $verbose -eq 0 -a $printpath -eq 0 ]; then
284
            echo "Found in path $path/..."
285
            printpath=1
286
         fi
287

    
288
         echo "    Found in $file"
289
         echo "        Entry: $result"
290
         line=`echo $result | awk ' { loc = index($1,":");\
291
                                    print substr($1,1,loc-1) }'`
292
         if [ $verbose -gt 1 ]; then
293
            echo "awk returned $line"
294
         fi
295
         result=`nm $opt2 $file | $transform2 | head -$line | tail -1`
296
         echo "        Translates to $result"
297
      done <<< "$resultmulti"
298
    fi
299
  done
300
done
301

    
302
echo ""
303
echo "Note that  U       <symbol>    means the symbol is undefined (required) here"
304
echo "           T, W, V <symbol>    is defined here"
305
echo ""
306
echo "For a full list of codes type"
307
echo ""
308
echo "    find_global_symbol.sh -h"
309
echo ""
310

    
311
exit 0;
312