1 1.1 christos 2 1.1 christos #! /usr/bin/env perl 3 1.1 christos # Copyright 2018-2021 The OpenSSL Project Authors. All Rights Reserved. 4 1.1 christos # 5 1.1 christos # Licensed under the Apache License 2.0 (the "License"). You may not use 6 1.1 christos # this file except in compliance with the License. You can obtain a copy 7 1.1 christos # in the file LICENSE in the source distribution or at 8 1.1 christos # https://www.openssl.org/source/license.html 9 1.1 christos 10 1.1 christos use strict; 11 1.1 christos use warnings; 12 1.1 christos 13 1.1 christos use Getopt::Long; 14 1.1 christos use FindBin; 15 1.1 christos use lib "$FindBin::Bin/perl"; 16 1.1 christos 17 1.1 christos use OpenSSL::Ordinals; 18 1.1 christos use OpenSSL::ParseC; 19 1.1 christos 20 1.1 christos my $ordinals_file = undef; # the ordinals file to use 21 1.1 christos my $symhacks_file = undef; # a symbol hacking file (optional) 22 1.1 christos my $version = undef; # the version to use for added symbols 23 1.1 christos my $checkexist = 0; # (unsure yet) 24 1.1 christos my $warnings = 1; 25 1.1 christos my $renumber = 0; 26 1.1 christos my $verbose = 0; 27 1.1 christos my $debug = 0; 28 1.1 christos 29 1.1 christos GetOptions('ordinals=s' => \$ordinals_file, 30 1.1 christos 'symhacks=s' => \$symhacks_file, 31 1.1 christos 'version=s' => \$version, 32 1.1 christos 'exist' => \$checkexist, 33 1.1 christos 'renumber' => \$renumber, 34 1.1 christos 'warnings!' => \$warnings, 35 1.1 christos 'verbose' => \$verbose, 36 1.1 christos 'debug' => \$debug) 37 1.1 christos or die "Error in command line arguments\n"; 38 1.1 christos 39 1.1 christos die "Please supply ordinals file\n" 40 1.1 christos unless $ordinals_file; 41 1.1 christos 42 1.1 christos my $ordinals = OpenSSL::Ordinals->new(from => $ordinals_file, 43 1.1 christos warnings => $warnings, 44 1.1 christos verbose => $verbose, 45 1.1 christos debug => $debug); 46 1.1 christos $ordinals->set_version($version); 47 1.1 christos 48 1.1 christos my %orig_names = (); 49 1.1 christos %orig_names = map { $_->name() => 1 } 50 1.1 christos $ordinals->items(comparator => sub { $_[0] cmp $_[1] }, 51 1.1 christos filter => sub { $_->exists() }) 52 1.1 christos if $checkexist; 53 1.1 christos 54 1.1 christos # Invalidate all entries, they get revalidated when we re-check below 55 1.1 christos $ordinals->invalidate(); 56 1.1 christos 57 1.1 christos foreach my $f (($symhacks_file // (), @ARGV)) { 58 1.1 christos print STDERR $f," ","-" x (69 - length($f)),"\n" if $verbose; 59 1.1 christos open IN, $f or die "Couldn't open $f: $!\n"; 60 1.1 christos foreach (parse(<IN>, { filename => $f, 61 1.1 christos warnings => $warnings, 62 1.1 christos verbose => $verbose, 63 1.1 christos debug => $debug })) { 64 1.1 christos $_->{value} = $_->{value}||""; 65 1.1 christos next if grep { $_ eq 'CONST_STRICT' } @{$_->{conds}}; 66 1.1 christos printf STDERR "%s> %s%s : %s\n", 67 1.1 christos $_->{type}, 68 1.1 christos $_->{name}, 69 1.1 christos ($_->{type} eq 'M' && defined $symhacks_file && $f eq $symhacks_file 70 1.1 christos ? ' = ' . $_->{value} 71 1.1 christos : ''), 72 1.1 christos join(', ', @{$_->{conds}}) 73 1.1 christos if $verbose; 74 1.1 christos if ($_->{type} eq 'M' 75 1.1 christos && defined $symhacks_file 76 1.1 christos && $f eq $symhacks_file 77 1.1 christos && $_->{value} =~ /^\w(?:\w|\d)*/) { 78 1.1 christos $ordinals->add_alias($f, $_->{value}, $_->{name}, @{$_->{conds}}); 79 1.1 christos } else { 80 1.1 christos next if $_->{returntype} =~ /\b(?:ossl_)inline/; 81 1.1 christos my $type = { 82 1.1 christos F => 'FUNCTION', 83 1.1 christos V => 'VARIABLE', 84 1.1 christos } -> {$_->{type}}; 85 1.1 christos if ($type) { 86 1.1 christos $ordinals->add($f, $_->{name}, $type, @{$_->{conds}}); 87 1.1 christos } 88 1.1 christos } 89 1.1 christos } 90 1.1 christos close IN; 91 1.1 christos } 92 1.1 christos 93 1.1 christos $ordinals->renumber() if $renumber; 94 1.1 christos 95 1.1 christos if ($checkexist) { 96 1.1 christos my %new_names = map { $_->name() => 1 } 97 1.1 christos $ordinals->items(comparator => sub { $_[0] cmp $_[1] }, 98 1.1 christos filter => sub { $_->exists() }); 99 1.1 christos # Eliminate common names 100 1.1 christos foreach (keys %orig_names) { 101 1.1 christos next unless exists $new_names{$_}; 102 1.1 christos delete $orig_names{$_}; 103 1.1 christos delete $new_names{$_}; 104 1.1 christos } 105 1.1 christos if (%orig_names) { 106 1.1 christos print "The following symbols do not seem to exist in code:\n"; 107 1.1 christos foreach (sort keys %orig_names) { 108 1.1 christos print "\t$_\n"; 109 1.1 christos } 110 1.1 christos } 111 1.1 christos if (%new_names) { 112 1.1 christos print "The following existing symbols are not in ordinals file:\n"; 113 1.1 christos foreach (sort keys %new_names) { 114 1.1 christos print "\t$_\n"; 115 1.1 christos } 116 1.1 christos } 117 1.1 christos } else { 118 1.1 christos my $dropped = 0; 119 1.1 christos my $unassigned; 120 1.1 christos my $filter = sub { 121 1.1 christos my $item = shift; 122 1.1 christos my $result = $item->number() ne '?' || $item->exists(); 123 1.1 christos $dropped++ unless $result; 124 1.1 christos return $result; 125 1.1 christos }; 126 1.1 christos $ordinals->rewrite(filter => $filter); 127 1.1 christos my %stats = $ordinals->stats(); 128 1.1 christos print STDERR 129 1.1 christos "${ordinals_file}: $stats{modified} old symbols have updated info\n" 130 1.1 christos if $stats{modified}; 131 1.1 christos if ($stats{new}) { 132 1.1 christos print STDERR "${ordinals_file}: Added $stats{new} new symbols\n"; 133 1.1 christos } else { 134 1.1 christos print STDERR "${ordinals_file}: No new symbols added\n"; 135 1.1 christos } 136 1.1 christos if ($dropped) { 137 1.1 christos print STDERR "${ordinals_file}: Dropped $dropped new symbols\n"; 138 1.1 christos } 139 1.1 christos $stats{unassigned} = 0 unless defined $stats{unassigned}; 140 1.1 christos $unassigned = $stats{unassigned} - $dropped; 141 1.1 christos if ($unassigned) { 142 1.1 christos my $symbol = $unassigned == 1 ? "symbol" : "symbols"; 143 1.1 christos my $is = $unassigned == 1 ? "is" : "are"; 144 1.1 christos print STDERR "${ordinals_file}: $unassigned $symbol $is without ordinal number\n"; 145 1.1 christos } 146 1.1 christos } 147