-
Notifications
You must be signed in to change notification settings - Fork 1
/
ox-gen.pl
120 lines (92 loc) · 3.18 KB
/
ox-gen.pl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
=pod
=head1 NAME
ox-gen.pm - Generate an object cross reference database
=head1 SYNOPSIS
on-gen.pl
=head1 DESCRIPTION
The I<ox-gen.pl> command searches the current directory and
all sub-directory for I<.o> files and generates a cross reference
of all the symbols in each of them. This database can then be used
by the I<ox.pl> program to find symbols and their use.
=head1 FILES
=over 4
=item object_xref.dat
The database containing the symbol information.
=back
=head1 SEE ALSO
L<ox.pl>, L<nm>
=cut
use strict;
use warnings;
use POSIX (qw(getcwd));
use Storable;
use File::Find ();
# Key -- Function name
# Value --
# defined => List of files that define this symbol
# used => List of files that use this symbol
#
my %object_xref;
# The directory we started for
my $top_dir = getcwd();
#########################################################
# gen_xref($file) -- Add cross reference information for
# the given file.
#########################################################
sub gen_xref($)
{
# The name of the file we're examining
my $file_name = shift;
# The symbol information
my @lines = `nm $top_dir/$file_name`;
# Loop over each line in the symbol data
foreach my $cur_line (@lines) {
# Decode the line
# ++++++++----------------- Any Hex digit
# ||||||||*---------------- Zero or more
# +|||||||||+--------------- Put in $1
# |||||||||||++------------- Whitespace (\s)
# |||||||||||||+------------ 1 or more (+)
# |||||||||||||| +---------- Any char (.)
# ||||||||||||||+|+--------- Put in $2 ($type)
# |||||||||||||||||++------- Whitespace (\s)
# |||||||||||||||||||+------ 1 or more (+)
# |||||||||||||||||||| ++--- Any character (.)
# |||||||||||||||||||| || repeat 0
# |||||||||||||||||||| || or more times(*)
# ||||||||||||||||||||+||+-- Put in $3
$cur_line =~ /^([0-9a-f]*)\s+(.)\s+(.*)$/;
my $value = $1; # Value of the symbol
my $type = $2; # Type code
my $name = $3; # Name of the symbol
# If we don't have an entry for this thing, create it
if (not defined($object_xref{$name})) {
$object_xref{$name} = {
'used' => [],
'defined' => []
};
}
# Check to see if it's used or defined
if ($value eq "") {
push(@{$object_xref{$name}->{'used'}}, $file_name);
} else {
push(@{$object_xref{$name}->{'defined'}}, $file_name);
}
}
}
# Set the variable $File::Find::dont_use_nlink if you're using AFS,
# since AFS cheats.
# for the convenience of &wanted calls, including -eval statements:
use vars qw/*name *dir *prune/;
*name = *File::Find::name;
*dir = *File::Find::dir;
*prune = *File::Find::prune;
# Generated by find2perl
sub wanted {
/^.*\.o\z/s &&
gen_xref($name);
}
# Traverse desired filesystems
File::Find::find({wanted => \&wanted}, '.');
# Store the results
nstore \%object_xref, "object_xref.dat";