| 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 | }
|
|---|