#!/usr/bin/env bash

# Copyright 2016 The Fuchsia Authors
#
# Use of this source code is governed by a MIT-style
# license that can be found in the LICENSE file or at
# https://opensource.org/licenses/MIT

# This script reads symbols with nm and writes a C header file that
# defines macros <NAME>_CODE_*, <NAME>_DATA_* and <NAME>_ENTRY, with
# the address constants found in the symbol table for the symbols
# CODE_*, DATA_* and _start, respectively.
#
# When there is a dynamic symbol table, then it also emits macros
# <NAME>_DYNSYM_* giving the dynamic symbol table index of each
# exported symbol, and <NAME>_DYNSYM_COUNT giving the total number
# of entries in the table.

usage() {
  echo >&2 "\
Usage: $0 NM READELF [--depfile DEPFILE] [--writable] OUTFILE {NAME DSO}..."
  exit 2
}

if [ $# -lt 3 ]; then
  usage
fi

NM="$1"
shift
READELF="$1"
shift

DEPFILE=
if [ $# -gt 2 -a "$1" = "--depfile" ]; then
  DEPFILE="$2"
  shift 2
fi
USED_FILES=()

OUTFILE="$1"
shift

set -e
if [ -n "$BASH_VERSION" ]; then
  set -o pipefail
fi

grok_code_symbols() {
  local symbol type addr size rest
  while read symbol type addr size rest; do
    case "$symbol" in
    CODE_*|DATA_*|SYSCALL_*|_start)
      if [ "$symbol" = _start ]; then
        symbol=ENTRY
      fi
      echo "#define ${1}_${symbol} 0x${addr}" >> $OUTFILE
      case "$size" in
      ''|0|0x0) ;;
      *) echo "#define ${1}_${symbol}_SIZE 0x${size}" >> $OUTFILE
      esac
      status=0
      ;;
    esac
  done
  return $status
}

find_code_symbols() {
  "$NM" -P -S -n "$2" | grok_code_symbols "$1"
}

grok_dynsym_slots() {
  local symno=0
  local symbol rest
  while read symbol rest; do
    symno=$((symno+1))
    echo "#define ${1}_DYNSYM_${symbol} ${symno}" >> $OUTFILE
  done
  if [ $symno -gt 0 ]; then
    symno=$((symno+1))
    echo "#define ${1}_DYNSYM_COUNT ${symno}" >> $OUTFILE
  fi
}

find_dynsym_slots() {
  "$NM" -P -D -p "$2" | grok_dynsym_slots "$1"
}

SEGMENTS_HAVE_DYNSYM=22
SEGMENTS_NO_DYNSYM=33

grok_segments() {
  local line
  local status=$SEGMENTS_NO_DYNSYM
  while read line; do
    case "$line" in
    # Program header for the code segment, e.g.:
    # LOAD           0x002000 0x0000000000002000 0x0000000000002000 0x00f50f 0x00f50f R E 0x1000
    #                         ^^^^^ vaddr ^^^^^^                    ^filesz^
    *LOAD*\ R\ E\ *)
      local words=($line)
      local vaddr=$(printf '%#x' ${words[2]})
      local filesz=$(printf '%#x' ${words[4]})
      echo "#define ${1}_CODE_START $vaddr" >> $OUTFILE
      echo "#define ${1}_CODE_END (((${1}_CODE_START + $filesz + (1 << PAGE_SIZE_SHIFT) - 1) >> PAGE_SIZE_SHIFT) << PAGE_SIZE_SHIFT)" >> $OUTFILE
      ;;
    # Make sure there's no writable segment unless --writable allows it.
    *LOAD*W*)
      $WRITABLE || {
        echo >&2 "$0: writable segment: $line"
        exit 1
      }
      echo "#define ${1}_DATA_START $vaddr" >> $OUTFILE
      echo "#define ${1}_DATA_END (((${1}_DATA_START + $filesz + (1 << PAGE_SIZE_SHIFT) - 1) >> PAGE_SIZE_SHIFT) << PAGE_SIZE_SHIFT)" >> $OUTFILE
      ;;
    # Section header for .dynsym, e.g.:
    #  [ 3] .dynsym           DYNSYM          0000000000001268 001268 000018 18   A  6   1  8
    #                                         ^^^^^ addr ^^^^^        ^size^ ^entsize^
    *DYNSYM*)
      line="${line#*DYNSYM}"
      local words=($line)
      local addr=$(printf '%#x' 0x${words[0]})
      local size=$(printf '%#x' 0x${words[2]})
      local entsize=$(printf '%#x' 0x${words[3]})
      # A dummy .dynsym has a single entry.  Don't count that case.
      if [ $size != $entsize ]; then
        status=$SEGMENTS_HAVE_DYNSYM
        echo "#define ${1}_DATA_START_dynsym $addr" >> $OUTFILE
        echo "#define ${1}_DATA_END_dynsym (${1}_DATA_START_dynsym + $size)" >> $OUTFILE
      fi
      ;;
    # Hex dump of section '.note.gnu.build-id':
    # 0x000001c8 04000000 08000000 03000000 474e5500 ............GNU.
    *Hex\ dump*)
      # This always comes last, so we can consume the rest of the lines.
      grok_build_id "$1"
      ;;
    esac
  done
  return $status
}

