#!/bin/bash
# SPDX-License-Identifier: GPL-2.0
#
# Translate stack dump function offsets.
#
# addr2line doesn't work with KASLR addresses.  This works similarly to
# addr2line, but instead takes the 'func+0x123' format as input:
#
#   $ ./scripts/faddr2line ~/k/vmlinux meminfo_proc_show+0x5/0x568
#   meminfo_proc_show+0x5/0x568:
#   meminfo_proc_show at fs/proc/meminfo.c:27
#
# If the address is part of an inlined function, the full inline call chain is
# printed:
#
#   $ ./scripts/faddr2line ~/k/vmlinux native_write_msr+0x6/0x27
#   native_write_msr+0x6/0x27:
#   arch_static_branch at arch/x86/include/asm/msr.h:121
#    (inlined by) static_key_false at include/linux/jump_label.h:125
#    (inlined by) native_write_msr at arch/x86/include/asm/msr.h:125
#
# The function size after the '/' in the input is optional, but recommended.
# It's used to help disambiguate any duplicate symbol names, which can occur
# rarely.  If the size is omitted for a duplicate symbol then it's possible for
# multiple code sites to be printed:
#
#   $ ./scripts/faddr2line ~/k/vmlinux raw_ioctl+0x5
#   raw_ioctl+0x5/0x20:
#   raw_ioctl at drivers/char/raw.c:122
#
#   raw_ioctl+0x5/0xb1:
#   raw_ioctl at net/ipv4/raw.c:876
#
# Multiple addresses can be specified on a single command line:
#
#   $ ./scripts/faddr2line ~/k/vmlinux type_show+0x10/45 free_reserved_area+0x90
#   type_show+0x10/0x2d:
#   type_show at drivers/video/backlight/backlight.c:213
#
#   free_reserved_area+0x90/0x123:
#   free_reserved_area at mm/page_alloc.c:6429 (discriminator 2)


set -o errexit
set -o nounset

usage() {
	echo "usage: faddr2line [--list] <object file> <func+offset> <func+offset>..." >&2
	exit 1
}

warn() {
	echo "$1" >&2
}

die() {
	echo "ERROR: $1" >&2
	exit 1
}

READELF="${CROSS_COMPILE:-}readelf"
ADDR2LINE="${CROSS_COMPILE:-}addr2line"
AWK="awk"

command -v ${AWK} >/dev/null 2>&1 || die "${AWK} isn't installed"
command -v ${READELF} >/dev/null 2>&1 || die "${READELF} isn't installed"
command -v ${ADDR2LINE} >/dev/null 2>&1 || die "${ADDR2LINE} isn't installed"

# Try to figure out the source directory prefix so we can remove it from the
# addr2line output.  HACK ALERT: This assumes that start_kernel() is in
# init/main.c!  This only works for vmlinux.  Otherwise it falls back to
# printing the absolute path.
find_dir_prefix() {
	local objfile=$1

	local start_kernel_addr=$(${READELF} --symbols --wide $objfile | ${AWK} '$8 == "start_kernel" {printf "0x%s", $2}')
	[[ -z $start_kernel_addr ]] && return

	local file_line=$(${ADDR2LINE} -e $objfile $start_kernel_addr)
	[[ -z $file_line ]] && return

	local prefix=${file_line%init/main.c:*}
	if [[ -z $prefix ]] || [[ $prefix = $file_line ]]; then
		return
	fi

	DIR_PREFIX=$prefix
	return 0
}

