Skip to content

openbsd: ensure we link to the built libperl.a, not the system libperl.a #23265

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: blead
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions embed.fnc
Original file line number Diff line number Diff line change
Expand Up @@ -663,6 +663,10 @@ Adp |SV * |amagic_deref_call \
p |bool |amagic_is_enabled \
|int method

CTdp |void |api_version_assert \
|size_t interp_size \
|NULLOK void *v_my_perl \
|NN const char *api_version
ETXip |void |append_utf8_from_native_byte \
|const U8 byte \
|NN U8 **dest
Expand Down
1 change: 1 addition & 0 deletions embed.h
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@
# define _to_utf8_upper_flags(a,b,c,d,e) Perl__to_utf8_upper_flags(aTHX_ a,b,c,d,e)
# define amagic_call(a,b,c,d) Perl_amagic_call(aTHX_ a,b,c,d)
# define amagic_deref_call(a,b) Perl_amagic_deref_call(aTHX_ a,b)
# define api_version_assert Perl_api_version_assert
# define apply_attrs_string(a,b,c,d) Perl_apply_attrs_string(aTHX_ a,b,c,d)
# define apply_builtin_cv_attributes(a,b) Perl_apply_builtin_cv_attributes(aTHX_ a,b)
# define atfork_lock Perl_atfork_lock
Expand Down
19 changes: 17 additions & 2 deletions lib/ExtUtils/t/Embed.t
Original file line number Diff line number Diff line change
Expand Up @@ -103,13 +103,26 @@ if ($^O eq 'VMS') {
elsif ($^O eq 'os390' && $Config{usedl}) {
push(@cmd,"-L$lib", ldopts());
} else { # Not MSWin32 or OS/390 (z/OS) dynamic.
push(@cmd,"-L$lib",'-lperl');
my $ldopts = ldopts();
if ($^O eq 'openbsd' && $Config{useshrplib} eq "false") {
# see github #22125
# with OpenBSD, the packaged gcc (tries to) link
# against the system libperl, this will be fine once
# this perl gets installed, but that's not so good when
# testing against the uninstalled perl.
# This also matches how Makefile.SH links the perl executable
push @cmd, "$lib/libperl.a";
$ldopts =~ s/ -lperl\b//;
}
else {
push(@cmd,"-L$lib",'-lperl');
}
local $SIG{__WARN__} = sub {
warn $_[0] unless $_[0] =~ /No library found for .*perl/
};
push(@cmd, '-Zlinker', '/PM:VIO') # Otherwise puts a warning to STDOUT!
if $^O eq 'os2' and $Config{ldflags} =~ /(?<!\S)-Zomf\b/;
push(@cmd,ldopts());
push(@cmd, $ldopts);
}

if ($^O eq 'aix') { # AIX needs an explicit symbol export list.
Expand Down Expand Up @@ -196,6 +209,8 @@ int main(int argc, char **argv, char **env) {
perl_construct(my_perl);
PL_exit_flags |= PERL_EXIT_WARN;

PERL_API_VERSION_ASSERT;

my_puts("ok 3");

perl_parse(my_perl, NULL, (sizeof(cmds)/sizeof(char *))-1, (char **)cmds, env);
Expand Down
8 changes: 8 additions & 0 deletions perl.h
Original file line number Diff line number Diff line change
Expand Up @@ -9264,6 +9264,14 @@ END_EXTERN_C
# define PERL_STACK_REALIGN
#endif

#ifdef MULTIPLICITY
# define PERL_API_VERSION_ASSERT \
Perl_api_version_assert(sizeof(PerlInterpreter), aTHX, PERL_API_VERSION_STRING)
#else
# define PERL_API_VERSION_ASSERT \
Perl_api_version_assert(sizeof(PerlInterpreter), NULL, PERL_API_VERSION_STRING)
#endif

/*

(KEEP THIS LAST IN perl.h!)
Expand Down
8 changes: 5 additions & 3 deletions pod/perldelta.pod
Original file line number Diff line number Diff line change
Expand Up @@ -289,7 +289,8 @@ made:

=item *

XXX
When testing embedding, add a sanity check to ensure the C<libperl> we
link against matches the perl we are building. [GH #22125]

=back

Expand Down Expand Up @@ -338,9 +339,10 @@ L</Modules and Pragmata> section.

=over 4

=item XXX-some-platform
=item OpenBSD

XXX
When testing embedding, ensure we link against the correct static
libperl. [GH #22125]

=back

Expand Down
5 changes: 5 additions & 0 deletions pod/perldiag.pod
Original file line number Diff line number Diff line change
Expand Up @@ -4020,6 +4020,11 @@ See L</500 Server error>.
by a missing delimiter on a string or pattern, because it eventually
ended earlier on the current line.

=item Mismatch between expected and libperl %s

(F) For an embedded perl, the perl headers and configuration you built
your binary against don't match the library you've linked with.

=item Mismatched brackets in template

(F) A pack template could not be parsed because pairs of C<[...]> or
Expand Down
5 changes: 5 additions & 0 deletions proto.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

46 changes: 46 additions & 0 deletions util.c
Original file line number Diff line number Diff line change
Expand Up @@ -5737,6 +5737,52 @@ S_xs_version_bootcheck(pTHX_ SSize_t items, SSize_t ax, const char *xs_p,
}
}

/*
=for apidoc api_version_assert

Used by the PERL_API_VERSION_CHECK macro to compare the perl the
object was built with and the perl that C<libperl> was built with.

This can be used to ensure that these match and produces a more
diagnosable than random crashes and mis-behaviour.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There seems to be a word or two missing after diagnosable. diagnosable behavior, perhaps?


=cut
*/

void
Perl_api_version_assert(size_t interp_size, void *v_my_perl,
const char *api_version) {
dTHX;

PERL_ARGS_ASSERT_API_VERSION_ASSERT;

if (interp_size != sizeof(PerlInterpreter)) {
/* detects various types of configuration mismatches */
/* diag_listed_as: Mismatch between expected and libperl %s */
Perl_croak(aTHX_
"Mismatch between expected and libperl interpreter structure size %zd vs %zd",
interp_size, sizeof(PerlInterpreter));
}
if (
#ifdef MULTIPLICITY
v_my_perl != my_perl
#else
v_my_perl != NULL
#endif
) {
/* detect threads vs non-threads mismatch */
/* diag_listed_as: Mismatch between expected and libperl %s */
Perl_croak(aTHX_
"Mismatch between expected and libperl interpreter pointer");
}
if (strNE(api_version, PERL_API_VERSION_STRING)) {
/* diag_listed_as: Mismatch between expected and libperl %s */
Perl_croak(aTHX_
"Mismatch between expected and libperl API versions %s vs %s",
api_version, PERL_API_VERSION_STRING);
}
}

PERL_STATIC_INLINE bool
S_gv_has_usable_name(pTHX_ GV *gv)
{
Expand Down
Loading