grok_build_id() {
  # The first line looks like:
  #   0x000001c8 04000000 08000000 03000000 474e5500 ............GNU.
  # where 0x000001c8 is the address of the section.  Subsequent lines look
  # similar, but possibly with an odd ending:
  #   0x000001d8 9470536b 2dd1e5e7                   .pSk-...
  local -a hex words=()
  read -a hex
  local addr="${hex[0]}"
  local hexp='[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]'

  while true; do
    local n=${#hex[@]} i=1
    # The "...text..." portion can contain spaces, so the word count
    # is not a reliable way to detect the last hex word.  So also stop
    # when the first non-hex word is seen.
    while ((i < n - 1)) && [[ "${hex[$i]}" == $hexp ]]; do
      words+=("${hex[$i]}")
      ((i++))
    done
    read -a hex || break
  done

  local -a bytes=()
  local w
  for w in "${words[@]}"; do
    bytes+=("0x${w:0:2}," "0x${w:2:2}," "0x${w:4:2}," "0x${w:6:2},")
  done

  echo "#define ${1}_BUILD_ID_NOTE_ADDRESS $addr" >> "$OUTFILE"
  echo "#define ${1}_BUILD_ID_NOTE_SIZE ${#bytes[@]}" >> "$OUTFILE"
  echo "#define ${1}_BUILD_ID_NOTE_BYTES {${bytes[@]}}" >> "$OUTFILE"
}

find_segments() {
  # This if silliness disarms -e so we can observe grok_segments's return code.
  if {
  "$READELF" -W -S -l -x.note.gnu.build-id "$2" | grok_segments "$1"
  case $? in
  $SEGMENTS_NO_DYNSYM) have_dynsym=no ;;
  $SEGMENTS_HAVE_DYNSYM) have_dynsym=yes ;;
  *) exit $? ;;
  esac
  return 0
  }; then : ; fi
}

trap 'rm -f "$OUTFILE" ${DEPFILE:+"$DEPFILE"}' ERR HUP INT TERM

while [ $# -gt 0 ]; do
  if [ "$1" = --writable ]; then
    WRITABLE=true
    shift
  else
    WRITABLE=false
  fi

  if [ $# -lt 2 ]; then
    usage
  fi
  name="$1"
  dso="$2"
  shift 2

  # This argument might be a response file.
  if [[ "$dso" == @* ]]; then
    rspfile="${dso#@}"
    dso="$(< "$rspfile")"
    USED_FILES+=("$rspfile" "$dso")
  else
    USED_FILES+=("$dso")
  fi

  echo "#define ${name}_FILENAME \"${dso}\"" > $OUTFILE
  find_segments "$name" "$dso"
  find_code_symbols "$name" "$dso"
  if [ $have_dynsym = yes ]; then
    find_dynsym_slots "$name" "$dso"
  fi
done

if [ -n "$DEPFILE" ]; then
  echo "$OUTFILE: ${USED_FILES[*]}" > "$DEPFILE"
fi