__faddr2line() {
	local objfile=$1
	local func_addr=$2
	local dir_prefix=$3
	local print_warnings=$4

	local sym_name=${func_addr%+*}
	local offset=${func_addr#*+}
	offset=${offset%/*}
	local user_size=
	[[ $func_addr =~ "/" ]] && user_size=${func_addr#*/}

	if [[ -z $sym_name ]] || [[ -z $offset ]] || [[ $sym_name = $func_addr ]]; then
		warn "bad func+offset $func_addr"
		DONE=1
		return
	fi

	# Go through each of the object's symbols which match the func name.
	# In rare cases there might be duplicates, in which case we print all
	# matches.
	while read line; do
		local fields=($line)
		local sym_addr=0x${fields[1]}
		local sym_elf_size=${fields[2]}
		local sym_sec=${fields[6]}

		# Get the section size:
		local sec_size=$(${READELF} --section-headers --wide $objfile |
			sed 's/\[ /\[/' |
			${AWK} -v sec=$sym_sec '$1 == "[" sec "]" { print "0x" $6; exit }')

		if [[ -z $sec_size ]]; then
			warn "bad section size: section: $sym_sec"
			DONE=1
			return
		fi

		# Calculate the symbol size.
		#
		# Unfortunately we can't use the ELF size, because kallsyms
		# also includes the padding bytes in its size calculation.  For
		# kallsyms, the size calculation is the distance between the
		# symbol and the next symbol in a sorted list.
		local sym_size
		local cur_sym_addr
		local found=0
		while read line; do
			local fields=($line)
			cur_sym_addr=0x${fields[1]}
			local cur_sym_elf_size=${fields[2]}
			local cur_sym_name=${fields[7]:-}

			if [[ $cur_sym_addr = $sym_addr ]] &&
			   [[ $cur_sym_elf_size = $sym_elf_size ]] &&
			   [[ $cur_sym_name = $sym_name ]]; then
				found=1
				continue
			fi

			if [[ $found = 1 ]]; then
				sym_size=$(($cur_sym_addr - $sym_addr))
				[[ $sym_size -lt $sym_elf_size ]] && continue;
				found=2
				break
			fi
		done < <(${READELF} --symbols --wide $objfile | ${AWK} -v sec=$sym_sec '$7 == sec' | sort --key=2)

		if [[ $found = 0 ]]; then
			warn "can't find symbol: sym_name: $sym_name sym_sec: $sym_sec sym_addr: $sym_addr sym_elf_size: $sym_elf_size"
			DONE=1
			return
		fi

		# If nothing was found after the symbol, assume it's the last
		# symbol in the section.
		[[ $found = 1 ]] && sym_size=$(($sec_size - $sym_addr))

		if [[ -z $sym_size ]] || [[ $sym_size -le 0 ]]; then
			warn "bad symbol size: sym_addr: $sym_addr cur_sym_addr: $cur_sym_addr"
			DONE=1
			return
		fi

		sym_size=0x$(printf %x $sym_size)

		# Calculate the section address from user-supplied offset:
		local addr=$(($sym_addr + $offset))
		if [[ -z $addr ]] || [[ $addr = 0 ]]; then
			warn "bad address: $sym_addr + $offset"
			DONE=1
			return
		fi
		addr=0x$(printf %x $addr)

		# If the user provided a size, make sure it matches the symbol's size:
		if [[ -n $user_size ]] && [[ $user_size -ne $sym_size ]]; then
			[[ $print_warnings = 1 ]] &&
				echo "skipping $sym_name address at $addr due to size mismatch ($user_size != $sym_size)"
			continue;
		fi

		# Make sure the provided offset is within the symbol's range:
		if [[ $offset -gt $sym_size ]]; then
			[[ $print_warnings = 1 ]] &&
				echo "skipping $sym_name address at $addr due to size mismatch ($offset > $sym_size)"
			continue
		fi

		# In case of duplicates or multiple addresses specified on the
		# cmdline, separate multiple entries with a blank line:
		[[ $FIRST = 0 ]] && echo
		FIRST=0

		echo "$sym_name+$offset/$sym_size:"

		# Pass section address to addr2line and strip absolute paths
		# from the output:
		local output=$(${ADDR2LINE} -fpie $objfile $addr | sed "s; $dir_prefix\(\./\)*; ;")
		[[ -z $output ]] && continue

		# Default output (non --list):
		if [[ $LIST = 0 ]]; then
			echo "$output" | while read -r line
			do
				echo $line
			done
			DONE=1;
			continue
		fi

		# For --list, show each line with its corresponding source code:
		echo "$output" | while read -r line
		do
			echo
			echo $line
			n=$(echo $line | sed 's/.*:\([0-9]\+\).*/\1/g')
			n1=$[$n-5]
			n2=$[$n+5]
			f=$(echo $line | sed 's/.*at \(.\+\):.*/\1/g')
			${AWK} 'NR>=strtonum("'$n1'") && NR<=strtonum("'$n2'") { if (NR=='$n') printf(">%d<", NR); else printf(" %d ", NR); printf("\t%s\n", $0)}' $f
		done

		DONE=1

	done < <(${READELF} --symbols --wide $objfile | ${AWK} -v fn=$sym_name '$4 == "FUNC" && $8 == fn')
}

[[ $# -lt 2 ]] && usage

objfile=$1

LIST=0
[[ "$objfile" == "--list" ]] && LIST=1 && shift && objfile=$1

[[ ! -f $objfile ]] && die "can't find objfile $objfile"
shift

DIR_PREFIX=supercalifragilisticexpialidocious
find_dir_prefix $objfile

FIRST=1
while [[ $# -gt 0 ]]; do
	func_addr=$1
	shift

	# print any matches found
	DONE=0
	__faddr2line $objfile $func_addr $DIR_PREFIX 0

	# if no match was found, print warnings
	if [[ $DONE = 0 ]]; then
		__faddr2line $objfile $func_addr $DIR_PREFIX 1
		warn "no match for $func_addr"
	fi
done
