summaryrefslogtreecommitdiff
path: root/build-aux/gen-crypt-symbol-vers-h
blob: d5ee15e079409014a543b454f6ebb7b57bf7076e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
#! /usr/bin/perl
# Written by Zack Weinberg <zackw at panix.com> in 2017 and 2021.
# To the extent possible under law, Zack Weinberg has waived all
# copyright and related or neighboring rights to this work.
#
# See https://creativecommons.org/publicdomain/zero/1.0/ for further
# details.

# Generate macros that control the symbol versions of the public
# library API, from a .map.in file.
#
# See libcrypt.map.in for an explanation of the format of .map.in
# files.  See crypt-port.h for an explanation of how to use the macros
# generated by this program.
#
# Note: we currently don't support compatibility symbols that need
# a different definition from the default version.

use v5.14;    # implicit use strict, use feature ':5.14'
use warnings FATAL => 'all';
use utf8;
use open qw(:std :utf8);
no  if $] >= 5.022, warnings => 'experimental::re_strict';
use if $] >= 5.022, re       => 'strict';

use FindBin ();
use lib $FindBin::Bin;
use BuildCommon qw(
    parse_version_map_in
);

sub output {
    my ($symvers) = @_;
    my $basemap = $symvers->basemap;
    print "/* Generated from $basemap by ${FindBin::Script}.  "
        . "DO NOT EDIT.  */\n";

    print <<'EOT';

#ifndef _CRYPT_SYMBOL_VERS_H
#define _CRYPT_SYMBOL_VERS_H 1

/* For each public symbol <sym>, INCLUDE_<sym> is true if it
   has any versions above the backward compatibility minimum.
   Compatibility-only symbols are not included in the static
   library, or in the shared library when configured with
   --disable-obsolete-api.  */
#if defined PIC && ENABLE_OBSOLETE_API

EOT

    for my $sym (@{$symvers->symbols}) {
        printf "#define INCLUDE_%-*s %d\n",
            $symvers->max_symlen, $sym->name, $sym->included;
    }
    print "\n#else\n\n";
    for my $sym (@{$symvers->symbols}) {
        printf "#define INCLUDE_%-*s %d\n",
            $symvers->max_symlen, $sym->name,
            $sym->included && !$sym->compat_only;
    }

    print <<'EOT';

#endif

/* When the public symbols are being given versions, they must be
   defined under a different, private name first.  */
#ifdef PIC
EOT

    for my $sym (@{$symvers->symbols}) {
        if ($sym->included) {
            printf "#define %-*s _crypt_%s\n",
                $symvers->max_symlen, $sym->name, $sym->name;
        }
    }

    print <<'EOT';
#endif

/* For each public symbol <sym> that is included, define its
   highest version as the default, and aliases at each
   compatibility version. */
EOT

    for my $sym (@{$symvers->symbols}) {
        my $name = $sym->name;
        if (!$sym->included) {
            print "#define SYMVER_$name symver_nop()\n";
            next;
        }

        my $seq = 0;
        for my $v (@{$sym->versions}) {
            if ($seq == 0) {
                print "#define SYMVER_$name \\\n";
                if ($sym->compat_only) {
                    print "  symver_compat0 (\"$name\", $name, $v)";
                } else {
                    print "  symver_default (\"$name\", $name, $v)";
                }
            } else {
                print "; \\\n"
                    . "  symver_compat ($seq, \"$name\", $name, $name, $v)";
            }
            $seq++;
        }
        print "\n";
    }

    print <<'EOT';

#endif /* crypt-symbol-vers.h */
EOT

    close STDOUT or die "write error: $!\n";
    return;
}

#
# Main
#
exit 0 if eval {
    output(parse_version_map_in(@ARGV));
    1;
};

print {*STDERR} "${FindBin::Script}: $@";
exit 1;