^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();