]>
git.ipfire.org Git - thirdparty/openssl.git/blob - test/recipes/01-test_symbol_presence.t
3 # Copyright 2016-2023 The OpenSSL Project Authors. All Rights Reserved.
5 # Licensed under the Apache License 2.0 (the "License"). You may not use
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
11 use File
::Spec
::Functions
qw(devnull);
13 use OpenSSL
::Test
qw(:DEFAULT srctop_file srctop_dir bldtop_dir bldtop_file);
14 use OpenSSL
::Test
::Utils
;
17 setup
("test_symbol_presence");
20 use lib srctop_dir
('Configurations');
21 use lib bldtop_dir
('.');
24 plan skip_all
=> "Test is disabled on NonStop" if config
('target') =~ m
|^nonstop
|;
25 # MacOS arranges symbol names differently
26 plan skip_all
=> "Test is disabled on MacOS" if config
('target') =~ m
|^darwin
|;
27 plan skip_all
=> "This is unsupported on platforms that don't have 'nm'"
28 unless IPC
::Cmd
::can_run
('nm');
31 "NOTE: developer test! It's possible that it won't run on your\n",
32 "platform, and that's perfectly fine. This is mainly for developers\n",
33 "on Unix to check that our shared libraries are consistent with the\n",
34 "ordinals (util/*.num in the source tree), and that our static libraries\n",
35 "don't share symbols, something that should be a good enough check for\n",
36 "the other platforms as well.\n";
43 foreach (qw(crypto ssl)) {
44 $stlibname{$_} = platform
->staticlib("lib$_");
45 $stlibpath{$_} = bldtop_file
($stlibname{$_});
46 $shlibname{$_} = platform
->sharedlib("lib$_") unless disabled
('shared');
47 $shlibpath{$_} = bldtop_file
($shlibname{$_}) unless disabled
('shared');
51 = 1 # Check for static library symbols duplicates
54 += (scalar keys %shlibpath) # Check for missing symbols in shared lib
55 unless disabled
('shared');
57 plan tests
=> $testcount;
59 ######################################################################
61 # [3 tests per library]
63 my %stsymbols; # Static library symbols
64 my %shsymbols; # Shared library symbols
65 my %defsymbols; # Symbols taken from ordinals
66 foreach (sort keys %stlibname) {
67 my $stlib_cmd = "nm -Pg $stlibpath{$_} 2> /dev/null";
68 my $shlib_cmd = "nm -DPg $shlibpath{$_} 2> /dev/null";
73 open STDERR
, ">", devnull
();
74 open STDOUT
, ">", devnull
();
75 @stlib_lines = map { s
|\R
$||; $_ } `$stlib_cmd`;
77 note
"running '$stlib_cmd' => $?";
80 unless (disabled
('shared')) {
81 @shlib_lines = map { s
|\R
$||; $_ } `$shlib_cmd`;
83 note
"running '$shlib_cmd' => $?";
92 my $bldtop = bldtop_dir
();
94 unless (disabled
('shared')) {
95 indir
$bldtop => sub {
96 my $mkdefpath = srctop_file
("util", "mkdef.pl");
97 my $def_path = srctop_file
("util", "lib$_.num");
98 my $def_cmd = "$^X $mkdefpath --ordinals $def_path --name $_ --OS linux 2> /dev/null";
99 @def_lines = map { s
|\R
$||; $_ } `$def_cmd`;
101 note
"running 'cd $bldtop; $def_cmd' => $?";
104 }, create
=> 0, cleanup
=> 0;
107 note
"Number of lines in \@stlib_lines before massaging: ", scalar @stlib_lines;
108 unless (disabled
('shared')) {
109 note
"Number of lines in \@shlib_lines before massaging: ", scalar @shlib_lines;
110 note
"Number of lines in \@def_lines before massaging: ", scalar @def_lines;
113 # Massage the nm output to only contain defined symbols
114 my @arrays = ( \
@stlib_lines );
115 push @arrays, \
@shlib_lines unless disabled
('shared');
120 # Drop the first space and everything following it
122 # Drop OpenSSL dynamic version information if there is any
127 grep(m
|.* [BCDST
] .*|, @
$_);
130 # Massage the mkdef.pl output to only contain global symbols
131 # The output we got is in Unix .map format, which has a global
132 # and a local section. We're only interested in the global
135 unless (disabled
('shared')) {
138 map { s
|;||; s
|\s
+||g
; $_ }
139 grep { $in_global = 1 if m
|global
:|;
140 $in_global = 0 if m
|local:|;
141 $in_global = 0 if m
|\
}|;
142 $in_global && m
|;|; } @def_lines;
145 note
"Number of lines in \@stlib_lines after massaging: ", scalar @stlib_lines;
146 unless (disabled
('shared')) {
148 note
"Number of lines in \@shlib_lines after massaging: ", scalar @shlib_lines;
149 note
"Number of lines in \@def_lines after massaging: ", scalar @def_lines;
152 $stsymbols{$_} = [ @stlib_lines ];
153 unless (disabled
('shared')) {
154 $shsymbols{$_} = [ @shlib_lines ];
155 $defsymbols{$_} = [ @def_lines ];
159 ######################################################################
160 # Check that there are no duplicate symbols in all our static libraries
165 foreach (sort keys %stlibname) {
166 foreach (@
{$stsymbols{$_}}) {
170 my @duplicates = sort grep { $symbols{$_} > 1 } keys %symbols;
173 note
join('\n', @duplicates);
175 ok
(scalar @duplicates == 0, "checking no duplicate symbols in static libraries");
177 ######################################################################
178 # Check that the exported symbols in our shared libraries are consistent
179 # with our ordinals files.
180 # [1 test per library]
182 unless (disabled
('shared')) {
183 foreach (sort keys %stlibname) {
184 # Maintain lists of symbols that are missing in the shared library,
189 my @sh_symbols = ( @
{$shsymbols{$_}} );
190 my @def_symbols = ( @
{$defsymbols{$_}} );
192 while (scalar @sh_symbols || scalar @def_symbols) {
193 my $sh_first = $sh_symbols[0];
194 my $def_first = $def_symbols[0];
196 if (!defined($sh_first)) {
197 push @missing, shift @def_symbols;
198 } elsif (!defined($def_first)) {
199 push @extra, shift @sh_symbols;
200 } elsif ($sh_first gt $def_first) {
201 push @missing, shift @def_symbols;
202 } elsif ($sh_first lt $def_first) {
203 push @extra, shift @sh_symbols;
210 if (scalar @missing) {
211 note
"The following symbols are missing in $_:";
217 note
"The following symbols are extra in $_:";
222 ok
(scalar @missing == 0,
223 "check that there are no missing symbols in $_");