1#!/usr/bin/env bash 2 3# Copyright 2016 The Fuchsia Authors 4# 5# Use of this source code is governed by a MIT-style 6# license that can be found in the LICENSE file or at 7# https://opensource.org/licenses/MIT 8 9# This script reads the dynamic symbol table of a DSO (ELF file) via nm 10# and writes out a sequence of lines for each symbol in the DSO's ABI 11# that can be used as C macros. The macro invocations it writes look like: 12# TYPE(NAME, [ADDRESS,] SIZE) 13# The ADDRESS parameter is included only if the script is given the -a switch. 14# The SIZE is forced to 0 for functions if the script is given the -z switch. 15# The TYPE is one of: 16# COMMON_OBJECT STT_COMMON symbol 17# UNDEFINED SHN_UNDEF symbol 18# UNDEFINED_WEAK_OBJECT SHN_UNDEF, STB_WEAK, STT_OBJECT symbol 19# UNDEFINED_WEAK SHN_UNDEF, STB_WEAK, STT_FUNC symbol 20# WEAK_DATA_OBJECT STB_WEAK, STT_OBJECT symbol 21# WEAK_FUNCTION STB_WEAK, STT_FUNC symbol 22# FUNCTION STB_GLOBAL, STT_FUNC symbol 23# RODATA_OBJECT STB_GLOBAL, STT_OBJECT symbol in R/O section 24# DATA_OBJECT STB_GLOBAL, STT_OBJECT symbol in R/W section 25# BSS_OBJECT STB_GLOBAL symbol in SHT_NOBITS section 26# (nm actually uses a haphazard combination of ELF symbol details and 27# section details to choose its type letters rather than directly using the 28# ELF symbol bits consistently. But the type letters map to these symbol 29# details when symbols are defined in the usual ways by a compiler.) 30 31if [ "$(basename $0)" = "sh" ] 32then 33 set -e 34else 35 set -o pipefail -e 36fi 37 38show_address=false 39zero_function_size=false 40while [ $# -gt 0 ]; do 41 case "$1" in 42 -a) show_address=true ;; 43 -z) zero_function_size=true ;; 44 *) break ;; 45 esac 46 shift 47done 48 49if [ $# -ne 2 ]; then 50 echo >&2 "Usage: $0 [-a] [-z] NM DSO" 51 exit 2 52fi 53 54NM="$1" 55DSO="$2" 56 57dump_names() { 58 "$NM" -P -g -D -S "$DSO" 59} 60 61massage() { 62 local read name type addr size 63 while read name type addr size; do 64 65 # The numbers are printed in hex, but without a leading "0x" indicator. 66 addr="0x$addr" 67 if [ -z "$size" ]; then 68 size="0x0" 69 else 70 size="0x$size" 71 fi 72 73 case "$name" in 74 # Linkers sometimes emit these symbols into .dynsym, but they are useless 75 # and should not be consider part of the ABI. 76 __bss_start|__bss_start__|__bss_end__|_bss_end__) continue ;; 77 __data_start|__end__|_stack|_etext|_edata|_end) continue ;; 78 esac 79 80 case "$type" in 81 C) type=COMMON_OBJECT ;; 82 U) type=UNDEFINED ;; 83 v) type=UNDEFINED_WEAK_OBJECT ;; 84 w) type=UNDEFINED_WEAK ;; 85 V) type=WEAK_DATA_OBJECT ;; 86 W) type=WEAK_FUNCTION ;; 87 T) type=FUNCTION ;; 88 R) type=RODATA_OBJECT ;; 89 D) type=DATA_OBJECT ;; 90 B) type=BSS_OBJECT ;; 91 *) 92 echo >&2 "$0: Unhandled type '${type}' for symbol '${name}'" 93 exit 1 94 ;; 95 esac 96 97 if $show_address; then 98 address_item=", $addr" 99 else 100 address_item= 101 fi 102 103 if $zero_function_size; then 104 case $type in 105 FUNCTION|WEAK_FUNCTION) size="0x0" ;; 106 esac 107 fi 108 109 echo "${type}(${name}${address_item}, ${size})" 110 111 done 112} 113 114dump_names | massage 115