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