Page MenuHomeFreeBSD

efirt: restrict visibility of EFIABI_ATTR-declared functions
ClosedPublic

Authored by rlibby on Jul 18 2017, 8:10 AM.
Tags
None
Referenced Files
Unknown Object (File)
Thu, Oct 3, 11:57 AM
Unknown Object (File)
Thu, Oct 3, 9:19 AM
Unknown Object (File)
Wed, Oct 2, 1:09 PM
Unknown Object (File)
Wed, Oct 2, 12:12 PM
Unknown Object (File)
Wed, Oct 2, 10:00 AM
Unknown Object (File)
Fri, Sep 27, 4:07 PM
Unknown Object (File)
Fri, Sep 27, 12:23 AM
Unknown Object (File)
Thu, Sep 26, 6:08 AM
Subscribers

Details

Summary

In-tree gcc (4.2) doesn't understand __attribute__((ms_abi)) (EFIABI_ATTR). Avoid declaring functions with that attribute when the compiler is detected to be gcc < 4.4.

I realize that the old in-tree gcc is not a high priority but there is some value in keeping it functioning and this is one of the last couple thing blocking amd64/gcc4.2 buildkernel.

Diff Detail

Lint
Lint Passed
Unit
No Test Coverage
Build Status
Buildable 10555
Build 10962: arc lint + arc unit

Event Timeline

I would strongly prefer to have gcc version check in amd64/include/efi.h. The arm64 architecture currently lacks real-time clock, which must be implemented as GetTime() rt service and this is overdue.

I do not see much need to support old clang.

imp requested changes to this revision.EditedJul 18 2017, 1:59 PM

IMHO, This is completely bogus.

We do not support and cannot support building anything using EFI with the old gcc compiler. Better to have a check to see if it is the old gcc compiler and #error, or like we do for the loader build, exclude those modules when built with old gcc.

There will be other architectures where this code is used, like arm64, once the VM stuff is done for them.

Do not commit this code.

What's the use case that this is even included with gcc 4.2.1?

This revision now requires changes to proceed.Jul 18 2017, 1:59 PM
In D11636#241051, @imp wrote:

IMHO, This is completely bogus.

We do not support and cannot support building anything using EFI with the old gcc compiler. Better to have a check to see if it is the old gcc compiler and #error, or like we do for the loader build, exclude those modules when built with old gcc.

There will be other architectures where this code is used, like arm64, once the VM stuff is done for them.

Do not commit this code.

What's the use case that this is even included with gcc 4.2.1?

This isn't to build efirt with gcc 4.2, it's to NOT build it!

The EFIABI_ATTR decls currently are visible even when not compiling efi code, which breaks the gcc 4.2 build even when specifying WITHOUT_MODULES=efirt. E.g.

cc [...] /usr/src/freebsd/sys/amd64/amd64/machdep.c
cc1: warnings being treated as errors
In file included from /usr/src/freebsd/sys/amd64/amd64/machdep.c:65:
/usr/src/freebsd/sys/sys/efi.h:146: warning: 'ms_abi' attribute directive ignored [-Wattributes]

