5911489b12ff39f621c2ec1c0cfb5a599af2df78
[globsym.git] / extract_global_symbols.pl
1 #!/usr/bin/perl
2
3 use strict;
4 use warnings;
5
6 use File::Find ();
7 use File::Basename;
8 use Cwd;
9
10 # Set the variable $File::Find::dont_use_nlink if you're using AFS,
11 # since AFS cheats.
12
13 # for the convenience of &wanted calls, including -eval statements:
14 use vars qw/*name *dir *prune/;
15 *name   = *File::Find::name;
16 *dir    = *File::Find::dir;
17 *prune  = *File::Find::prune;
18
19 sub wanted;
20
21
22 print <<'EOF';
23 CREATE TABLE global_symbols   ( symbol TEXT,
24 dir TEXT,
25 file TEXT,
26 line INTEGER);
27 EOF
28
29 # Traverse desired filesystems
30 File::Find::find({wanted => \&wanted}, '.');
31
32 sub wanted {
33     my ($dev,$ino,$mode,$nlink,$uid,$gid);
34
35     (
36         (($dev,$ino,$mode,$nlink,$uid,$gid) = lstat($_)) &&
37         $File::Find::name =~ /^\.\/lib\z/s
38         ||
39         $File::Find::name =~ /^\.\/arch\/x86\/lib\z/s
40         ||
41         $File::Find::name =~ /^\.\/drivers\z/s
42     ) &&
43     ($File::Find::prune = 1)
44     ||
45     (
46         /^.*\.dwo\z/s &&
47         ($nlink || (($dev,$ino,$mode,$nlink,$uid,$gid) = lstat($_))) &&
48         ! /^.*built-in.*\z/s
49     ) &&
50     look_for_symbols_in_file($name);
51 }
52
53
54 sub look_for_symbols_in_file
55 {
56         my $file = shift;
57         my ($base,$path,$suffix) = fileparse($file,('.dwo'));
58         if (! -e "$base.mod.c" && -e "$base.o")
59         {
60                 #print STDERR "$base\n";
61                 my $nm_output;
62                 open ($nm_output, "-|", "nm -l -g --defined-only --no-sort $base.o");
63                 while (<$nm_output>)
64                 {
65                         if (/.*\s+T\s+(\w+).*:(\d+)/)
66                         {
67                                 # print STDERR $_;
68                                 my ($symbol,$line) = ($1,$2);
69                                 # Special case for system calls
70                                 next if $symbol =~ /^SyS_/;
71                                 $symbol =~ s/^sys_/SYSC_/;
72
73                                 print "INSERT INTO global_symbols (symbol,dir,file,line) VALUES ('$symbol', '$path', '$base.c', '$line');\n"
74                         }
75                 }
76         }
77 }
78
79 1;
80
81 __END__