grub/grub-core/genmoddep.awk
Alexander Kanavin 87648e9c12 grub-core/genmoddep.awk: Ensure output is deterministic
The output in moddep.lst generated from syminfo.lst using genmoddep.awk
is not deterministic since the order of the dependencies on each line
can vary depending on how awk sorts the values in the array.

Be deterministic in the output by sorting the dependencies on each line.

Signed-off-by: Alexander Kanavin <alex@linutronix.de>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2023-06-13 14:12:07 +02:00

105 lines
2.6 KiB
Awk

#! /usr/bin/awk -f
#
# Copyright (C) 2006 Free Software Foundation, Inc.
#
# This genmoddep.awk is free software; the author
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
# Read symbols' info from stdin.
BEGIN {
error = 0
}
{
if ($1 == "defined") {
if ($3 !~ /^\.refptr\./ && $3 in symtab) {
printf "%s in %s is duplicated in %s\n", $3, $2, symtab[$3] >"/dev/stderr";
error++;
}
symtab[$3] = $2;
modtab[$2] = "" modtab[$2]
} else if ($1 == "undefined") {
if ($3 in symtab)
modtab[$2] = modtab[$2] " " symtab[$3];
else if ($3 != "__gnu_local_gp" && $3 != "_gp_disp") {
printf "%s in %s is not defined\n", $3, $2 >"/dev/stderr";
error++;
}
}
else {
printf "error: %u: unrecognized input format\n", NR >"/dev/stderr";
error++;
}
}
# Output the result.
END {
if (error >= 1)
exit 1;
total_depcount = 0
for (mod in modtab) {
# Remove duplications.
split(modtab[mod], depmods, " ");
for (depmod in uniqmods) {
delete uniqmods[depmod];
}
for (i in depmods) {
depmod = depmods[i];
# Ignore kernel, as always loaded.
if (depmod != "kernel" && depmod != mod)
uniqmods[depmod] = 1;
}
modlist = ""
depcount[mod] = 0
n = asorti(uniqmods, w)
for (i = 1; i <= n; i++) {
depmod = w[i]
modlist = modlist " " depmod;
inverse_dependencies[depmod] = inverse_dependencies[depmod] " " mod
depcount[mod]++
total_depcount++
}
if (mod == "all_video") {
continue;
}
printf "%s:%s\n", mod, modlist;
}
# Check that we have no dependency circles
while (total_depcount != 0) {
something_done = 0
for (mod in depcount) {
if (depcount[mod] == 0) {
delete depcount[mod]
split(inverse_dependencies[mod], inv_depmods, " ");
for (ctr in inv_depmods) {
depcount[inv_depmods[ctr]]--
total_depcount--
}
delete inverse_dependencies[mod]
something_done = 1
}
}
if (something_done == 0) {
for (mod in depcount) {
circle = circle " " mod
}
printf "error: modules %s form a dependency circle\n", circle >"/dev/stderr";
exit 1
}
}
modlist = ""
while (getline <"video.lst") {
modlist = modlist " " $1;
}
printf "all_video:%s\n", modlist;
}