And also some userland code (don't recall exactly what, some ioctl code). So either the decls need to be hidden from in-tree gcc somehow, or it will no longer work for amd64 buildkernel or buildworld.

In D11636#241051, @imp wrote:

IMHO, This is completely bogus.

We do not support and cannot support building anything using EFI with the old gcc compiler. Better to have a check to see if it is the old gcc compiler and #error, or like we do for the loader build, exclude those modules when built with old gcc.

There will be other architectures where this code is used, like arm64, once the VM stuff is done for them.

Do not commit this code.

What's the use case that this is even included with gcc 4.2.1?

This isn't to build efirt with gcc 4.2, it's to NOT build it!

The EFIABI_ATTR decls currently are visible even when not compiling efi code, which breaks the gcc 4.2 build even when specifying WITHOUT_MODULES=efirt. E.g.

cc [...] /usr/src/freebsd/sys/amd64/amd64/machdep.c
cc1: warnings being treated as errors
In file included from /usr/src/freebsd/sys/amd64/amd64/machdep.c:65:
/usr/src/freebsd/sys/sys/efi.h:146: warning: 'ms_abi' attribute directive ignored [-Wattributes]

And also some userland code (don't recall exactly what, some ioctl code). So either the decls need to be hidden from in-tree gcc somehow, or it will no longer work for amd64 buildkernel or buildworld.

The proper solution then is what both kib and I are saying: add the proper ifdef so it isn't included when compiling with the old compiler. The declarations belong here as they aren't machine specific. The old compiler is going away, and it makes no sense to move something out of the way when we'll just move it back for arm64 EFIRT support later. Just ifdef it out for gcc < 4.4. We'll be dropping support for that in 12 most likely and it's a lot easier to delete a couple of lines than to move it around.

In D11636#241063, @imp wrote:

The proper solution then is what both kib and I are saying: add the proper ifdef so it isn't included when compiling with the old compiler. The declarations belong here as they aren't machine specific. The old compiler is going away, and it makes no sense to move something out of the way when we'll just move it back for arm64 EFIRT support later. Just ifdef it out for gcc < 4.4. We'll be dropping support for that in 12 most likely and it's a lot easier to delete a couple of lines than to move it around.

Oh, yeah, I'm happy to do that. I got the wrong impression from the previous comment I guess. I'll update this shortly with the compiler version detection.

In D11636#241063, @imp wrote:

The proper solution then is what both kib and I are saying: add the proper ifdef so it isn't included when compiling with the old compiler. The declarations belong here as they aren't machine specific. The old compiler is going away, and it makes no sense to move something out of the way when we'll just move it back for arm64 EFIRT support later. Just ifdef it out for gcc < 4.4. We'll be dropping support for that in 12 most likely and it's a lot easier to delete a couple of lines than to move it around.

Oh, yeah, I'm happy to do that. I got the wrong impression from the previous comment I guess. I'll update this shortly with the compiler version detection.

Thanks. I'd forgotten that we'd included this elsewhere.

rlibby edited edge metadata.

kib/imp feedback: detect old compiler version rather than move decls.

I checked that this compiles with gcc 4.2 WITHOUT_MODULES=efirt, and with clang 4.0 (plain, including efirt). I am still testing gcc > 4.4.

I guess clang also defines __GNUC__ as the clang build failed without the clang check. I don't have a way to check __INTEL_COMPILER, I am just following sys/sys/cdefs.h on that one.

kib/imp feedback: detect old compiler version rather than move decls.

I checked that this compiles with gcc 4.2 WITHOUT_MODULES=efirt, and with clang 4.0 (plain, including efirt). I am still testing gcc > 4.4.

I guess clang also defines __GNUC__ as the clang build failed without the clang check. I don't have a way to check __INTEL_COMPILER, I am just following sys/sys/cdefs.h on that one.

Fair enough. Dollars to donuts says that the intel compiler support is busted, but this won't change that.

This revision is now accepted and ready to land.Jul 18 2017, 5:19 PM
sys/sys/efi.h
135

No, please limit this to amd64/include/efi.h. In other words, if compiler does not support msabi attribute, define the EFIABI_ATTR macro on amd64 as empty.

sys/sys/efi.h
135

Normally, I'd agree with you. However, done this way any accidental use of efi_rt by a compiler that doesn't support it would trigger a compiler failure rather than bad run-time behavior.

sys/sys/efi.h
135

I agree with imp, I think we do want a warning/error if EFIABI_ATTR is not supported and we see such a decl (as in, we don't want to silently generate bad code).

I'm not attached to any particular formulation of the check, I'm happy to iterate if you like. Or, kib or imp, if you want to take the patch over so that the check gets spelled right, feel free, and I can instead just test that it compiles.

sys/sys/efi.h
135

Well, EFIABI_ATTR stuff appeared because I was lazy and decided to not write the trampoline code to call into EFI, relying on compiler.

At very least, your check is arch-specific and must be covered by amd64 visibility. Would it be easier if you put the struct definition also under #ifdef _KERNEL ? Then you might put #error into amd64/include/efi.h perhaps.

sys/sys/efi.h
135

At very least, your check is arch-specific and must be covered by amd64 visibility.

I can move the #define NO_EFIABI_ATTR gunk into sys/amd64/include/efi.h? Or guard it with defined(__amd64__). But I would then still leave the #ifndef NO_EFIABI_ATTR in sys/sys/efi.h. Would that work?

Would it be easier if you put the struct definition also under #ifdef _KERNEL ?

struct defn under #ifdef _KERNEL sounds like a good idea. That fixes the buildworld aspect by itself, but not buildkernel. This could apply to a couple other structures used only by efirt.c too (efi_systbl, efi_cfgtbl) but is not necessarily needed.

Then you might put #error into amd64/include/efi.h perhaps.

I'm not sure I see how that would work, could you maybe clarify?

I'll prepare a patch with the above.

rlibby edited edge metadata.

kib feedback: guard by arch and kernel

Checked buildkernel -DKERNFAST compilation, will check more thoroughly later.

This revision now requires review to proceed.Jul 18 2017, 7:05 PM
sys/amd64/include/efi.h
49

Just not define EFIABI_ATTR at all if compiler does not support msabi.

sys/sys/efi.h
127

Then this becomes #ifdef EFIABI_ATTR.

kib feedback: can implement check with just the one macro

I like your suggestion just to use EFIABI_ATTR. I struggled to make the conditional macro definition not super ugly. I can go back to defining NO_EFIABI_ATTR and then using that as an intermediate (guard with #ifndef NO_EFIABI_ATTR) (or something else?) if you prefer.

Checked clang 4.0 buildkernel, others still in progress.

Modulo the small tweaks I suggested inline, I am fine with this version.

sys/amd64/include/efi.h
40

Get rid of INTEL_COMPILER at all. Also, I am not sure that it is reasonable to use attribute if GNUC is not defined.

This also works, and I like the larger area protect by _KERNEL.

This revision is now accepted and ready to land.Jul 19 2017, 1:52 PM
rlibby edited edge metadata.

kib feedback: don't worry about __INTEL_COMPILER

This revision now requires review to proceed.Jul 19 2017, 5:01 PM
rlibby added inline comments.
sys/amd64/include/efi.h
40

Done. Yeah, I'm not sure either.

In the future we'll hopefully be able to use #if defined(__has_attribute) && __has_attribute(foo_attr) for this kind of thing. But unfortunately ms_abi predates __has_attribute so gcc needs the version check anyway.

This revision is now accepted and ready to land.Jul 19 2017, 5:10 PM
This revision was automatically updated to reflect the committed changes.
rlibby marked an inline comment as done.