]>
Commit | Line | Data |
---|---|---|
3f8f7282 RL |
1 | #! /usr/bin/env perl |
2 | # -*- mode: Perl -*- | |
eec0ad10 | 3 | # Copyright 2016-2020 The OpenSSL Project Authors. All Rights Reserved. |
3f8f7282 | 4 | # |
909f1a2e | 5 | # Licensed under the Apache License 2.0 (the "License"). You may not use |
3f8f7282 RL |
6 | # this file except in compliance with the License. You can obtain a copy |
7 | # in the file LICENSE in the source distribution or at | |
8 | # https://www.openssl.org/source/license.html | |
9 | ||
10 | use strict; | |
11 | use File::Spec::Functions qw(devnull); | |
12 | use OpenSSL::Test qw(:DEFAULT srctop_file bldtop_dir bldtop_file); | |
13 | use OpenSSL::Test::Utils; | |
14 | ||
15 | setup("test_symbol_presence"); | |
16 | ||
a9672221 | 17 | plan skip_all => "Test is disabled on NonStop" if config('target') =~ m|^nonstop|; |
3f8f7282 RL |
18 | plan skip_all => "Only useful when building shared libraries" |
19 | if disabled("shared"); | |
20 | ||
21 | my @libnames = ("crypto", "ssl"); | |
22 | my $testcount = scalar @libnames; | |
23 | ||
24 | plan tests => $testcount * 2; | |
25 | ||
26 | note | |
60250017 | 27 | "NOTE: developer test! It's possible that it won't run on your\n", |
3f8f7282 RL |
28 | "platform, and that's perfectly fine. This is mainly for developers\n", |
29 | "on Unix to check that our shared libraries are consistent with the\n", | |
30 | "ordinals (util/*.num in the source tree), something that should be\n", | |
31 | "good enough a check for the other platforms as well.\n"; | |
32 | ||
33 | foreach my $libname (@libnames) { | |
34 | SKIP: | |
35 | { | |
36 | my $shlibpath = bldtop_file("lib" . $libname . ".so"); | |
37 | *OSTDERR = *STDERR; | |
38 | *OSTDOUT = *STDOUT; | |
39 | open STDERR, ">", devnull(); | |
40 | open STDOUT, ">", devnull(); | |
41 | my @nm_lines = map { s|\R$||; $_ } `nm -Pg $shlibpath 2> /dev/null`; | |
42 | close STDERR; | |
43 | close STDOUT; | |
44 | *STDERR = *OSTDERR; | |
45 | *STDOUT = *OSTDOUT; | |
46 | skip "Can't run 'nm -Pg $shlibpath' => $?... ignoring", 2 | |
47 | unless $? == 0; | |
48 | ||
49 | my $bldtop = bldtop_dir(); | |
50 | my @def_lines; | |
51 | indir $bldtop => sub { | |
52 | my $mkdefpath = srctop_file("util", "mkdef.pl"); | |
8effd8fa RL |
53 | my $libnumpath = srctop_file("util", "lib$libname.num"); |
54 | @def_lines = map { s|\R$||; $_ } `$^X $mkdefpath --ordinals $libnumpath --name $libname --OS linux 2> /dev/null`; | |
55 | ok($? == 0, "running 'cd $bldtop; $^X $mkdefpath --ordinals $libnumpath --name $libname --OS linux' => $?"); | |
3f8f7282 RL |
56 | }, create => 0, cleanup => 0; |
57 | ||
58 | note "Number of lines in \@nm_lines before massaging: ", scalar @nm_lines; | |
59 | note "Number of lines in \@def_lines before massaging: ", scalar @def_lines; | |
60 | ||
61 | # Massage the nm output to only contain defined symbols | |
a182e546 | 62 | @nm_lines = sort map { s| .*||; $_ } grep(m|.* [BCDST] .*|, @nm_lines); |
3f8f7282 RL |
63 | |
64 | # Massage the mkdef.pl output to only contain global symbols | |
65 | # The output we got is in Unix .map format, which has a global | |
66 | # and a local section. We're only interested in the global | |
67 | # section. | |
68 | my $in_global = 0; | |
69 | @def_lines = | |
70 | sort | |
71 | map { s|;||; s|\s+||g; $_ } | |
72 | grep { $in_global = 1 if m|global:|; | |
73 | $in_global = 0 if m|local:|; | |
77a42b5f | 74 | $in_global = 0 if m|\}|; |
3f8f7282 RL |
75 | $in_global && m|;|; } @def_lines; |
76 | ||
77 | note "Number of lines in \@nm_lines after massaging: ", scalar @nm_lines; | |
78 | note "Number of lines in \@def_lines after massaging: ", scalar @def_lines; | |
79 | ||
80 | # Maintain lists of symbols that are missing in the shared library, | |
81 | # or that are extra. | |
82 | my @missing = (); | |
83 | my @extra = (); | |
84 | ||
85 | while (scalar @nm_lines || scalar @def_lines) { | |
86 | my $nm_first = $nm_lines[0]; | |
87 | my $def_first = $def_lines[0]; | |
88 | ||
89 | if (!defined($nm_first)) { | |
90 | push @missing, shift @def_lines; | |
91 | } elsif (!defined($def_first)) { | |
92 | push @extra, shift @nm_lines; | |
93 | } elsif ($nm_first gt $def_first) { | |
94 | push @missing, shift @def_lines; | |
95 | } elsif ($nm_first lt $def_first) { | |
96 | push @extra, shift @nm_lines; | |
97 | } else { | |
98 | shift @def_lines; | |
99 | shift @nm_lines; | |
100 | } | |
101 | } | |
102 | ||
103 | if (scalar @missing) { | |
104 | note "The following symbols are missing in lib$libname.so:"; | |
105 | foreach (@missing) { | |
106 | note " $_"; | |
107 | } | |
108 | } | |
109 | if (scalar @extra) { | |
110 | note "The following symbols are extra in lib$libname.so:"; | |
111 | foreach (@extra) { | |
112 | note " $_"; | |
113 | } | |
114 | } | |
115 | ok(scalar @missing == 0, | |
116 | "check that there are no missing symbols in lib$libname.so"); | |
117 | } | |
118 | } |