Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) #!/usr/bin/env perl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) # SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4) # Generates a linker script that specifies the correct initcall order.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6) # Copyright (C) 2019 Google LLC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8) use strict;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) use warnings;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) use IO::Handle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) use IO::Select;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) use POSIX ":sys_wait_h";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) my $nm = $ENV{'NM'} || die "$0: ERROR: NM not set?";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) my $objtree = $ENV{'objtree'} || '.';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) ## currently active child processes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) my $jobs = {};		# child process pid -> file handle
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) ## results from child processes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) my $results = {};	# object index -> [ { level, secname }, ... ]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) ## reads _NPROCESSORS_ONLN to determine the maximum number of processes to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) ## start
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) sub get_online_processors {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) 	open(my $fh, "getconf _NPROCESSORS_ONLN 2>/dev/null |")
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) 		or die "$0: ERROR: failed to execute getconf: $!";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) 	my $procs = <$fh>;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) 	close($fh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) 	if (!($procs =~ /^\d+$/)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) 		return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) 	return int($procs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) ## writes results to the parent process
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) ## format: <file index> <initcall level> <base initcall section name>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) sub write_results {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) 	my ($index, $initcalls) = @_;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) 	# sort by the counter value to ensure the order of initcalls within
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 	# each object file is correct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 	foreach my $counter (sort { $a <=> $b } keys(%{$initcalls})) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 		my $level = $initcalls->{$counter}->{'level'};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 		# section name for the initcall function
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 		my $secname = $initcalls->{$counter}->{'module'} . '__' .
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 			      $counter . '_' .
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 			      $initcalls->{$counter}->{'line'} . '_' .
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 			      $initcalls->{$counter}->{'function'};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 		print "$index $level $secname\n";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) ## reads a result line from a child process and adds it to the $results array
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) sub read_results{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 	my ($fh) = @_;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 	# each child prints out a full line w/ autoflush and exits after the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 	# last line, so even if buffered I/O blocks here, it shouldn't block
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 	# very long
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 	my $data = <$fh>;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 	if (!defined($data)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 	chomp($data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 	my ($index, $level, $secname) = $data =~
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 		/^(\d+)\ ([^\ ]+)\ (.*)$/;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 	if (!defined($index) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 		!defined($level) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 		!defined($secname)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 		die "$0: ERROR: child process returned invalid data: $data\n";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 	$index = int($index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 	if (!exists($results->{$index})) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 		$results->{$index} = [];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 	push (@{$results->{$index}}, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 		'level'   => $level,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 		'secname' => $secname
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 	});
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 	return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) ## finds initcalls from an object file or all object files in an archive, and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) ## writes results back to the parent process
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) sub find_initcalls {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 	my ($index, $file) = @_;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 	die "$0: ERROR: file $file doesn't exist?" if (! -f $file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 	open(my $fh, "\"$nm\" --defined-only \"$file\" 2>/dev/null |")
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 		or die "$0: ERROR: failed to execute \"$nm\": $!";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 	my $initcalls = {};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 	while (<$fh>) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 		chomp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 		# check for the start of a new object file (if processing an
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 		# archive)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 		my ($path)= $_ =~ /^(.+)\:$/;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 		if (defined($path)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 			write_results($index, $initcalls);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 			$initcalls = {};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 			next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 		# look for an initcall
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 		my ($module, $counter, $line, $symbol) = $_ =~
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 			/[a-z]\s+__initcall__(\S*)__(\d+)_(\d+)_(.*)$/;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 		if (!defined($module)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 			$module = ''
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 		if (!defined($counter) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 			!defined($line) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 			!defined($symbol)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 			next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 		# parse initcall level
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 		my ($function, $level) = $symbol =~
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 			/^(.*)((early|rootfs|con|[0-9])s?)$/;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 		die "$0: ERROR: invalid initcall name $symbol in $file($path)"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 			if (!defined($function) || !defined($level));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 		$initcalls->{$counter} = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 			'module'   => $module,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 			'line'     => $line,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 			'function' => $function,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 			'level'    => $level,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 		};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 	close($fh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 	write_results($index, $initcalls);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) ## waits for any child process to complete, reads the results, and adds them to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) ## the $results array for later processing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) sub wait_for_results {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 	my ($select) = @_;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 	my $pid = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 	do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 		# unblock children that may have a full write buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 		foreach my $fh ($select->can_read(0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 			read_results($fh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 		# check for children that have exited, read the remaining data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 		# from them, and clean up
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 		$pid = waitpid(-1, WNOHANG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 		if ($pid > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 			if (!exists($jobs->{$pid})) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 				next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 			my $fh = $jobs->{$pid};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 			$select->remove($fh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 			while (read_results($fh)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 				# until eof
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 			close($fh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 			delete($jobs->{$pid});
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 	} while ($pid > 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) ## forks a child to process each file passed in the command line and collects
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) ## the results
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) sub process_files {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 	my $index = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) 	my $njobs = $ENV{'PARALLELISM'} || get_online_processors();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) 	my $select = IO::Select->new();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 	while (my $file = shift(@ARGV)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 		# fork a child process and read it's stdout
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 		my $pid = open(my $fh, '-|');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 		if (!defined($pid)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 			die "$0: ERROR: failed to fork: $!";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 		} elsif ($pid) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 			# save the child process pid and the file handle
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 			$select->add($fh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 			$jobs->{$pid} = $fh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 			# in the child process
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) 			STDOUT->autoflush(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) 			find_initcalls($index, "$objtree/$file");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) 			exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) 		$index++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) 		# limit the number of children to $njobs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) 		if (scalar(keys(%{$jobs})) >= $njobs) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) 			wait_for_results($select);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 	# wait for the remaining children to complete
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) 	while (scalar(keys(%{$jobs})) > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) 		wait_for_results($select);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) sub generate_initcall_lds() {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) 	process_files();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) 	my $sections = {};	# level -> [ secname, ...]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) 	# sort results to retain link order and split to sections per
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 	# initcall level
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 	foreach my $index (sort { $a <=> $b } keys(%{$results})) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) 		foreach my $result (@{$results->{$index}}) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) 			my $level = $result->{'level'};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) 			if (!exists($sections->{$level})) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) 				$sections->{$level} = [];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) 			push(@{$sections->{$level}}, $result->{'secname'});
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 	die "$0: ERROR: no initcalls?" if (!keys(%{$sections}));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 	# print out a linker script that defines the order of initcalls for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) 	# each level
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) 	print "SECTIONS {\n";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) 	foreach my $level (sort(keys(%{$sections}))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) 		my $section;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) 		if ($level eq 'con') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) 			$section = '.con_initcall.init';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) 			$section = ".initcall${level}.init";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) 		print "\t${section} : {\n";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) 		foreach my $secname (@{$sections->{$level}}) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) 			print "\t\t*(${section}..${secname}) ;\n";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) 		print "\t}\n";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) 	print "}\n";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) generate_initcall_lds();