On Mon, Sep 13, 2021 at 5:58 PM Stephen Rothwell <sfr@xxxxxxxxxxxxxxxx> wrote: > > > I have no idea why it then complains about removal of the GCC4 macros. > > Me neither :-( Ooh. So I'm looking at gcc sources, just to see if "maybe this thing is somehow conditional". And bingo. In cpp_init_special_builtins(), gcc does if (b->value == BT_HAS_ATTRIBUTE && (CPP_OPTION (pfile, lang) == CLK_ASM || pfile->cb.has_attribute == NULL)) continue; which basically says that if we're pre-processing an ASM file, the magical pre-processor symbol for __has_attribute is not defined. I'm not sure what that 'pfile->cb.has_attribute == NULL' thing means, but the libcpp/ChangeLog file also mentions this: (cpp_init_special_builtins): Don't initialize __has_attribute or __has_cpp_attribute if CLK_ASM or pfile->cb.has_attribute is NULL. So this is a very very special magical thing: if building an *.S file, __has_attribute magically goes away. And sure enough, that's exactly what is going on. It's during that build of arch/powerpc/boot/crt0.S, and the reason this hits on powerpc is that in arch/powerpc/boot/Makefile we have -include $(srctree)/include/linux/compiler_attributes.h as part of BOOTCFLAGS, and then it does BOOTAFLAGS := -D__ASSEMBLY__ $(BOOTCFLAGS) -nostdinc to also include that header file when building ASM files. And our old GCC4 code silently hid this all, and made it work, because for a *.S file you'd then (completely illogically) get those fake gcc-4 attribute macros. Now, do I know *why* that ppc Makefile it does that? No. Neither do I know why the gcc people decided to just make ASM preprocessor so special. But at least I understand how the odd error happens. This was too damn subtle. When you have to go read the compiler sources to figure things like this out, you know you are too deep. The fix should be pretty simple: remove almost all of BOOTCFLAGS from BOOTAFLAGS. But sadly, "almost all" isn't "all". There's the include path stuff, there's the ABI and endianness, and there's the bit size ones. So I think the fix is either (a) remove that -include $(srctree)/include/linux/compiler_attributes.h thing entirely, and add it as required to the C files. OR (b) something like this ENTIRELY UNTESTED ATTACHED patch I will leave it to the powerpc people to make the right choice. Linus
arch/powerpc/boot/Makefile | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/arch/powerpc/boot/Makefile b/arch/powerpc/boot/Makefile index 6900d0ac2421..9bcf62d65509 100644 --- a/arch/powerpc/boot/Makefile +++ b/arch/powerpc/boot/Makefile @@ -32,28 +32,30 @@ else BOOTAR := $(AR) endif -BOOTCFLAGS := -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs \ - -fno-strict-aliasing -O2 -msoft-float -mno-altivec -mno-vsx \ - -pipe -fomit-frame-pointer -fno-builtin -fPIC -nostdinc \ - -include $(srctree)/include/linux/compiler_attributes.h \ - $(LINUXINCLUDE) +BOOTCOREFLAGS := $(LINUXINCLUDE) ifdef CONFIG_PPC64_BOOT_WRAPPER -BOOTCFLAGS += -m64 +BOOTCOREFLAGS += -m64 else -BOOTCFLAGS += -m32 +BOOTCOREFLAGS += -m32 endif -BOOTCFLAGS += -isystem $(shell $(BOOTCC) -print-file-name=include) +BOOTCOREFLAGS += -isystem $(shell $(BOOTCC) -print-file-name=include) ifdef CONFIG_CPU_BIG_ENDIAN -BOOTCFLAGS += -mbig-endian +BOOTCOREFLAGS += -mbig-endian else -BOOTCFLAGS += -mlittle-endian -BOOTCFLAGS += $(call cc-option,-mabi=elfv2) +BOOTCOREFLAGS += -mlittle-endian +BOOTCOREFLAGS += $(call cc-option,-mabi=elfv2) endif -BOOTAFLAGS := -D__ASSEMBLY__ $(BOOTCFLAGS) -nostdinc +BOOTCFLAGS := -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs \ + -fno-strict-aliasing -O2 -msoft-float -mno-altivec -mno-vsx \ + -pipe -fomit-frame-pointer -fno-builtin -fPIC -nostdinc \ + -include $(srctree)/include/linux/compiler_attributes.h \ + $(BOOTCOREFLAGS) + +BOOTAFLAGS := -D__ASSEMBLY__ $(BOOTCOREFLAGS) -nostdinc BOOTARFLAGS := -crD