Wade Berrier writes:
[platform/upstream/busybox.git] / examples / depmod.pl
1 #!/usr/bin/perl -w
2 # vi: set ts=4:
3 # Copyright (c) 2001 David Schleef <ds@schleef.org>
4 # Copyright (c) 2001 Erik Andersen <andersen@codepoet.org>
5 # Copyright (c) 2001 Stuart Hughes <stuarth@lineo.com>
6 # Copyright (c) 2002 Steven J. Hill <shill@broadcom.com>
7 # This program is free software; you can redistribute it and/or modify it
8 # under the same terms as Perl itself.
9
10 # TODO -- use strict mode...
11 #use strict;
12
13 use Getopt::Long;
14 use File::Find;
15
16
17 # Set up some default values
18
19 my $basedir="";
20 my $kernel;
21 my $kernelsyms;
22 my $stdout=0;
23 my $verbose=0;
24
25
26 # get command-line options
27
28 my %opt;
29
30 GetOptions(
31         \%opt,
32         "help|h",
33         "basedir|b=s" => \$basedir,
34         "kernel|k=s" => \$kernel,
35         "kernelsyms|F=s" => \$kernelsyms,
36         "stdout|n" => \$stdout,
37         "verbose|v" => \$verbose,
38 );
39
40 if (defined $opt{help}) {
41         print
42         "  $0 [OPTION]... [basedir]\n",
43         "     -h --help\t\tShow this help screen\n",
44         "     -b --basedir\tModules base directory (defaults to /lib/modules)\n",
45         "     -k --kernel\tKernel binary for the target\n",
46         "     -F --kernelsyms\tKernel symbol file\n",
47         "     -n --stdout\tWrite to stdout instead of <basedir>/modules.dep\n",
48         "     -v --verbose\tPrint out lots of debugging stuff\n",
49         ;
50         exit 1;
51 }
52
53 if($basedir !~ m-/lib/modules-) {
54     warn "WARNING: base directory does not match ..../lib/modules\n";
55 }
56
57 # Find the list of .o files living under $basedir
58 #if ($verbose) { printf "Locating all modules\n"; }
59 my($ofile) = "";
60 my($file) = "";
61 my(@liblist) = ();
62 find sub {
63         if ( -f $_  && ! -d $_ ) {
64                 $file = $File::Find::name;
65                 if ( $file =~ /.o$/ ) {
66                         push(@liblist, $file);
67                         if ($verbose) { printf "$file\n"; }
68                 }
69         }
70 }, $basedir;
71 if ($verbose) { printf "Finished locating modules\n"; }
72
73 foreach $obj ( @liblist, $kernel ){
74     # turn the input file name into a target tag name
75     # vmlinux is a special that is only used to resolve symbols
76     if($obj =~ /vmlinux/) {
77         $tgtname = "vmlinux";
78     } else {
79         ($tgtname) = $obj =~ m-(/lib/modules/.*)$-;
80     }
81
82     warn "MODULE = $tgtname\n" if $verbose;
83
84     # get a list of symbols
85         @output=`nm $obj`;
86         $ksymtab=grep m/ __ksymtab/, @output;
87
88     # gather the exported symbols
89         if($ksymtab){
90         # explicitly exported
91         foreach ( @output ) {
92             / __ksymtab_(.*)$/ and do {
93                 warn "sym = $1\n" if $verbose;
94                 $exp->{$1} = $tgtname;
95             };
96         }
97         } else {
98         # exporting all symbols
99         foreach ( @output) {
100             / [ABCDGRST] (.*)$/ and do {
101                 warn "syma = $1\n" if $verbose;
102                 $exp->{$1} = $tgtname;
103             };
104         }
105         }
106     # gather the unresolved symbols
107     foreach ( @output ) {
108         !/ __this_module/ && / U (.*)$/ and do {
109             warn "und = $1\n" if $verbose;
110             push @{$dep->{$tgtname}}, $1;
111         };
112     }
113 }
114
115
116 # reduce dependancies: remove unresolvable and resolved from vmlinux
117 # remove duplicates
118 foreach $module (keys %$dep) {
119     $mod->{$module} = {};
120     foreach (@{$dep->{$module}}) {
121         if( $exp->{$_} ) {
122             warn "resolved symbol $_ in file $exp->{$_}\n" if $verbose;
123             next if $exp->{$_} =~ /vmlinux/;
124             $mod->{$module}{$exp->{$_}} = 1;
125         } else {
126             warn "unresolved symbol $_ in file $module\n";
127         }
128     }
129 }
130
131 # resolve the dependancies for each module
132 if ($stdout == 1) {
133         foreach $module ( keys %$mod ) {
134                 print "$module:\t";
135                 @sorted = sort bydep keys %{$mod->{$module}};
136                 print join(" \\\n\t",@sorted);
137                 print "\n\n";
138         }
139 } else {
140         open(OFILE, ">$basedir/modules.dep");
141         foreach $module ( keys %$mod ) {
142                 print OFILE "$module:\t";
143                 @sorted = sort bydep keys %{$mod->{$module}};
144                 print OFILE join(" \\\n\t",@sorted);
145                 print OFILE "\n\n";
146         }
147 }
148
149
150 sub bydep
151 {
152     foreach my $f ( keys %{$mod->{$b}} ) {
153         if($f eq $a) {
154             return 1;
155         }
156     }
157     return -1;
158 }
159
160
161
162 __END__
163
164 =head1 NAME
165
166 depmod.pl - a cross platform script to generate kernel module dependency
167                 lists which can then be used by modprobe.
168
169 =head1 SYNOPSIS
170
171 depmod.pl [OPTION]... [basedir]...
172
173 Example:
174
175         depmod.pl -F linux/System.map target/lib/modules
176
177 =head1 DESCRIPTION
178
179 The purpose of this script is to automagically generate a list of of kernel
180 module dependancies.  This script produces dependancy lists that should be
181 identical to the depmod program from the modutils package.  Unlike the depmod
182 binary, however, depmod.pl is designed to be run on your host system, not
183 on your target system.
184
185 This script was written by David Schleef <ds@schleef.org> to be used in
186 conjunction with the BusyBox modprobe applet.
187
188 =head1 OPTIONS
189
190 =over 4
191
192 =item B<-h --help>
193
194 This displays the help message.
195
196 =item B<-b --basedir>
197
198 The base directory uner which the target's modules will be found.  This
199 defaults to the /lib/modules directory.
200
201 =item B<-k --kernel>
202
203 Kernel binary for the target.  You must either supply a kernel binary
204 or a kernel symbol file (using the -F option).
205
206 =item B<-F --kernelsyms>
207
208 Kernel symbol file for the target.  You must supply either a kernel symbol file
209 kernel binary for the target (using the -k option).
210
211 =item B<-n --stdout>
212
213 Write to stdout instead of modules.dep.  This is currently hard coded...
214 kernel binary for the target (using the -k option).
215
216 =item B<--verbose>
217
218 Be verbose (not implemented)
219
220 =back
221
222 =head1 COPYRIGHT
223
224 Copyright (c) 2001 David Schleef <ds@schleef.org>
225 Copyright (c) 2001 Erik Andersen <andersen@codepoet.org>
226 Copyright (c) 2001 Stuart Hughes <stuarth@lineo.com>
227 This program is free software; you can redistribute it and/or modify it
228 under the same terms as Perl itself.
229
230 =head1 AUTHOR
231
232 David Schleef <ds@schleef.org>
233
234 =cut
235
236 # $Id: depmod.pl,v 1.4 2004/03/15 08:28:33 andersen Exp $
237