Refactor linker script generation

The generation of linker scripts was badly balanced, as all sorts of
platform dependent stuff went into the top build.info, when that part
should really be made as simply and generic as possible.

Therefore, we move a lot of the "magic" to the build files templates,
since they are the place for platform dependent things.  What remains
is to parametrize just enough in the build.info file to generate the
linker scripts correctly for each associated library.

"linker script" is a term usually reserved for certain Unix linkers.
However, we only use them to say what symbols should be exported, so
we use the term loosely for all platforms.  The internal extension is
'.ld', and is changed by the build file templates as appropriate for
each target platform.

Note that this adds extra meaning to the value of the shared_target
attribute.

Reviewed-by: Tim Hudson <tjh@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/7333)
This commit is contained in:
Richard Levitte 2018-09-30 14:44:59 +02:00
parent b44882a0bd
commit ef2dfc9902
9 changed files with 90 additions and 72 deletions

View file

@ -211,7 +211,7 @@ my %targets = (
ex_libs => add("-lsocket -lnsl -ldl"),
dso_scheme => "dlfcn",
thread_scheme => "pthreads",
shared_target => "self",
shared_target => "solaris",
shared_extension => ".so.\$(SHLIB_VERSION_NUMBER)",
shared_ldflag => "-Wl,-Bsymbolic",
shared_defflag => "-Wl,-M,",
@ -1113,7 +1113,7 @@ my %targets = (
lflags => "-Wl,-bsvr4",
thread_scheme => "pthreads",
dso_scheme => "dlfcn",
shared_target => "self",
shared_target => "aix",
module_ldflags => "-Wl,-G,-bsymbolic,-bexpall",
shared_ldflag => "-Wl,-G,-bsymbolic",
shared_defflag => "-Wl,-bE:",
@ -1230,6 +1230,8 @@ my %targets = (
lib_defines => add("L_ENDIAN"),
dso_cflags => "/Zi /Fddso.pdb",
bin_cflags => "/Zi /Fdapp.pdb",
# def_flag made to empty string so a .def file gets generated
shared_defflag => '',
shared_ldflag => "/dll",
shared_target => "win-shared", # meaningless except it gives Configure a hint
thread_scheme => "winthreads",
@ -1743,6 +1745,8 @@ my %targets = (
dso_cflags => "",
ex_libs => add(sub { return vms_info()->{zlib} || (); }),
shared_target => "vms-shared",
# def_flag made to empty string so a .opt file gets generated
shared_defflag => '',
dso_scheme => "vms",
thread_scheme => "pthreads",

View file

@ -169,7 +169,14 @@ In each table entry, the following keys are significant:
assembler files used when compiling with
assembler implementations.
shared_target => The shared library building method used.
This is a target found in Makefile.shared.
This serves multiple purposes:
- as index for targets found in shared_info.pl.
- as linker script generation selector.
To serve both purposes, the index for shared_info.pl
should end with '-shared', and this suffix will be
removed for use as a linker script generation
selector. Note that the latter is only used if
'shared_defflag' is defined.
build_scheme => The scheme used to build up a Makefile.
In its simplest form, the value is a string
with the name of the build scheme.

View file

@ -132,7 +132,10 @@ DEPS={- our @deps = map { (my $x = $_) =~ s|\.o$|\$(DEP_EXT)|; $x; }
{- output_on() if $disabled{makedepend}; "" -}
GENERATED_MANDATORY={- join(", ", map { "-\n\t".$_ } @{$unified_info{depends}->{""}} ) -}
GENERATED={- # common0.tmpl provides @generated
join(", ", map { (my $x = $_) =~ s|\.[sS]$|.asm|; "-\n\t".$x }
join(", ", map { my $x = $_;
$x =~ s|\.[sS]$|.asm|;
$x =~ s|\.ld$|.OPT|;
"-\n\t".$x }
@generated) -}
INSTALL_LIBS={- join(", ", map { "-\n\t".$_.".OLB" } @install_libs) -}
@ -748,12 +751,19 @@ reconfigure reconf :
sub generatesrc {
my %args = @_;
(my $target = $args{src}) =~ s/\.[sS]$/.asm/;
my $generator = join(" ", @{$args{generator}});
my $generator_incs = join("", map { ' "-I'.$_.'"' } @{$args{generator_incs}});
my $deps = join(", -\n\t\t", @{$args{generator_deps}}, @{$args{deps}});
if ($target !~ /\.asm$/) {
if ($args{src} =~ /\.ld$/) {
(my $target = $args{src}) =~ s/\.ld$/.OPT/;
my $mkdef = sourcefile('util', 'mkdef.pl');
return <<"EOF";
$target : $args{generator}->[0] $deps
\$(PERL) $mkdef $args{generator}->[1] "VMS" > $target
EOF
} elsif ($target !~ /\.[sS]$/) {
my $target = $args{src};
if ($args{generator}->[0] =~ m|^.*\.in$|) {
my $dofile = abs2rel(rel2abs(catfile($config{sourcedir},
"util", "dofile.pl")),
@ -770,6 +780,7 @@ $target : $args{generator}->[0] $deps
EOF
}
} else {
(my $target = $args{src}) =~ s/\.[sS]$/.asm/;
if ($args{generator}->[0] =~ /\.pl$/) {
$generator = '$(PERL)'.$generator_incs.' '.$generator;
} elsif ($args{generator}->[0] =~ /\.S$/) {
@ -913,7 +924,9 @@ EOF
my @objs = map { (my $x = $_) =~ s|\.o$|.OBJ|; $x }
grep { $_ =~ m|\.o$| }
@{$args{objs}};
my @defs = grep { $_ =~ /\.opt$/ } @{$args{objs}};
my @defs = map { (my $x = $_) =~ s|\.ld$|.OPT|; $x }
grep { $_ =~ /\.ld$/ }
@{$args{objs}};
my @deps = compute_lib_depends(@{$args{deps}});
die "More than one symbol vector" if scalar @defs > 1;
my $deps = join(", -\n\t\t", @objs, @defs, @deps);

View file

@ -53,7 +53,7 @@ my %shared_info;
'mingw-shared' => sub {
return {
%{$shared_info{'cygwin-shared'}},
# def_flag made to empty string so it still generates
# def_flag made to empty string so it still generates
# something
shared_defflag => '',
};

View file

@ -4,6 +4,7 @@
## {- join("\n## ", @autowarntext) -}
{-
our $objext = $target{obj_extension} || ".o";
our $defext = $target{def_extension} || ".ld";
our $depext = $target{dep_extension} || ".d";
our $exeext = $target{exe_extension} || "";
our $libext = $target{lib_extension} || ".a";
@ -112,7 +113,10 @@ DEPS={- join(" ", map { (my $x = $_) =~ s|\.o$|$depext|; $x; }
{- output_on() if $disabled{makedepend}; "" -}
GENERATED_MANDATORY={- join(" ", @{$unified_info{depends}->{""}}) -}
GENERATED={- # common0.tmpl provides @generated
join(" ", @generated ) -}
join(" ", map { my $x = $_;
$x =~ s|\.ld$|$defext|;
$x }
@generated ) -}
INSTALL_LIBS={- join(" ", map { lib($_) } @{$unified_info{install}->{libraries}}) -}
INSTALL_SHLIBS={- join(" ", map { shlib($_) } @{$unified_info{install}->{libraries}}) -}
@ -408,7 +412,7 @@ libclean:
fi; \
done
$(RM) $(LIBS)
$(RM) *.map
$(RM) *.{- $defext -}
clean: libclean
$(RM) $(PROGRAMS) $(TESTPROGS) $(ENGINES) $(SCRIPTS)
@ -956,7 +960,14 @@ reconfigure reconf:
my $incs = join("", map { " -I".$_ } @{$args{incs}});
my $deps = join(" ", @{$args{generator_deps}}, @{$args{deps}});
if ($args{src} !~ /\.[sS]$/) {
if ($args{src} =~ /\.ld$/) {
(my $target = $args{src}) =~ s/\.ld$/${defext}/;
(my $mkdef_os = $target{shared_target}) =~ s|-shared$||;
return <<"EOF";
$target: $args{generator}->[0] $deps
\$(PERL) \$(SRCDIR)/util/mkdef.pl $args{generator}->[1] $mkdef_os > $target
EOF
} elsif ($args{src} !~ /\.[sS]$/) {
if ($args{generator}->[0] =~ m|^.*\.in$|) {
my $dofile = abs2rel(rel2abs(catfile($config{sourcedir},
"util", "dofile.pl")),
@ -1102,9 +1113,11 @@ EOF
(my $l = $f) =~ s/^lib//;
" -l$l" } @{$args{deps}});
my @objs = map { (my $x = $_) =~ s|\.o$||; "$x$objext" }
grep { $_ !~ m/\.(?:def|map)$/ }
grep { $_ !~ m/\.ld$/ }
@{$args{objs}};
my @defs = map { (my $x = $_) =~ s|\.ld$||; "$x$defext" }
grep { $_ =~ /\.ld$/ }
@{$args{objs}};
my @defs = grep { $_ =~ /\.(?:def|map)$/ } @{$args{objs}};
my @deps = compute_lib_depends(@{$args{deps}});
die "More than one exported symbol map" if scalar @defs > 1;
my $objs = join(" ", @objs);
@ -1169,7 +1182,7 @@ EOF
(my $l = $f) =~ s/^lib//;
" -l$l" } @{$args{deps}});
my @objs = map { (my $x = $_) =~ s|\.o$||; "$x$objext" }
grep { $_ !~ m/\.(?:def|map)$/ }
grep { $_ !~ m/\.ld$/ }
@{$args{objs}};
my @deps = compute_lib_depends(@{$args{deps}});
my $objs = join(" ", @objs);

View file

@ -6,6 +6,7 @@
our $objext = $target{obj_extension} || ".obj";
our $resext = $target{res_extension} || ".res";
our $depext = $target{dep_extension} || ".d";
our $defext = $target{dep_extension} || ".def";
our $exeext = $target{exe_extension} || ".exe";
our $libext = $target{lib_extension} || ".lib";
our $shlibext = $target{shared_extension} || ".dll";
@ -89,7 +90,10 @@ DEPS={- join(" ", map { (my $x = $_) =~ s|\.o$|$depext|; $x; }
{- output_on() if $disabled{makedepend}; "" -}
GENERATED_MANDATORY={- join(" ", @{$unified_info{depends}->{""}} ) -}
GENERATED={- # common0.tmpl provides @generated
join(" ", map { (my $x = $_) =~ s|\.[sS]$|.asm|; $x }
join(" ", map { my $x = $_;
$x =~ s|\.[sS]$|.asm|;
$x =~ s|\.ld$|$defext|;
$x }
@generated) -}
INSTALL_LIBS={- join(" ", map { quotify1(lib($_)) } @{$unified_info{install}->{libraries}}) -}
@ -496,7 +500,6 @@ reconfigure reconf:
sub generatesrc {
my %args = @_;
(my $target = $args{src}) =~ s/\.[sS]$/.asm/;
my ($gen0, @gens) = @{$args{generator}};
my $generator = '"'.$gen0.'"'.join('', map { " $_" } @gens);
my $generator_incs = join("", map { " -I \"$_\"" } @{$args{generator_incs}});
@ -504,7 +507,17 @@ reconfigure reconf:
my $deps = @{$args{deps}} ?
'"'.join('" "', @{$args{generator_deps}}, @{$args{deps}}).'"' : '';
if ($target !~ /\.asm$/) {
if ($args{src} =~ /\.ld$/) {
(my $target = $args{src}) =~ s/\.ld$/$defext/;
my $mkdef = abs2rel(rel2abs(catfile($config{sourcedir},
"util", "mkdef.pl")),
rel2abs($config{builddir}));
return <<"EOF";
$target: $args{generator}->[0] $deps
\$(PERL) $mkdef $args{generator}->[1] 32 > $target
EOF
} elsif ($args{src} !~ /\.[sS]$/) {
my $target = $args{src};
if ($args{generator}->[0] =~ m|^.*\.in$|) {
my $dofile = abs2rel(rel2abs(catfile($config{sourcedir},
"util", "dofile.pl")),
@ -521,6 +534,7 @@ $target: "$args{generator}->[0]" $deps
EOF
}
} else {
(my $target = $args{src}) =~ s/\.[sS]$/.asm/;
if ($args{generator}->[0] =~ /\.pl$/) {
$generator = '"$(PERL)"'.$generator_incs.' '.$generator;
} elsif ($args{generator}->[0] =~ /\.S$/) {
@ -623,7 +637,9 @@ EOF
my @objs = map { (my $x = $_) =~ s|\.o$|$objext|; $x }
grep { $_ =~ m/\.(?:o|res)$/ }
@{$args{objs}};
my @defs = grep { $_ =~ /\.def$/ } @{$args{objs}};
my @defs = map { (my $x = $_) =~ s|\.ld$||; "$x$defext" }
grep { $_ =~ /\.ld$/ }
@{$args{objs}};
my @deps = compute_lib_depends(@{$args{deps}});
die "More than one exported symbols list" if scalar @defs > 1;
my $linklibs = join("", map { "$_\n" } @deps);

View file

@ -1121,7 +1121,9 @@ $target{exe_extension}="";
$target{exe_extension}=".exe" if ($config{target} eq "DJGPP"
|| $config{target} =~ /^(?:Cygwin|mingw)/);
$target{exe_extension}=".pm" if ($config{target} =~ /vos/);
$target{def_extension}=".ld";
$target{def_extension}=".def" if $config{target} =~ /^mingw|VC-/;
$target{def_extension}=".opt" if $config{target} =~ /^vms/;
($target{shared_extension_simple}=$target{shared_extension})
=~ s|\.\$\(SHLIB_VERSION_NUMBER\)||
unless defined($target{shared_extension_simple});
@ -2074,11 +2076,11 @@ EOF
my $o = cleanfile($buildd, $o, $blddir);
$unified_info{shared_sources}->{$ddest}->{$o} = -1;
$unified_info{sources}->{$o}->{$s} = -1;
} elsif ($s =~ /\.(def|map|opt)$/) {
# We also recognise .def / .map / .opt files
} elsif ($s =~ /\.ld$/) {
# We also recognise linker scripts (or corresponding)
# We know they are generated files
my $def = cleanfile($buildd, $s, $blddir);
$unified_info{shared_sources}->{$ddest}->{$def} = 1;
my $ld = cleanfile($buildd, $s, $blddir);
$unified_info{shared_sources}->{$ddest}->{$ld} = 1;
} else {
die "unrecognised source file type for shared library: $s\n";
}
@ -2189,7 +2191,7 @@ EOF
}
}
# Go through all object files and change their names to something that
# Go through all intermediary files and change their names to something that
# reflects what they will be built for. Note that for some source files,
# this leads to duplicate object files because they are used multiple times.
# the goal is to rename all object files according to this scheme:
@ -2246,8 +2248,9 @@ EOF
map { keys %{$unified_copy{$_}->{$prod}} }
@src;
foreach (keys %prod_sources) {
# Only affect object or resource files, the others
# simply get a new value (+1 instead of -1)
# Only affect object files and resource files,
# the others simply get a new value
# (+1 instead of -1)
if ($_ =~ /\.(o|res)$/) {
(my $prodname = $prod) =~ s|\.a$||;
my $newobj =

View file

@ -25,50 +25,11 @@ DEPEND[crypto/include/internal/dso_conf.h]=configdata.pm
GENERATE[crypto/include/internal/dso_conf.h]=crypto/include/internal/dso_conf.h.in
IF[{- defined $target{shared_defflag} -}]
IF[{- $config{target} =~ /^mingw/ -}]
GENERATE[libcrypto.def]=util/mkdef.pl crypto 32
DEPEND[libcrypto.def]=util/libcrypto.num
GENERATE[libssl.def]=util/mkdef.pl ssl 32
DEPEND[libssl.def]=util/libssl.num
SHARED_SOURCE[libcrypto]=libcrypto.ld
SHARED_SOURCE[libssl]=libssl.ld
SHARED_SOURCE[libcrypto]=libcrypto.def
SHARED_SOURCE[libssl]=libssl.def
ELSIF[{- $config{target} =~ /^aix/ -}]
GENERATE[libcrypto.map]=util/mkdef.pl crypto aix
DEPEND[libcrypto.map]=util/libcrypto.num
GENERATE[libssl.map]=util/mkdef.pl ssl aix
DEPEND[libssl.map]=util/libssl.num
SHARED_SOURCE[libcrypto]=libcrypto.map
SHARED_SOURCE[libssl]=libssl.map
ELSE
GENERATE[libcrypto.map]=util/mkdef.pl crypto linux
DEPEND[libcrypto.map]=util/libcrypto.num
GENERATE[libssl.map]=util/mkdef.pl ssl linux
DEPEND[libssl.map]=util/libssl.num
SHARED_SOURCE[libcrypto]=libcrypto.map
SHARED_SOURCE[libssl]=libssl.map
ENDIF
ENDIF
# VMS and VC don't have parametrised .def / .symvec generation, so they get
# special treatment, since we know they do use these files
IF[{- $config{target} =~ /^VC-/ -}]
GENERATE[libcrypto.def]=util/mkdef.pl crypto 32
DEPEND[libcrypto.def]=util/libcrypto.num
GENERATE[libssl.def]=util/mkdef.pl ssl 32
DEPEND[libssl.def]=util/libssl.num
SHARED_SOURCE[libcrypto]=libcrypto.def
SHARED_SOURCE[libssl]=libssl.def
ELSIF[{- $config{target} =~ /^vms/ -}]
GENERATE[libcrypto.opt]=util/mkdef.pl crypto "VMS"
DEPEND[libcrypto.opt]=util/libcrypto.num
GENERATE[libssl.opt]=util/mkdef.pl ssl "VMS"
DEPEND[libssl.opt]=util/libssl.num
SHARED_SOURCE[libcrypto]=libcrypto.opt
SHARED_SOURCE[libssl]=libssl.opt
GENERATE[libcrypto.ld]=util/libcrypto.num crypto
GENERATE[libssl.ld]=util/libssl.num ssl
ENDIF
IF[{- $config{target} =~ /^(?:Cygwin|mingw|VC-)/ -}]

View file

@ -167,12 +167,13 @@ foreach (@ARGV, split(/ /, $config{options}))
$debug=1 if $_ eq "debug";
$trace=1 if $_ eq "trace";
$verbose=1 if $_ eq "verbose";
$W32=1 if $_ eq "32";
die "win16 not supported" if $_ eq "16";
if($_ eq "NT") {
if ($_ eq "32" || $_ eq "mingw") {
$W32=1;
} elsif ($_ eq "NT") {
$W32 = 1;
$NT = 1;
} elsif ($_ eq "linux") {
} elsif ($_ eq "linux" || $_ eq "solaris") {
$linux=1;
$UNIX=1;
} elsif ($_ eq "aix") {