2016-04-22 08:20:59 +00:00
|
|
|
#! /usr/bin/env perl
|
|
|
|
# -*- mode: Perl -*-
|
2018-11-20 13:13:00 +00:00
|
|
|
# Copyright 2016-2018 The OpenSSL Project Authors. All Rights Reserved.
|
2016-04-22 08:20:59 +00:00
|
|
|
#
|
|
|
|
# Licensed under the OpenSSL license (the "License"). You may not use
|
|
|
|
# this file except in compliance with the License. You can obtain a copy
|
|
|
|
# in the file LICENSE in the source distribution or at
|
|
|
|
# https://www.openssl.org/source/license.html
|
|
|
|
|
|
|
|
use strict;
|
|
|
|
use File::Spec::Functions qw(devnull);
|
|
|
|
use OpenSSL::Test qw(:DEFAULT srctop_file bldtop_dir bldtop_file);
|
|
|
|
use OpenSSL::Test::Utils;
|
|
|
|
|
|
|
|
setup("test_symbol_presence");
|
|
|
|
|
|
|
|
plan skip_all => "Only useful when building shared libraries"
|
|
|
|
if disabled("shared");
|
|
|
|
|
|
|
|
my @libnames = ("crypto", "ssl");
|
|
|
|
my $testcount = scalar @libnames;
|
|
|
|
|
|
|
|
plan tests => $testcount * 2;
|
|
|
|
|
|
|
|
note
|
2016-08-05 17:56:58 +00:00
|
|
|
"NOTE: developer test! It's possible that it won't run on your\n",
|
2016-04-22 08:20:59 +00:00
|
|
|
"platform, and that's perfectly fine. This is mainly for developers\n",
|
|
|
|
"on Unix to check that our shared libraries are consistent with the\n",
|
|
|
|
"ordinals (util/*.num in the source tree), something that should be\n",
|
|
|
|
"good enough a check for the other platforms as well.\n";
|
|
|
|
|
|
|
|
foreach my $libname (@libnames) {
|
|
|
|
SKIP:
|
|
|
|
{
|
|
|
|
my $shlibpath = bldtop_file("lib" . $libname . ".so");
|
|
|
|
*OSTDERR = *STDERR;
|
|
|
|
*OSTDOUT = *STDOUT;
|
|
|
|
open STDERR, ">", devnull();
|
|
|
|
open STDOUT, ">", devnull();
|
|
|
|
my @nm_lines = map { s|\R$||; $_ } `nm -Pg $shlibpath 2> /dev/null`;
|
|
|
|
close STDERR;
|
|
|
|
close STDOUT;
|
|
|
|
*STDERR = *OSTDERR;
|
|
|
|
*STDOUT = *OSTDOUT;
|
|
|
|
skip "Can't run 'nm -Pg $shlibpath' => $?... ignoring", 2
|
|
|
|
unless $? == 0;
|
|
|
|
|
|
|
|
my $bldtop = bldtop_dir();
|
|
|
|
my @def_lines;
|
|
|
|
indir $bldtop => sub {
|
|
|
|
my $mkdefpath = srctop_file("util", "mkdef.pl");
|
2018-09-14 12:59:40 +00:00
|
|
|
my $libnumpath = srctop_file("util", "lib$libname.num");
|
|
|
|
@def_lines = map { s|\R$||; $_ } `$^X $mkdefpath --ordinals $libnumpath --name $libname --OS linux 2> /dev/null`;
|
|
|
|
ok($? == 0, "running 'cd $bldtop; $^X $mkdefpath --ordinals $libnumpath --name $libname --OS linux' => $?");
|
2016-04-22 08:20:59 +00:00
|
|
|
}, create => 0, cleanup => 0;
|
|
|
|
|
|
|
|
note "Number of lines in \@nm_lines before massaging: ", scalar @nm_lines;
|
|
|
|
note "Number of lines in \@def_lines before massaging: ", scalar @def_lines;
|
|
|
|
|
|
|
|
# Massage the nm output to only contain defined symbols
|
2016-06-02 00:06:25 +00:00
|
|
|
@nm_lines = sort map { s| .*||; $_ } grep(m|.* [BCDST] .*|, @nm_lines);
|
2016-04-22 08:20:59 +00:00
|
|
|
|
|
|
|
# Massage the mkdef.pl output to only contain global symbols
|
|
|
|
# The output we got is in Unix .map format, which has a global
|
|
|
|
# and a local section. We're only interested in the global
|
|
|
|
# section.
|
|
|
|
my $in_global = 0;
|
|
|
|
@def_lines =
|
|
|
|
sort
|
|
|
|
map { s|;||; s|\s+||g; $_ }
|
|
|
|
grep { $in_global = 1 if m|global:|;
|
|
|
|
$in_global = 0 if m|local:|;
|
2016-09-05 22:48:13 +00:00
|
|
|
$in_global = 0 if m|\}|;
|
2016-04-22 08:20:59 +00:00
|
|
|
$in_global && m|;|; } @def_lines;
|
|
|
|
|
|
|
|
note "Number of lines in \@nm_lines after massaging: ", scalar @nm_lines;
|
|
|
|
note "Number of lines in \@def_lines after massaging: ", scalar @def_lines;
|
|
|
|
|
|
|
|
# Maintain lists of symbols that are missing in the shared library,
|
|
|
|
# or that are extra.
|
|
|
|
my @missing = ();
|
|
|
|
my @extra = ();
|
|
|
|
|
|
|
|
while (scalar @nm_lines || scalar @def_lines) {
|
|
|
|
my $nm_first = $nm_lines[0];
|
|
|
|
my $def_first = $def_lines[0];
|
|
|
|
|
|
|
|
if (!defined($nm_first)) {
|
|
|
|
push @missing, shift @def_lines;
|
|
|
|
} elsif (!defined($def_first)) {
|
|
|
|
push @extra, shift @nm_lines;
|
|
|
|
} elsif ($nm_first gt $def_first) {
|
|
|
|
push @missing, shift @def_lines;
|
|
|
|
} elsif ($nm_first lt $def_first) {
|
|
|
|
push @extra, shift @nm_lines;
|
|
|
|
} else {
|
|
|
|
shift @def_lines;
|
|
|
|
shift @nm_lines;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (scalar @missing) {
|
|
|
|
note "The following symbols are missing in lib$libname.so:";
|
|
|
|
foreach (@missing) {
|
|
|
|
note " $_";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (scalar @extra) {
|
|
|
|
note "The following symbols are extra in lib$libname.so:";
|
|
|
|
foreach (@extra) {
|
|
|
|
note " $_";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
ok(scalar @missing == 0,
|
|
|
|
"check that there are no missing symbols in lib$libname.so");
|
|
|
|
}
|
|
|
|
}
|