#!/bin/sh set -e # 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. if [ "$#" -ne 4 ]; then printf 'USAGE: %s modulename packagename README.txt nv-kernel.o\n' "$0" exit 1 fi device_ids() { local modname="$1"; shift local pkgname="$1"; shift local readme="$1"; shift local object="$1"; shift local ret=1 local symbols="$(mktemp)" local readme_list="$(mktemp)" local object_list="$(mktemp)" local diff="$(mktemp)" sed -nr '/^Appendix .\. Supported NVIDIA /,/legacy/ { s/.* 0x([0-9a-fA-F]{4})( .*|$)/\1/p }' "$readme" | tr A-F a-f | sort | uniq >"$readme_list" local readme_length="$(grep -Ec . "$readme_list")" objdump --section=.rodata --syms "$object" | sed -nr '/SYMBOL TABLE/,/^$/ { s/^([0-9a-f]+)\s+l\s+O\s+\S+\s+([0-9a-f]+)\s+\S+.*/\2 \1/p }' | sort -nr >"$symbols" # The list is probably among the larger symbols. while read length start; do [ "$((0x$length))" -gt 0 ] || continue objdump --section=.rodata --full-contents \ --start-address="0x$start" \ --stop-address="$((0x$start+0x$length))" "$object" | sed -nr 's/^ [0-9a-f]+ ([0-9a-f]{2})([0-9a-f]{2}).*/\2\1/p' | sort | uniq | (grep -vx 0000 || :) >"$object_list" local object_length="$(grep -Ec . "$object_list")" diff -u "$readme_list" "$object_list" | tail -n +3 >"$diff" local num_deletions="$(grep -Ec '^-' "$diff")" local num_additions="$(grep -Ec '^\+' "$diff")" # Some thresholds for now. if [ "$num_deletions" -eq 0 ] && [ "$num_additions" -le "$(($readme_length*3/2))" ]; then >&2 printf 'DEBUG: readme:%d object:%d deletions:%d additions:%d\n' \ "$readme_length" "$object_length" "$num_deletions" "$num_additions" ret=0 break fi done <"$symbols" if [ "$ret" -eq 0 ]; then printf '%s\n' '# List generated by nvidia_supported. Do not edit manually.' while read id; do printf 'alias pci:v%08Xd%08Xsv*sd*bc03sc*i* %s %s\n' \ 0x10de "0x$id" "$modname" "$pkgname" done <"$object_list" else >&2 printf '%s\n' 'Failed to find the list.' fi rm -f "$symbols" "$readme_list" "$object_list" "$diff" return "$ret" } device_ids "$@" # vim:set et sw=2 sts=2: