X-Git-Url: https://git.openssl.org/?a=blobdiff_plain;f=util%2Fmkerr.pl;h=44332d423ec5c92c147b6d7b9270dce31dea29e6;hb=e655ce14d0c68e8ddf85a2941e222f7806f84013;hp=23e4a2279764da58b16f73ac83cceeeb39cdf80a;hpb=52df25cf2e656146cb3b206d8220124f0417d03f;p=openssl.git diff --git a/util/mkerr.pl b/util/mkerr.pl index 23e4a22797..44332d423e 100755 --- a/util/mkerr.pl +++ b/util/mkerr.pl @@ -1,7 +1,7 @@ #! /usr/bin/env perl -# Copyright 1999-2016 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 1999-2020 The OpenSSL Project Authors. All Rights Reserved. # -# Licensed under the OpenSSL license (the "License"). You may not use +# Licensed under the Apache License 2.0 (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 @@ -9,6 +9,9 @@ use strict; use warnings; +use lib "."; +use configdata; + my $config = "crypto/err/openssl.ec"; my $debug = 0; my $internal = 0; @@ -17,6 +20,7 @@ my $rebuild = 0; my $reindex = 0; my $static = 0; my $unref = 0; +my %modules = (); my $errors = 0; my @t = localtime(); @@ -42,6 +46,13 @@ Options: -internal Generate code that is to be built as part of OpenSSL itself. Also scans internal list of files. + -module M Only useful with -internal! + Only write files for library module M. Whether files are + actually written or not depends on other options, such as + -rebuild. + Note: this option is cumulative. If not given at all, all + internal modules will be considered. + -nowrite Do not write the header/source files, even if changed. -rebuild Rebuild all header and C source files, even if there @@ -86,6 +97,9 @@ while ( @ARGV ) { } elsif ( $arg eq "-unref" ) { $unref = 1; $nowrite = 1; + } elsif ( $arg eq "-module" ) { + shift @ARGV; + $modules{uc $ARGV[0]} = 1; } elsif ( $arg =~ /-*h(elp)?/ ) { &help(); exit; @@ -100,27 +114,32 @@ if ( $internal ) { die "Cannot mix -internal and -static\n" if $static; die "Extra parameters given.\n" if @ARGV; @source = ( glob('crypto/*.c'), glob('crypto/*/*.c'), - glob('ssl/*.c'), glob('ssl/*/*.c') ); + glob('ssl/*.c'), glob('ssl/*/*.c'), glob('providers/*.c'), + glob('providers/*/*.c'), glob('providers/*/*/*.c') ); } else { + die "-module isn't useful without -internal\n" if scalar keys %modules > 0; @source = @ARGV; } # Data parsed out of the config and state files. +# We always map function-code values to zero, so items marked below with +# an asterisk could eventually be removed. TODO(4.0) my %hinc; # lib -> header my %libinc; # header -> lib my %cskip; # error_file -> lib my %errorfile; # lib -> error file name -my %fmax; # lib -> max assigned function code +my %fmax; # lib -> max assigned function code* my %rmax; # lib -> max assigned reason code -my %fassigned; # lib -> colon-separated list of assigned function codes +my %fassigned; # lib -> colon-separated list of assigned function codes* my %rassigned; # lib -> colon-separated list of assigned reason codes -my %fnew; # lib -> count of new function codes +my %fnew; # lib -> count of new function codes* my %rnew; # lib -> count of new reason codes my %rextra; # "extra" reason code -> lib my %rcodes; # reason-name -> value -my %ftrans; # old name -> #define-friendly name (all caps) -my %fcodes; # function-name -> value +my %ftrans; # old name -> #define-friendly name (all caps)* +my %fcodes; # function-name -> value* my $statefile; # state file with assigned reason and function codes +my %strings; # define -> text # Read and parse the config file open(IN, "$config") || die "Can't open config file $config, $!,"; @@ -167,18 +186,32 @@ if ( ! $reindex && $statefile ) { # maximum code used. while ( ) { next if /^#/ || /^$/; - die "Bad line in $statefile:\n$_\n" unless /(\S+)\s+(\d+)/; - my $name = $1; - my $code = $2; + my $name; + my $code; + if ( /^(.+):(\d+):\\$/ ) { + $name = $1; + $code = $2; + my $next = ; + $next =~ s/^\s*(.*)\s*$/$1/; + die "Duplicate define $name" if exists $strings{$name}; + $strings{$name} = $next; + } elsif ( /^(\S+):(\d+):(.*)$/ ) { + $name = $1; + $code = $2; + die "Duplicate define $name" if exists $strings{$name}; + $strings{$name} = $3; + } else { + die "Bad line in $statefile:\n$_\n"; + } my $lib = $name; - $lib =~ s/_.*//; + $lib =~ s/^((?:OSSL_|OPENSSL_)?[^_]{2,}).*$/$1/; $lib = "SSL" if $lib =~ /TLS/; if ( !defined $errorfile{$lib} ) { print "Skipping $_"; $skippedstate++; next; } - if ( $name =~ /^[A-Z0-9]+_R_/ ) { + if ( $name =~ /^(?:OSSL_|OPENSSL_)?[A-Z0-9]{2,}_R_/ ) { die "$lib reason code $code collision at $name\n" if $rassigned{$lib} =~ /:$code:/; $rassigned{$lib} .= "$code:"; @@ -186,9 +219,7 @@ if ( ! $reindex && $statefile ) { $rmax{$lib} = $code if $code > $rmax{$lib}; } $rcodes{$name} = $code; - } elsif ( $name =~ /^[A-Z0-9]+_F_/ ) { - die "$lib function code $code collision at $name\n" - if $fassigned{$lib} =~ /:$code:/; + } elsif ( $name =~ /^(?:OSSL_|OPENSSL_)?[A-Z0-9]{2,}_F_/ ) { $fassigned{$lib} .= "$code:"; $fmax{$lib} = $code if $code > $fmax{$lib}; $fcodes{$name} = $code; @@ -284,7 +315,7 @@ while ( ( my $hdr, my $lib ) = each %libinc ) { s/[\n\s]*$//g; # Skip over recognized non-function declarations - next if /typedef\W/ or /DECLARE_STACK_OF/ or /TYPEDEF_.*_OF/; + next if /typedef\W/; # Remove STACK_OF(foo) s/STACK_OF\(\w+\)/void/; @@ -299,8 +330,9 @@ while ( ( my $hdr, my $lib ) = each %libinc ) { # pretend as we didn't use curly braces: {} -> () s/\{\}/\(\)/gs; - if ( /(\w+)\s*\(\).*/s ) { # first token prior [first] () is - my $name = $1; # a function name! + # Last token just before the first () is a function name. + if ( /(\w+)\s*\(\).*/s ) { + my $name = $1; $name =~ tr/[a-z]/[A-Z]/; $ftrans{$name} = $1; } elsif ( /[\(\)]/ and not(/=/) ) { @@ -350,7 +382,7 @@ foreach my $file ( @source ) { $func = $1; } - if ( /(([A-Z0-9]+)_F_([A-Z0-9_]+))/ ) { + if ( /(((?:OSSL_|OPENSSL_)?[A-Z0-9]{2,})_F_([A-Z0-9_]+))/ ) { next unless exists $errorfile{$2}; next if $1 eq "BIO_F_BUFFER_CTX"; $usedfuncs{$1} = 1; @@ -360,14 +392,10 @@ foreach my $file ( @source ) { $fnew{$2}++; } $ftrans{$3} = $func unless exists $ftrans{$3}; - if ( uc($func) ne $3 ) { - print STDERR "ERROR: mismatch $file:$linenr $func:$3\n"; - $errors++; - } print STDERR " Function $1 = $fcodes{$1}\n" if $debug; } - if ( /(([A-Z0-9]+)_R_[A-Z0-9_]+)/ ) { + if ( /(((?:OSSL_|OPENSSL_)?[A-Z0-9]{2,})_R_[A-Z0-9_]+)/ ) { next unless exists $errorfile{$2}; $usedreasons{$1} = 1; if ( !exists $rcodes{$1} ) { @@ -386,10 +414,10 @@ print STDERR "\n" if $debug; &phase("Writing files"); my $newstate = 0; foreach my $lib ( keys %errorfile ) { - if ( ! $fnew{$lib} && ! $rnew{$lib} ) { - next unless $rebuild; - } + next if ! $fnew{$lib} && ! $rnew{$lib} && ! $rebuild; + next if scalar keys %modules > 0 && !$modules{$lib}; next if $nowrite; + next if $hinc{$lib} eq 'NONE'; print STDERR "$lib: $fnew{$lib} new functions\n" if $fnew{$lib}; print STDERR "$lib: $rnew{$lib} new reasons\n" if $rnew{$lib}; $newstate = 1; @@ -401,6 +429,9 @@ foreach my $lib ( keys %errorfile ) { my @function = sort grep( /^${lib}_/, keys %fcodes ); my @reasons = sort grep( /^${lib}_/, keys %rcodes ); + # indent level for innermost preprocessor lines + my $indent = " "; + # Rewrite the header file my $hfile = $hinc{$lib}; @@ -411,31 +442,43 @@ foreach my $lib ( keys %errorfile ) { * Generated by util/mkerr.pl DO NOT EDIT * Copyright 1995-$YEAR The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the \"License\"). You may not use + * Licensed under the Apache License 2.0 (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 */ -#ifndef HEADER_${lib}ERR_H -# define HEADER_${lib}ERR_H +#ifndef OPENSSL_${lib}ERR_H +# define OPENSSL_${lib}ERR_H +# pragma once + +# include +# include + EOF if ( $internal ) { # Declare the load function because the generate C file # includes "fooerr.h" not "foo.h" + if ($lib ne "SSL" && $lib ne "ASYNC" + && (grep { $lib eq uc $_ } @disablables, @disablables_int)) { + print OUT <<"EOF"; +# include + +# ifndef OPENSSL_NO_${lib} + +EOF + $indent = " "; + } print OUT <<"EOF"; -# ifdef __cplusplus -extern \"C\" { -# endif +#${indent}ifdef __cplusplus +extern \"C\" +#${indent}endif int ERR_load_${lib}_strings(void); -# ifdef __cplusplus -} -# endif EOF } else { print OUT <<"EOF"; -# define ${lib}err(f, r) ERR_${lib}_error((f), (r), OPENSSL_FILE, OPENSSL_LINE) +# define ${lib}err(f, r) ERR_${lib}_error(0, (r), OPENSSL_FILE, OPENSSL_LINE) EOF if ( ! $static ) { @@ -455,8 +498,10 @@ EOF } print OUT "\n/*\n * $lib function codes.\n */\n"; + print OUT "# ifndef OPENSSL_NO_DEPRECATED_3_0\n"; foreach my $i ( @function ) { my $z = 48 - length($i); + $z = 0 if $z < 0; if ( $fcodes{$i} eq "X" ) { $fassigned{$lib} =~ m/^:([^:]*):/; my $findcode = $1; @@ -468,12 +513,14 @@ EOF $fassigned{$lib} .= "$findcode:"; print STDERR "New Function code $i\n" if $debug; } - printf OUT "# define $i%s $fcodes{$i}\n", " " x $z; + printf OUT "#${indent} define $i%s 0\n", " " x $z; } + print OUT "# endif\n"; print OUT "\n/*\n * $lib reason codes.\n */\n"; foreach my $i ( @reasons ) { my $z = 48 - length($i); + $z = 0 if $z < 0; if ( $rcodes{$i} eq "X" ) { $rassigned{$lib} =~ m/^:([^:]*):/; my $findcode = $1; @@ -485,40 +532,19 @@ EOF $rassigned{$lib} .= "$findcode:"; print STDERR "New Reason code $i\n" if $debug; } - printf OUT "# define $i%s $rcodes{$i}\n", " " x $z; + printf OUT "#${indent}define $i%s $rcodes{$i}\n", " " x $z; } print OUT "\n"; - print OUT "#endif\n"; + while (length($indent) > 0) { + $indent = substr $indent, 0, -1; + print OUT "#${indent}endif\n"; + } # Rewrite the C source file containing the error details. # First, read any existing reason string definitions: - my %err_reason_strings; my $cfile = $errorfile{$lib}; - if ( open( IN, "<$cfile" ) ) { - my $line = ""; - while ( ) { - s|\R$||; # Better chomp - $_ = $line . $_; - $line = ""; - if ( /{ERR_(PACK|FUNC|REASON)\(/ ) { - if ( /\b(${lib}_R_\w*)\b.*\"(.*)\"/ ) { - $err_reason_strings{$1} = $2; - } elsif ( /\b${lib}_F_(\w*)\b.*\"(.*)\"/ ) { - if ( !exists $ftrans{$1} && $1 ne $2 ) { -# Don't print warning, too noisy. :( -# print STDERR "WARNING: Mismatched/unused function $2\n"; - $ftrans{$1} = $2; - } - } else { - $line = $_; - } - } - } - close(IN); - } - my $pack_lib = $internal ? "ERR_LIB_${lib}" : "0"; my $hincf = $hfile; $hincf =~ s|.*include/||; @@ -538,7 +564,7 @@ EOF * Generated by util/mkerr.pl DO NOT EDIT * Copyright 1995-$YEAR The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * Licensed under the Apache License 2.0 (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 @@ -549,38 +575,20 @@ EOF #ifndef OPENSSL_NO_ERR -static ${const}ERR_STRING_DATA ${lib}_str_functs[] = { -EOF - - # Add each function code: if a function name is found then use it. - foreach my $i ( @function ) { - my $fn; - $i =~ /^${lib}_F_(\S+)$/; - $fn = $1; - $fn = $ftrans{$fn} if exists $ftrans{$fn}; - my $short = " {ERR_PACK($pack_lib, $i, 0), \"$fn\"},"; - if ( length($short) <= 80 ) { - print OUT "$short\n"; - } else { - print OUT " {ERR_PACK($pack_lib, $i, 0),\n \"$fn\"},\n"; - } - } - print OUT <<"EOF"; - {0, NULL} -}; - static ${const}ERR_STRING_DATA ${lib}_str_reasons[] = { EOF # Add each reason code. foreach my $i ( @reasons ) { my $rn; - if ( exists $err_reason_strings{$i} ) { - $rn = $err_reason_strings{$i}; + if ( exists $strings{$i} ) { + $rn = $strings{$i}; + $rn = "" if $rn eq '*'; } else { $i =~ /^${lib}_R_(\S+)$/; $rn = $1; $rn =~ tr/_[A-Z]/ [a-z]/; + $strings{$i} = $rn; } my $short = " {ERR_PACK($pack_lib, 0, $i), \"$rn\"},"; if ( length($short) <= 80 ) { @@ -601,10 +609,8 @@ EOF int ERR_load_${lib}_strings(void) { #ifndef OPENSSL_NO_ERR - if (ERR_func_error_string(${lib}_str_functs[0].error) == NULL) { - ERR_load_strings_const(${lib}_str_functs); + if (ERR_reason_error_string(${lib}_str_reasons[0].error) == NULL) ERR_load_strings_const(${lib}_str_reasons); - } #endif return 1; } @@ -623,7 +629,6 @@ ${st}int ERR_load_${lib}_strings(void) if (!error_loaded) { #ifndef OPENSSL_NO_ERR - ERR_load_strings(lib_code, ${lib}_str_functs); ERR_load_strings(lib_code, ${lib}_str_reasons); #endif error_loaded = 1; @@ -635,7 +640,6 @@ ${st}void ERR_unload_${lib}_strings(void) { if (error_loaded) { #ifndef OPENSSL_NO_ERR - ERR_unload_strings(lib_code, ${lib}_str_functs); ERR_unload_strings(lib_code, ${lib}_str_reasons); #endif error_loaded = 0; @@ -646,14 +650,14 @@ ${st}void ERR_${lib}_error(int function, int reason, char *file, int line) { if (lib_code == 0) lib_code = ERR_get_next_error_library(); - ERR_PUT_error(lib_code, function, reason, file, line); + ERR_raise(lib_code, reason); + ERR_set_debug(file, line, NULL); } EOF } close OUT; - undef %err_reason_strings; } &phase("Ending"); @@ -687,11 +691,27 @@ die "Found $errors errors, quitting" if $errors; if ( $newstate ) { open(OUT, ">$statefile.new") || die "Can't write $statefile.new, $!"; + print OUT <<"EOF"; +# Copyright 1999-$YEAR The OpenSSL Project Authors. All Rights Reserved. +# +# Licensed under the Apache License 2.0 (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 +EOF + print OUT "\n# Function codes\n"; foreach my $i ( sort keys %fcodes ) { - print OUT "$i $fcodes{$i}\n"; + my $short = "$i:$fcodes{$i}:"; + my $t = exists $strings{$i} ? $strings{$i} : ""; + $t = "\\\n\t" . $t if length($short) + length($t) > 80; + print OUT "$short$t\n"; } + print OUT "\n#Reason codes\n"; foreach my $i ( sort keys %rcodes ) { - print OUT "$i $rcodes{$i}\n" if !exists $rextra{$i}; + my $short = "$i:$rcodes{$i}:"; + my $t = exists $strings{$i} ? "$strings{$i}" : ""; + $t = "\\\n\t" . $t if length($short) + length($t) > 80; + print OUT "$short$t\n" if !exists $rextra{$i}; } close(OUT); if ( $skippedstate ) { @@ -703,4 +723,5 @@ if ( $newstate ) { || die "Can't rename $statefile to $statefile.new, $!"; } } + exit;