Skip to content
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

Add apisupport with two checks #445

Merged
merged 7 commits into from
Aug 24, 2022
Merged

Add apisupport with two checks #445

merged 7 commits into from
Aug 24, 2022

Conversation

gperciva
Copy link
Member

@gperciva gperciva commented Aug 4, 2022

No description provided.

@gperciva gperciva marked this pull request as draft August 4, 2022 00:32
@gperciva gperciva closed this Aug 4, 2022
@gperciva gperciva reopened this Aug 4, 2022
@gperciva gperciva added the depends PR depends on other PR(s) label Aug 4, 2022
@gperciva gperciva marked this pull request as ready for review August 4, 2022 19:50
@gperciva gperciva changed the title Add build-time apisupport Add apisupport with two checks Aug 4, 2022
@gperciva
Copy link
Member Author

gperciva commented Aug 4, 2022

Depends on #446.

@gperciva gperciva marked this pull request as draft August 4, 2022 19:51
@gperciva gperciva removed the depends PR depends on other PR(s) label Aug 4, 2022
@gperciva gperciva marked this pull request as ready for review August 4, 2022 23:23
@gperciva
Copy link
Member Author

gperciva commented Aug 4, 2022

In #83, you mused about adding support for other APIs (in particular, getrandom(3)). apisupport.sh sets of the framework which would allow for that.

At the moment, this PR only uses it for detecting some nitpicky compiler things. In a few places, we don't strictly obey the C99 & POSIX standards, so some compilers legitimately complain about it.

This PR does not add the capability for our code to do things like #ifdef APISUPPORT_NONPOSIX_SETGROUPS. I have that available in a separate branch, but at the moment there's no need for such things, so I haven't included it. Likewise, there's no runtime checks (such as a theoretical apisupport_linux_getrandom(), similar to cpusupport_x86_shani()) in this particular PR.

CFLAGS_HARDCODED="-D_POSIX_C_SOURCE=200809L -D_XOPEN_SOURCE=700"

feature() {
ARCH=$1
Copy link
Member

Choose a reason for hiding this comment

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

s/ARCH/PLATFORM/ ?

Copy link
Member Author

Choose a reason for hiding this comment

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

Hmm, good point. I'm happy calling it PLATFORM, but at the moment, I'm using that variable to be NONPOSIX and LIBSSL. Is that stretching the meaning of "platform"?

Copy link
Member

Choose a reason for hiding this comment

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

Maybe a bit of a stretch but it's better than anything else which comes to mind.

Copy link
Member Author

Choose a reason for hiding this comment

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

ok, done as a REBASE commit.

@cperciva
Copy link
Member

Ok, LGTM. We should probably change the NO_SETGROUPS check to a APISUPPORT_NONPOSIX_SETGROUPS in setgroups_none.c at some point though?

@gperciva
Copy link
Member Author

At some point, yes.

This PR does not add the capability for our code to do things like #ifdef APISUPPORT_NONPOSIX_SETGROUPS

Although maybe "some point" should be "now".

It would be easy to add that back in -- actually, the first 3 drafts of this PR contained that code, but I removed it since it wasn't needed. This gives me an excuse to get that infrastructure done now.

@gperciva
Copy link
Member Author

We should probably change the NO_SETGROUPS check to a APISUPPORT_NONPOSIX_SETGROUPS in setgroups_none.c at some point though?

On second thought, I'm not sure about this.

Suppose that FreeBSD 14.0 moved setgroups() out of <unistd.h> and into <grp.h>. What would we want libcperciva to do?

  • give a compile error (because we expected util/setgroups_none.c to have the correct includes)
  • silently make setgroups_none() do nothing

I'd say that "compile error" is the appropriate response.

I'll still add the "support preprocessor #if APISUPPORT_FOO_BAR" stuff to this PR, but I won't mess with NO_SETGROUPS. We can revisit that in a separate PR targeted at that case.

@gperciva
Copy link
Member Author

Updated. I put the cpusupport.sh changes in a separate #449, but if you'd prefer to just merge it all in this PR, that's fine with me.

There's now a ton of Makefile changes to add -DAPISUPPORT_CONFIG_FILE=\"apisupport-config.h\" everywhere.

FEATURE=$2
EXTRALIB=$3
shift 3;
if ! [ -f "${SRCDIR}"/apisupport-"$PLATFORM"-"$FEATURE".c ]; then
Copy link
Member

Choose a reason for hiding this comment

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

Excessive quotes (as in cpusupport.sh).

@gperciva gperciva removed the depends PR depends on other PR(s) label Aug 21, 2022
Specifically, I did:
- s/cpu/api/g
- s/CPU/API/g
- s/ARCH/PLATFORM/g
- removed the CPU features from the bottom of the file

This commit does not include any run-time detection (which would occur
in a new apisupport.h file).
It will be useful to allow checks to link to certain libraries
(notably libssl).
This allows us to:
- detect any compiler flags needed for special functionality
- use those flags for specific files
- use `#ifdef APISUPPORT_$platform_$feature` in the C preprocessor
setgroups() is not part of POSIX.  We've hardcoded -D_POSIX_C_SOURCE=200809L
-D_XOPEN_SOURCE=700 into our command-line arguments, and we're trying to
undo that in util/setgroups_none.c by having:
    /* We use non-POSIX functionality in this file. */
    #undef _POSIX_C_SOURCE
    #undef _XOPEN_SOURCE

However, that's not technically allowed under C99:

c99 7.1.3 Reserved identifiers:
    All identifiers that begin with an underscore and either an uppercase
    letter or another underscore are always reserved for any use.

    ...

    If the program removes (with #undef) any macro definition of an
    identifier in the first group listed above, the behavior is undefined.

The POSIX page for c99 states:
    -D  name[=value]
	Define name as if by a C-language #define directive. If no = value
	is given, a value of 1 shall be used. The -D option has lower
	precedence than the -U option. That is, if name is used in both a -U
	and a -D option, name shall be undefined regardless of the order of
	the options.
    ...
    -U  name
        Remove any initial definition of name.

In other words, `-U foo` is not the same thing as prepending `#undef foo`
to the top of the source file [1][2].

So our goal of this commit is to detect whether appending
-U_POSIX_C_SOURCE -U_XOPEN_SOURCE to the command-line will allow the
compiler to find setgroups().

[1] gcc and clang have slightly different descriptions of -D and -U: gcc
says that -U cancels any *previous* definition of foo, while clang says
that it adds an implicit #undef that is read before the source file is
processed.  But those compiler's lack of POSIX compliance is not our
responsibility... and in any case, I'm fairly confident that is a
completely theoretical issue.

[2] FWIW, FreeBSD's `man c99` matches the POSIX behaviour for -U,
whereas `man cc` has the non-POSIX clang behaviour for -U.
openssl documents SSL_set_tlsext_host_name function prototype as:

     int SSL_set_tlsext_host_name(const SSL *s, const char *name);

However, <openssl/tls1.h> implements it as:

    # define SSL_set_tlsext_host_name(s,name) \
        SSL_ctrl(s,SSL_CTRL_SET_TLSEXT_HOSTNAME,TLSEXT_NAMETYPE_host_name,\
                (void *)name)

which drops the "const" from the "name" parameter.  That's technically not
allowed, so the compiler might need to use a special flag for this file.
@gperciva
Copy link
Member Author

Fixed, rebased, ready for merge or more review.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

2 participants