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