summaryrefslogtreecommitdiffstats
path: root/scripts/gen-cdefs.sh
blob: 0627fa40bbc73fc7170edf7be297c546702c747f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
#!/bin/bash
set -o pipefail -o errexit

if [ "$2" != types ] && [ "$2" != functions ]; then
	echo "Usage: $0 libkres (types|functions)" >&2
	echo "    and input identifiers, one per line." >&2
	echo "    You need debug symbols in the library." >&2
	exit 1
fi

if ! command -v gdb >/dev/null; then
	echo "Failed to find gdb" >&2
	exit 1
fi

if ! command -v sed >/dev/null; then
	echo "Failed to find GNU sed" >&2
	exit 1
fi

if ! sed --version | head -1 | grep -q "GNU sed"; then
	echo "GNU sed required to run this script" >&2
fi

# be very precise with the directories for libraries to not pick wrong library
case "$1" in
	libknot) library="$(PATH="$(pkg-config libknot --variable=libdir)" command -v "$1.so")" ;;
	libzscanner) library="$(PATH="$(pkg-config libzscanner --variable=libdir)" command -v "$1.so")" ;;
	*) library="$(PATH="$(pwd)/lib" command -v "$1.so")"
esac

if [ -z "$library" ]; then
	echo "$1 not found.  Note: only .so platforms work currently." >&2
	exit 1
fi

# Let's use an array to hold command-line arguments, to simplify quoting.
GDB=(gdb)
GDB+=(-n -quiet -batch "-symbols=$library")
GDB+=(-iex "set width unlimited" -iex "set max-value-size unlimited")

grep -v '^#\|^$' | while read -r ident; do
	if [ "$2" = functions ]; then
		output="$("${GDB[@]}" --ex "info functions ^$ident\$" \
				| sed '0,/^All functions/ d; /^File .*:$/ d')"
	else # types
		case "$ident" in
			struct\ *|union\ *|enum\ *)
				output="$("${GDB[@]}" --ex "ptype $ident" \
						| sed '0,/^type = /s/^type = /\n/; $ s/$/;/')"
				;;
			*)
				output="$("${GDB[@]}" --ex "info types ^$ident\$" \
						| sed -e '0,/^File .*:$/ d' -e '/^File .*:$/,$ d')"
						# we need to stop early to remove ^^ multiple matches
				;;
		esac
	fi
	# LuaJIT FFI blows up on "uint" type
	output="$(echo "$output" | sed 's/\buint\b/unsigned int/g')"
	# GDB 8.2+ added source line prefix to output
	output="$(echo "$output" | sed 's/^[0-9]\+:[[:space:]]*//g')"

	# abort on empty output
	if [ -z "$(echo "$output" | tr -d "\n;")" ]; then
		echo "Failed to find cdef of $ident" >&2
		exit 1
	fi
	echo "$output" | grep -v '^$'
done

exit 0