#!/bin/sh -e

# Install linux-restricted-modules and binutils, start the script, and put its
# output to modalias_override/nvidia.

# This is a nasty kluge, but it seems to work. Better check the output when
# upgrading to a new release of the nvidia driver, though.

# Whenever a PCI ID is supported by both nvidia and nvidia_legacy, it is only
# listed for nvidia.

echo "# Listing generated by nvidia_supported. Do not edit manually."

device_ids() {
	local filename="$1"

	# Find the first symbol of the .rodata section...
	objdump --section=.rodata --syms "$filename" |
	sed -n '/SYMBOL TABLE/,+2 {
	  s/^\([0-9a-f]\+\)\s\+l\s\+O\s\+\S\+\s\+\([0-9a-f]\+\)\s\+\(\S\+\).*/\1 \2 \3/p
	}' |
	while read start stop symname; do
		# ...and grab the IDs from its hex dump.
		objdump --section=.rodata --full-contents \
		  --start-address="0x$start" --stop-address="0x$stop" "$filename" |
		sed -n 's/^ [0-9a-f]\+ \([0-9a-f]\{2\}\)\([0-9a-f]\{2\}\).*/\2\1/p' |
		sort | uniq
	done
}

set -- "/lib/linux-restricted-modules/$(uname -r)/nvidia/nv-kernel.o" nvidia \
  "/lib/linux-restricted-modules/$(uname -r)/nvidia_legacy/nv-kernel.o" nvidia_legacy

seen_ids=' '

while [ -n "$1" ]; do
	filename="$1"; shift
	modname="$1";  shift

	orig_ids="$(device_ids "$filename")"
	ids=''

	for id in $orig_ids; do
		case "$seen_ids" in
		*" $id "*)
			# Already seen the ID.
			;;
		*)
			# Not seen it yet.
			seen_ids="${seen_ids}${id} "
			ids="$ids $id"
			;;
		esac
	done

	for id in $ids; do
		printf "alias pci:v%08Xd%08Xsv*sd*bc03sc*i* %s\n" \
		  0x10de "0x$id" "$modname"
	done
done | sort
