|
1 #!/usr/bin/perl -w |
|
2 |
|
3 # A script to get around some shortcomings in elf2e32, namely: |
|
4 # - Returning 0 even when there are errors. |
|
5 # - Excluding symbols from the dso file even when they are present in the ELF file. |
|
6 # - Including symbols in the the dso file even when they are not present in the ELF file. |
|
7 # - Overwriting the old dso file even when there are no changes (increases build time). |
|
8 |
|
9 use File::Copy; |
|
10 |
|
11 my @args = (); |
|
12 my @definput; |
|
13 my @defoutput; |
|
14 my @dso; |
|
15 my @tmpdso; |
|
16 foreach (@ARGV) { |
|
17 if (/^--definput/o) { |
|
18 @definput = split('=', $_); |
|
19 } elsif (/^--defoutput/o) { |
|
20 @defoutput = split('=', $_); |
|
21 } elsif (/^--dso/o) { |
|
22 @dso = split('=', $_); |
|
23 } elsif (/^--tmpdso/o) { |
|
24 @tmpdso = split('=', $_); |
|
25 $tmpdso[0] = "--dso"; |
|
26 } else { |
|
27 push(@args, $_); |
|
28 } |
|
29 } |
|
30 |
|
31 @definput = () if (!@definput || ! -e $definput[1]); |
|
32 |
|
33 if (@dso && !@tmpdso || !@dso && @tmpdso) { |
|
34 print("--dso and --tmpdso must be used together.\n"); |
|
35 exit 1; |
|
36 } |
|
37 |
|
38 my $buildingLibrary = (@defoutput && @dso) ? 1 : 0; |
|
39 |
|
40 my $fixupFile = ""; |
|
41 my $runCount = 0; |
|
42 my $returnCode = 0; |
|
43 |
|
44 while (1) { |
|
45 if (++$runCount > 2) { |
|
46 print("Internal error in $0, link succeeded, but exports may be wrong.\n"); |
|
47 last; |
|
48 } |
|
49 |
|
50 my $elf2e32Pipe; |
|
51 my $elf2e32Cmd = "elf2e32 @args" |
|
52 . " " . join("=", @definput) |
|
53 . " " . join("=", @defoutput) |
|
54 . " " . join("=", @tmpdso); |
|
55 open($elf2e32Pipe, "$elf2e32Cmd 2>&1 |") or die ("Could not run elf2e32"); |
|
56 |
|
57 my %fixupSymbols; |
|
58 my $foundBrokenSymbols = 0; |
|
59 my $errors = 0; |
|
60 while (<$elf2e32Pipe>) { |
|
61 print; |
|
62 if (/Error:/io) { |
|
63 $errors = 1; |
|
64 } elsif (/symbol ([a-z0-9_]+) absent in the DEF file, but present in the ELF file/io) { |
|
65 $fixupSymbols{$1} = 1; |
|
66 $foundBrokenSymbols = 1; |
|
67 } elsif (/[0-9]+ Frozen Export\(s\) missing from the ELF file/io) { |
|
68 $foundBrokenSymbols = 1; |
|
69 } |
|
70 } |
|
71 close($elf2e32Pipe); |
|
72 |
|
73 if ($errors) { |
|
74 $returnCode = 1; |
|
75 last; |
|
76 } |
|
77 |
|
78 if ($buildingLibrary) { |
|
79 my $tmpDefFile; |
|
80 my $defFile; |
|
81 open($defFile, "< $defoutput[1]") or die("Could not open $defoutput[1]"); |
|
82 open($tmpDefFile, "> $defoutput[1].tmp") or die("Could not open $defoutput[1].tmp"); |
|
83 $fixupFile = "$defoutput[1].tmp"; |
|
84 while (<$defFile>) { |
|
85 s/\r//; |
|
86 s/\n//; |
|
87 next if (/; NEW:/); |
|
88 if (/([a-z0-9_]+) @/i) { |
|
89 if (exists($fixupSymbols{$1})) { |
|
90 s/ ABSENT//; |
|
91 } elsif (s/; MISSING://) { |
|
92 s/$/ ABSENT/; |
|
93 } |
|
94 } |
|
95 print($tmpDefFile "$_\n"); |
|
96 } |
|
97 close($defFile); |
|
98 close($tmpDefFile); |
|
99 |
|
100 $definput[1] = "$defoutput[1].tmp"; |
|
101 |
|
102 if (!$foundBrokenSymbols || $errors) { |
|
103 last; |
|
104 } |
|
105 |
|
106 print("Rerunning elf2e32 due to DEF file / ELF file mismatch\n"); |
|
107 } else { |
|
108 last; |
|
109 } |
|
110 }; |
|
111 |
|
112 if ($fixupFile) { |
|
113 unlink($defoutput[1]); |
|
114 move($fixupFile, $defoutput[1]); |
|
115 } |
|
116 |
|
117 exit $returnCode if ($returnCode != 0); |
|
118 |
|
119 if ($buildingLibrary) { |
|
120 my $differenceFound = 0; |
|
121 |
|
122 if (-e $dso[1]) { |
|
123 my $dsoFile; |
|
124 my $tmpdsoFile; |
|
125 my $dsoBuf; |
|
126 my $tmpdsoBuf; |
|
127 open($dsoFile, "< $dso[1]") or die("Could not open $dso[1]"); |
|
128 open($tmpdsoFile, "< $tmpdso[1]") or die("Could not open $tmpdso[1]"); |
|
129 binmode($dsoFile); |
|
130 binmode($tmpdsoFile); |
|
131 while(read($dsoFile, $dsoBuf, 4096) && read($tmpdsoFile, $tmpdsoBuf, 4096)) { |
|
132 if ($dsoBuf ne $tmpdsoBuf) { |
|
133 $differenceFound = 1; |
|
134 } |
|
135 } |
|
136 close($tmpdsoFile); |
|
137 close($dsoFile); |
|
138 } else { |
|
139 $differenceFound = 1; |
|
140 } |
|
141 |
|
142 if ($differenceFound) { |
|
143 copy($tmpdso[1], $dso[1]); |
|
144 } |
|
145 } |