3 # reference_init.pl (C) Keith Owens 2002 <kaos@ocs.com.au>
5 # List references to vmlinux init sections from non-init sections.
7 # Unfortunately I had to exclude references from read only data to .init
8 # sections, almost all of these are false positives, they are created by
9 # gcc. The downside of excluding rodata is that there really are some
10 # user references from rodata to init code, e.g. drivers/video/vgacon.c
12 # const struct consw vga_con = {
13 # con_startup: vgacon_startup,
15 # where vgacon_startup is __init. If you want to wade through the false
16 # positives, take out the check for rodata.
19 die($0 . " takes no arguments\n") if($#ARGV >= 0);
28 printf("Finding objects, ");
29 open(OBJDUMP_LIST, "find . -name '*.o' | xargs objdump -h |") || die "getting objdump list failed";
30 while (defined($line = <OBJDUMP_LIST>)) {
32 if ($line =~ /:\s+file format/) {
33 ($object = $line) =~ s/:.*//;
34 $object{$object}->{'module'} = 0;
35 $object{$object}->{'size'} = 0;
36 $object{$object}->{'off'} = 0;
38 if ($line =~ /^\s*\d+\s+\.modinfo\s+/) {
39 $object{$object}->{'module'} = 1;
41 if ($line =~ /^\s*\d+\s+\.comment\s+/) {
42 ($object{$object}->{'size'}, $object{$object}->{'off'}) = (split(' ', $line))[2,5];
46 printf("%d objects, ", scalar keys(%object));
48 foreach $object (keys(%object)) {
49 if ($object{$object}->{'module'}) {
51 delete($object{$object});
54 printf("ignoring %d module(s)\n", $ignore);
56 # Ignore conglomerate objects, they have been built from multiple objects and we
57 # only care about the individual objects. If an object has more than one GCC:
58 # string in the comment section then it is conglomerate. This does not filter
59 # out conglomerates that consist of exactly one object, can't be helped.
61 printf("Finding conglomerates, ");
63 foreach $object (keys(%object)) {
64 if (exists($object{$object}->{'off'})) {
65 my ($off, $size, $comment, $l);
66 $off = hex($object{$object}->{'off'});
67 $size = hex($object{$object}->{'size'});
68 open(OBJECT, "<$object") || die "cannot read $object";
69 seek(OBJECT, $off, 0) || die "seek to $off in $object failed";
70 $l = read(OBJECT, $comment, $size);
71 die "read $size bytes from $object .comment failed" if ($l != $size);
73 if ($comment =~ /GCC\:.*GCC\:/m || $object =~ /built-in\.o/) {
75 delete($object{$object});
79 printf("ignoring %d conglomerate(s)\n", $ignore);
81 printf("Scanning objects\n");
82 foreach $object (sort(keys(%object))) {
84 open(OBJDUMP, "objdump -r $object|") || die "cannot objdump -r $object";
85 while (defined($line = <OBJDUMP>)) {
87 if ($line =~ /RELOCATION RECORDS FOR /) {
88 ($from = $line) =~ s/.*\[([^]]*).*/$1/;
90 if (($line =~ /\.init$/ || $line =~ /\.init\./) &&
91 ($from !~ /\.init$/ &&
92 $from !~ /\.init\./ &&
94 $from !~ /\.rodata$/ &&
95 $from !~ /\.text\.lock$/ &&
96 $from !~ /\.pci_fixup_header$/ &&
97 $from !~ /\.pci_fixup_final$/ &&
99 $from !~ /\__param$/ &&
100 $from !~ /\.altinstructions/ &&
101 $from !~ /\.eh_frame/ &&
102 $from !~ /\.debug_/)) {
103 printf("Error: %s %s refers to %s\n", $object, $from, $line);