Home | History | Annotate | Download | only in scripts
      1 #!/bin/bash -eu
      2 
      3 # Copyright 2017 Google Inc. All rights reserved.
      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 # Script to handle generating a .toc file from a .so file
     18 # Inputs:
     19 #  Environment:
     20 #   CROSS_COMPILE: prefix added to readelf tool
     21 #  Arguments:
     22 #   -i ${file}: input file (required)
     23 #   -o ${file}: output file (required)
     24 #   -d ${file}: deps file (required)
     25 #   --elf | --macho | --pe: format (required)
     26 
     27 OPTSTRING=d:i:o:-:
     28 
     29 usage() {
     30     cat <<EOF
     31 Usage: toc.sh [options] -i in-file -o out-file -d deps-file
     32 Options:
     33 EOF
     34     exit 1
     35 }
     36 
     37 do_elf() {
     38     ("${CROSS_COMPILE}readelf" -d "${infile}" | grep SONAME || echo "No SONAME for ${infile}") > "${outfile}.tmp"
     39     "${CROSS_COMPILE}readelf" --dyn-syms "${infile}" | awk '{$2=""; $3=""; print}' >> "${outfile}.tmp"
     40 
     41     cat <<EOF > "${depsfile}"
     42 ${outfile}: \\
     43   ${CROSS_COMPILE}readelf \\
     44 EOF
     45 }
     46 
     47 do_macho() {
     48     "${CROSS_COMPILE}/otool" -l "${infile}" | grep LC_ID_DYLIB -A 5 > "${outfile}.tmp"
     49     "${CROSS_COMPILE}/nm" -gP "${infile}" | cut -f1-2 -d" " | (grep -v 'U$' >> "${outfile}.tmp" || true)
     50 
     51     cat <<EOF > "${depsfile}"
     52 ${outfile}: \\
     53   ${CROSS_COMPILE}/otool \\
     54   ${CROSS_COMPILE}/nm \\
     55 EOF
     56 }
     57 
     58 do_pe() {
     59     "${CROSS_COMPILE}objdump" -x "${infile}" | grep "^Name" | cut -f3 -d" " > "${outfile}.tmp"
     60     "${CROSS_COMPILE}nm" -g -f p "${infile}" | cut -f1-2 -d" " >> "${outfile}.tmp"
     61 
     62     cat <<EOF > "${depsfile}"
     63 ${outfile}: \\
     64   ${CROSS_COMPILE}objdump \\
     65   ${CROSS_COMPILE}nm \\
     66 EOF
     67 }
     68 
     69 while getopts $OPTSTRING opt; do
     70     case "$opt" in
     71         d) depsfile="${OPTARG}" ;;
     72         i) infile="${OPTARG}" ;;
     73         o) outfile="${OPTARG}" ;;
     74         -)
     75             case "${OPTARG}" in
     76                 elf) elf=1 ;;
     77                 macho) macho=1 ;;
     78                 pe) pe=1 ;;
     79                 *) echo "Unknown option --${OPTARG}"; usage ;;
     80             esac;;
     81         ?) usage ;;
     82         *) echo "'${opt}' '${OPTARG}'"
     83     esac
     84 done
     85 
     86 if [ -z "${infile:-}" ]; then
     87     echo "-i argument is required"
     88     usage
     89 fi
     90 
     91 if [ -z "${outfile:-}" ]; then
     92     echo "-o argument is required"
     93     usage
     94 fi
     95 
     96 if [ -z "${depsfile:-}" ]; then
     97     echo "-d argument is required"
     98     usage
     99 fi
    100 
    101 if [ -z "${CROSS_COMPILE:-}" ]; then
    102     echo "CROSS_COMPILE environment variable must be set"
    103     usage
    104 fi
    105 
    106 rm -f "${outfile}.tmp"
    107 
    108 cat <<EOF > "${depsfile}"
    109 ${outfile}: \\
    110   ${CROSS_COMPILE}readelf \\
    111 EOF
    112 
    113 if [ -n "${elf:-}" ]; then
    114     do_elf
    115 elif [ -n "${macho:-}" ]; then
    116     do_macho
    117 elif [ -n "${pe:-}" ]; then
    118     do_pe
    119 else
    120     echo "--elf, --macho or --pe is required"; usage
    121 fi
    122 
    123 if cmp "${outfile}" "${outfile}.tmp" > /dev/null 2> /dev/null; then
    124     rm -f "${outfile}.tmp"
    125 else
    126     mv -f "${outfile}.tmp" "${outfile}"
    127 fi
    128