| #!/bin/bash |
| # Copyright 2021 The Fuchsia Authors. All rights reserved. |
| # Use of this source code is governed by a BSD-style license that can be |
| # found in the LICENSE file. |
| |
| #### CATEGORY=Diagnostic |
| ### Dumps disassembly for binaries from the build. |
| |
| ## usage: fx dis [-l | -S | -n] BINARY... |
| ## |
| ## Dump disassembly for a binary to a file in the build directory. |
| ## |
| ## -l list source locations interleaved with assembly |
| ## -S list source code lines interleaved with assembly |
| ## -r list relocations interleaved with assembly |
| ## -n do not demangle symbol names |
| ## -L use llvm-objdump rather than GNU objdump |
| ## |
| ## Each BINARY can be the name of the binary file without directory, e.g. |
| ## "libzircon.so" or "zircon.elf"; or the name of a GN target, e.g. "zircon". |
| ## |
| ## The disassembly will be written to a file next to the binary file in |
| ## the build directory, using its name with ".lst" suffix. |
| |
| set -o errexit |
| |
| source "$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null 2>&1 && pwd)"/../lib/vars.sh || exit $? |
| fx-config-read |
| |
| readonly BINARIES_JSON="$FUCHSIA_BUILD_DIR/binaries.json" |
| |
| DEMANGLE=true |
| USE_LLVM=false |
| OBJDUMP_ARGS=() |
| |
| while getopts lSrLn OPT; do |
| case $OPT in |
| [lSr]) OBJDUMP_ARGS+=(-$OPT) ;; |
| L) USE_LLVM=true ;; |
| n) DEMANGLE=false ;; |
| esac |
| done |
| shift $((OPTIND-1)) |
| |
| if $DEMANGLE; then |
| OBJDUMP_ARGS+=(--demangle) |
| fi |
| |
| if [[ $# -eq 0 ]]; then |
| fx-command-help |
| exit 1 |
| fi |
| |
| FILTER=".[] | select(false" |
| |
| for BINARY in "$@"; do |
| DEBUG_RE="(^|/)$BINARY([.]debug)?\$" |
| LABEL_RE=":$BINARY[(]" |
| FILTER+=" or (.debug | test(\"$DEBUG_RE\")) or (.label | test(\"$LABEL_RE\"))" |
| done |
| |
| FILTER+=") | [.cpu, .debug, .label] | join(\" \")" |
| |
| PATHS=($(fx-command-run jq --raw-output "$FILTER" "$BINARIES_JSON")) |
| |
| if (( ${#PATHS[@]} == 0 )); then |
| fx-error "No binaries matched $BINARY" |
| exit 1 |
| fi |
| |
| disassemble() { |
| local BINARY_CPU="$1" BINARY_PATH="$2" BINARY_LABEL="$3" |
| local -a CMD |
| |
| if $USE_LLVM; then |
| CMD=("$PREBUILT_CLANG_DIR/bin/llvm-objdump") |
| else |
| case "$BINARY_CPU" in |
| arm64) CMD=("$PREBUILT_GCC_DIR/bin/aarch64-elf-objdump" -m aarch64) ;; |
| x64) CMD=("$PREBUILT_GCC_DIR/bin/x86_64-elf-objdump" -m i386:x86-64) ;; |
| *) |
| fx-error "Can't handle binary $BINARY_PATH with CPU type $BINARY_CPU" |
| exit 1 |
| ;; |
| esac |
| fi |
| |
| CMD+=(-d) |
| |
| "${CMD[@]}" "${OBJDUMP_ARGS[@]}" "$FUCHSIA_BUILD_DIR/$BINARY_PATH" > "$FUCHSIA_BUILD_DIR/${BINARY_PATH}.lst" |
| fx-info Wrote "${BINARY_PATH}.lst" for "$BINARY_LABEL" |
| } |
| |
| i=0 |
| while (( i < ${#PATHS[@]} )); do |
| disassemble "${PATHS[$i]}" "${PATHS[$((i+1))]}" "${PATHS[$((i+2))]}" |
| ((i+=3)) |
| done |