This file is indexed.

/usr/share/lintian/helpers/coll/objdump-info-helper is in lintian 2.5.22ubuntu1.

This file is owned by root:root, with mode 0o755.

The actual contents of the file can be viewed below.

  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
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
#!/usr/bin/perl
# objdump-info-helper -- lintian collection script

# Most of it is taken from objdump-info (Lintian 2.5.9), which had the
# following copyright/license statements:
#
# The original shell script version of this script is
# Copyright (C) 1998 Christian Schwarz
#
# This version, including support for etch's binutils, is
# Copyright (C) 2008 Adam D. Barratt
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, you can find it on the World Wide
# Web at http://www.gnu.org/copyleft/gpl.html, or write to the Free
# Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
# MA 02110-1301, USA.

use strict;
use warnings;
use autodie;

my (@sections, @symbol_versions);
my @dyn_symbols;
my %program_headers;
my $bin;
my $truncated = 0;
my $section = '';

# it would have been nice to do open '-|', "readelf ... 2>&1" but
# then we have to escape the args and that puts us over the
# argument limit in some cases...
my $pid = open(my $readelf, '-|');

if (not $pid) {
    # child - re-direct standerr and exec
    open(STDERR, '>&', \*STDOUT);
    exec 'readelf', '-WltdVs', @ARGV;
}

if (scalar @ARGV == 1) {
    # Special case - readelf will not prefix the output with "File:
    # $name" if it only gets one file argument, so act as if it did...
    # - In fact, if readelf always emitted that File: header, we could
    #   simply use xargs directly on readelf and just parse its output
    #   in the loop below.
    $bin = $ARGV[0];
    print "Filename: $bin\n";

    system("head \Q$bin\E | grep -q 'packed.*with.*UPX'");
    print "UPX: yes\n" if $? == 0;
}

