1 #!/bin/sh 2 # 3 # Copyright (C) 2011 The Android Open Source Project 4 # 5 # Licensed under the Apache License, Version 2.0 (the "License"); 6 # you may not use this file except in compliance with the License. 7 # You may obtain a copy of the License at 8 # 9 # http://www.apache.org/licenses/LICENSE-2.0 10 # 11 # Unless required by applicable law or agreed to in writing, software 12 # distributed under the License is distributed on an "AS IS" BASIS, 13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 # See the License for the specific language governing permissions and 15 # limitations under the License. 16 # 17 # gen-system-symbols.sh 18 # 19 # This tool is used to read the shared library from a source directory 20 # (SRC) and extract the list of functions and variables. 21 # 22 # Then, for each library, it will generate in (DST) two text files 23 # named <library>.functions.txt and <library>.variables.txt 24 # 25 26 # Only runs on Linux because it requires the "readelf" utility 27 # 28 29 . `dirname $0`/prebuilt-common.sh 30 31 VERBOSE=no 32 33 PROGRAM_PARAMETERS="<src-dir> <dst-dir>" 34 PROGRAM_DESCRIPTION=\ 35 "This program is used to parse all shared libraries in <src-dir> 36 and extract, for each one of them, the list of functions and variables 37 that it exports. 38 39 For some of these libraries, it will remove symbols that are not meant 40 to be imported (unless you use --no-symbol-filtering) 41 42 These lists will then be saved into two files: 43 44 <dst-dir>/<libname>.functions.txt 45 <dst-dir>/<libname>.variables.txt 46 " 47 48 NO_FILTERING= 49 register_var_option "--no-symbol-filtering" NO_FILTERING "Disable symbol filtering" 50 51 extract_parameters "$@" 52 53 parse_params () 54 { 55 SRCDIR=$1 56 DSTDIR=$2 57 58 if [ -z "$SRCDIR" ]; then 59 dump "ERROR: Missing first parameter (source directory path), see --help" 60 exit 1 61 fi 62 63 if [ -z "$DSTDIR" ]; then 64 dump "ERROR: Missing second parameter (destination directory path), see --help" 65 exit 1 66 fi 67 68 if [ ! -d "$SRCDIR" ]; then 69 dump "ERROR: Not a source directory: $SRCDIR" 70 exit 1 71 fi 72 73 mkdir -p $DSTDIR 74 fail_panic "Could not create destination directory: $DSTDIR" 75 } 76 77 parse_params $PARAMETERS 78 79 READELF=readelf 80 81 # $1: shared library path 82 get_library_functions () 83 { 84 $READELF -s -D -W $1 | awk '$5 ~ /FUNC/ && $6 ~ /GLOBAL|WEAK/ && $8 !~ /UND/ { print $9; }' | sort -u 85 } 86 87 # $1: shared library path 88 get_library_variables () 89 { 90 $READELF -s -D -W $1 | awk '$5 ~ /OBJECT/ && $6 ~ /GLOBAL|WEAK/ && $8 !~ /UND/ { print $9; }' | sort -u 91 } 92 93 # Temp file used to list shared library symbol exclusions 94 # See set_symbol_excludes and extract_shared_library_xxxx functions below 95 SYMBOL_EXCLUDES=$TMPDIR/ndk-symbol-excludes.txt 96 97 # Temp file used to list shared library symbol inclusions, these 98 # are essentially overrides to the content of SYMBOL_EXCLUDES 99 SYMBOL_INCLUDES=$TMPDIR/ndk-symbol-includes.txt 100 101 # Temp file used to filter symbols 102 SYMBOL_TMPFILE=$TMPDIR/ndk-symbols-list.txt 103 104 # Reset the symbol exclusion list to its default 105 reset_symbol_excludes () 106 { 107 # By default, do not export C++ mangled symbol, which all start with _Z 108 echo '^_Z' > $SYMBOL_EXCLUDES 109 110 # __INIT_ARRAY__, __FINI_ARRAY__ and _GLOBAL_OFFSET_TABLE_ are special symbols 111 # that should normally be hidden. 112 echo "^__INIT_ARRAY__" >> $SYMBOL_EXCLUDES 113 echo "^__FINI_ARRAY__" >> $SYMBOL_EXCLUDES 114 echo "^_GLOBAL_OFFSET_TABLE_" >> $SYMBOL_EXCLUDES 115 > $SYMBOL_INCLUDES 116 } 117 118 # Add new exclusion patterns to SYMBOL_EXCLUDES 119 set_symbol_excludes () 120 { 121 (echo "$@" | tr ' ' '\n') >> $SYMBOL_EXCLUDES 122 } 123 124 # Add new inclusion patterns to SYMBOL_INCLUDES 125 set_symbol_includes () 126 { 127 (echo "$@" | tr ' ' '\n') >> $SYMBOL_INCLUDES 128 } 129 130 # Clear symbol exclusion/inclusion files 131 clear_symbol_excludes () 132 { 133 rm -f $SYMBOL_EXCLUDES $SYMBOL_INCLUDES 134 } 135 136 # Filter the list of symbols from a file 137 # $1: path to symbol list file 138 filter_symbols () 139 { 140 (grep -v -f $SYMBOL_EXCLUDES $1 ; grep -f $SYMBOL_INCLUDES $1) | sort -u 141 } 142 143 # $1: Library name 144 # $2+: List of symbols (functions or variables) 145 # Out: sorted list of filtered symbols, based on library name 146 filter_library_symbols () 147 { 148 local LIB=$1 149 shift 150 local SYMBOLS="$@" 151 (echo "$SYMBOLS" | tr ' ' '\n' | sort -u) > $SYMBOL_TMPFILE 152 153 reset_symbol_excludes 154 155 case $LIB in 156 libc.so) 157 # Remove a few internal symbols that should not be exposed 158 # from the C library (we plan to clean that up soon by using the 159 # "hidden" visibility attribute in the near future). 160 # 161 set_symbol_excludes \ 162 '^the_' '^dns_' 'load_domain_search_list' 'res_get_dns_changed' \ 163 '^_resolv_cache' '^_dns_getht' '^_thread_atexit' \ 164 '^free_malloc_leak_info' 'fake_gmtime_r' 'fake_localtime_r' \ 165 '^gAllocationsMutex' '^gHashTable' '^gMallocLeakZygoteChild' 166 # libc.so now absort libstdc++ use to have, thus contains C++ symbols from now on 167 set_symbol_includes '^_Z.*' 168 ;; 169 libstdc++.so) 170 # This used to be the only library that is allowed to export C++ symbols for now. 171 set_symbol_includes '^_Z.*' 172 ;; 173 liblog.so) 174 set_symbol_excludes '^.*' # exclude everything 175 set_symbol_includes '^__android_' # except __android_xxxx functions 176 ;; 177 libOpenSLES.so) 178 set_symbol_excludes '^_' '^MPH_' # remove MPH_to_xxx definitions 179 ;; 180 libGLESv*.so) 181 # Exclude non-OES extension entry points 182 set_symbol_excludes 'EXT$' 183 set_symbol_excludes 'AMD$' 184 set_symbol_excludes 'ANGLE$' 185 set_symbol_excludes 'APPLE$' 186 set_symbol_excludes 'IMG$' 187 set_symbol_excludes 'NV$' 188 set_symbol_excludes 'QCOM$' 189 ;; 190 esac 191 filter_symbols "$SYMBOL_TMPFILE" 192 } 193 194 for LIB in $(cd $SRCDIR && ls lib*.so); do 195 SRCLIB=$SRCDIR/$LIB 196 log "Extracting symbols from $LIB" 197 FUNCS=$(get_library_functions $SRCLIB) 198 VARS=$(get_library_variables $SRCLIB) 199 if [ -z "$NO_FILTERING" ]; then 200 FUNCS=$(filter_library_symbols $LIB $FUNCS) 201 VARS=$(filter_library_symbols $LIB $VARS) 202 fi 203 NUMFUNCS=$(echo $FUNCS | wc -w) 204 NUMVARS=$(echo $VARS | wc -w) 205 log " Found $NUMFUNCS functions and $NUMVARS variables" 206 (echo "$FUNCS" | tr ' ' '\n') > $DSTDIR/$LIB.functions.txt 207 (echo "$VARS" | tr ' ' '\n') > $DSTDIR/$LIB.variables.txt 208 done 209