Blame test/recipes/01-test_symbol_presence.t

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