while (my $line = <$readelf>) {

    chomp $line;

    if ($line =~ m/^File: (.+)$/) {
        my $file = $1;
        finish_file();

        $bin = $file;
        print "Filename: $bin\n";

        system("head \Q$bin\E | grep -q 'packed.*with.*UPX'");
        print "UPX: yes\n" if $? == 0;
    } elsif (
        $line =~ m/^readelf: Error: Unable to read in 0x[0-9a-fA-F]+ bytes of/
        or $line
        =~ m/^readelf: Error: .*: Failed to read .*(?:magic number|file header)/
      ) {
       # Various errors for corrupt / broken files.  Note, readelf may spit out
       # multiple errors per file, hench the "unless".
        print "Broken: yes\n" unless $truncated++;
        next;
    } elsif ($line =~ m/^Program Headers:/) {
        $section = 'PH';
        print "Program-Headers:\n";
    } elsif ($line =~ m/^Section Headers:/) {
        $section = 'SH';
        print "Section-Headers:\n";
    } elsif ($line =~ m/^Dynamic section at offset .*:/) {
        $section = 'DS';
        print "Dynamic-Section:\n";
    } elsif ($line =~ m/^Version symbols section /) {
        $section = 'VS';
    } elsif ($line =~ m/^Symbol table '.dynsym'/) {
        $section = 'DS';
    } elsif ($line =~ m/^Symbol table/) {
        $section = '';
    } elsif ($line =~ m/^\s*$/) {
        $section = '';
    } elsif ($line =~ m/^\s*(\S+)\s*(?:(?:\S+\s+){4})\S+\s(...)/
        and $section eq 'PH') {
        my ($header, $flags) = ($1, $2);
        $header =~ s/^GNU_//g;
        next if $header eq 'Type';

        my $newflags = '';
        my $redo = 0;
        my $extra = '';
        $newflags .= ($flags =~ m/R/) ? 'r' : '-';
        $newflags .= ($flags =~ m/W/) ? 'w' : '-';
        $newflags .= ($flags =~ m/E/) ? 'x' : '-';

        $program_headers{$header} = $newflags;

        if ($header eq 'INTERP') {
            # Check if the next line is the "requesting an interpreter"
            # (readelf appears to always emit on the next line if at all)
            my $next = <$readelf>;
            if ($next =~ m,\[Requesting program interpreter:\s([^\]]+)\],) {
                $extra .= " interp=$1";
            } else {
                # Nope, give it back
                $redo = 1;
                $line = $next;
            }
        }

        print "  $header flags=${newflags}$extra\n";

        redo if $redo;
        next;

    } elsif ($line =~ m/^\s*\[(\d+)\]\s*(\S+)(?:\s|\Z)/
        and $section eq 'SH') {
        # We also match " [<addr>]: flags*, but don't need them
        # - in this case $2 will be ':'.
        next if $2 eq ':';
        $sections[$1] = $2;
        # We need sections as well (e.g. for incomplete stripping)
        print " $1 $2\n";
    } elsif ($line =~ m/^\s*0x(?:[0-9A-F]+)\s+\((.*?)\)\s+(\S.*)\Z/i
        and $section eq 'DS') {
        my ($type, $value) = ($1, $2);

        if ($type eq 'RPATH') {
            $value =~ s/.*\[//;
            $value =~ s/\]\s*$//;
        }
        $value =~ s/^(?:Shared library|Library soname): \[(.*)\]/$1/;
        print "  $type   $value\n";
    } elsif ($line =~ m/^\s*[0-9A-F]+: \s+ \S+ \s* (?:\(\S+\))? (?:\s|\Z)/xi
        and $section eq 'VS') {
        while ($line =~ m/([0-9A-F]+h?)\s*(?:\((\S+)\))?(?:\s|\Z)/gci) {
            my ($vernum, $verstring) = ($1, $2);
            $verstring ||= '';
            if ($vernum =~ m/h$/) {
                $verstring = "($verstring)";
            }
            push @symbol_versions, $verstring;
        }
    } elsif ($line
        =~ m/^\s*(\d+):\s*[0-9a-f]+\s+\d+\s+(?:(?:\S+\s+){3})(\S+)\s+(.*)\Z/
        and $section eq 'DS') {
        # We (somtimes) need to read the "Version symbols section" first to
        # use this data and readelf tends to print after this section, so
        # save for later.
        push(@dyn_symbols, [$1, $2, $3]);

    } elsif ($line =~ m/^There is no dynamic section in this file/
        and exists $program_headers{DYNAMIC}) {
        # The headers declare a dynamic section but it's
        # empty.
        print "Bad-Dynamic-Table: Yes\n";
    }
}

# Finish the last file
finish_file();

close($readelf);

exit 0;

sub finish_file {

    if (@dyn_symbols) {
        print "Dynamic-Symbols:\n";
        foreach my $dynsym (@dyn_symbols) {
            my ($symnum, $seg, $sym) = @{$dynsym};
            my $ver;

            if ($sym =~ m/^(.*)@(.*) \(.*\)$/) {
                $sym = $1;
                $ver = $2;
            } elsif (@symbol_versions == 0) {
                # No versioned symbols...
                $ver = '';
            } else {
                $ver = $symbol_versions[$symnum];

                if ($ver eq '*local*' or $ver eq '*global*') {
                    if ($seg eq 'UND') {
                        $ver = '   ';
                    } else {
                        $ver = 'Base';
                    }
                } elsif ($ver eq '()') {
                    $ver = '(Base)';
                }
            }

            if ($seg =~ m/^\d+$/ and defined $sections[$seg]) {
                $seg = $sections[$seg];
            }

            print " $seg $ver $sym\n";
        }
    }
    # Add an newline to end the current paragraph
    print "\n";

    # reset variables
    @sections = ();
    @symbol_versions = ();
    @dyn_symbols = ();
    $truncated = 0;
    $section = '';
    %program_headers = ();
    $bin = '';
    return;
}