Skip to content

aarch64: end the .aros.init directive so its attributes survive - #1044

Draft
metaneutrons wants to merge 1 commit into
aros-development-team:masterfrom
metaneutrons:upstream/aarch64-aros-init-section
Draft

aarch64: end the .aros.init directive so its attributes survive#1044
metaneutrons wants to merge 1 commit into
aros-development-team:masterfrom
metaneutrons:upstream/aarch64-aros-init-section

Conversation

@metaneutrons

@metaneutrons metaneutrons commented Aug 20, 2026

Copy link
Copy Markdown
Contributor

.aros.init holds two things: the entry point, which has to be executable, and a pair of stack pointers, which do not. The section is therefore declared twice — once as "ax" by the inline asm carrying start:, and once through a section attribute on the pointers — and the second declaration must not carry attributes of its own.

TARGET_SECTION_COMMENT exists for exactly that: it ends the directive, so whatever flags the compiler appends become a comment and the section keeps what the entry point asked for. It reaches this file from the mmakefile as

USER_CPPFLAGS := -DTARGET_SECTION_COMMENT=\"$(AROS_SECTION_COMMENT)\"

and arrives empty. The compiler's flags come through, the second declaration says "aw" where the first said "ax", and the assembler refuses it:

Error: changed section attributes for .aros.init

Why it arrives empty

Worth stating precisely, because it decides where the real fix goes — and it is not configure.in. The value belongs to config/features, which does probe for it and picks "#", "@", or falls back to "//". The probe never runs here, because the whole block sits inside

if test "$AROS_TARGET_CPU" = "arm"; then

so every target that is not arm skips it and gets the empty string. A riscv build shows the same from the other side: gen/config/compiler.cfg has AROS_SECTION_COMMENT empty and the features log has no "comment style" line at all.

And widening that test alone would not be enough

There is a second fault in the same probe. Its test program assembles

ldr sp, section_ptr

which is an ARM instruction. On any other target both the "#" and the "@" attempt fail on the instruction rather than on the section attribute, so the probe lands on its "//" fallback whatever the assembler would actually accept — and arch/arm-native/kernel/kernel_startup.c already records that "//" is not a comment for clang's integrated assembler.

Doing this properly therefore means widening the CPU test and making the test program target-neutral, so the assembler decides. That is a change across targets I cannot test, so it is deliberately not attempted here.

This is a workaround

Defined locally, exactly as arch/riscv-native/sifive_u already does in its own kernel_startup.c. sifive_u also has a third variant in boot/mmakefile.src, which passes the -D directly, and the mmakefile line in kernel/mmakefile.src is commented out — which is the clearest evidence that the configure value has been unusable for some time.

I am happy to be told to do it properly instead of this. If the preference is a config/features fix, say so and I will close this in favour of one — it just needs someone who can test the other targets.

Why now

It takes a strict enough assembler to reject this and a toolchain new enough to build at all on a current host. Neither condition held for the aarch64 target until recently.

Testing

Tested on darwin-aarch64 building raspi-aarch64. Not run on hardware, hence draft.

@metaneutrons

Copy link
Copy Markdown
Contributor Author

Independent of #1042 in content, but on a macOS host you need #1042 merged (or applied locally) to get the host tools built at all, and therefore to reproduce this. On Linux it should stand alone.

.aros.init holds two things: the entry point, which has to be
executable, and a pair of stack pointers, which do not. The section is
therefore declared twice - once as "ax" by the inline asm carrying
start:, and once through a section attribute on the pointers - and the
second declaration must not carry attributes of its own.

TARGET_SECTION_COMMENT exists for exactly that. It ends the directive, so
whatever flags the compiler appends become a comment and the section
keeps what the entry point asked for. It reaches this file from the
mmakefile as -DTARGET_SECTION_COMMENT="$(AROS_SECTION_COMMENT)", and
arrives empty, so the flags come through, the second declaration says
"aw" where the first said "ax", and the assembler refuses it:

    Error: changed section attributes for .aros.init

Why it arrives empty is worth stating precisely, because it decides
where the real fix goes. The value is not configure.in's; it belongs to
config/features, which does probe for it and picks "#", "@" or falls back
to "//". The probe never runs here, because the whole block sits inside

    if test "$AROS_TARGET_CPU" = "arm"; then

so every target that is not arm skips it and gets the empty string. A
riscv build on this machine shows the same thing from the other side:
gen/config/compiler.cfg has AROS_SECTION_COMMENT empty and the features
log has no "comment style" line at all.

There is a second fault in the same probe, and it is why widening that
test alone would not be enough. Its test program assembles

    ldr sp, section_ptr

which is an ARM instruction, so on any other target both the "#" and the
"@" attempt fail on the instruction rather than on the section
attribute, and the probe lands on its "//" fallback whatever the
assembler would actually accept. arm-native's own kernel_startup.c
records that "//" is not a comment for clang's integrated assembler.
Doing this properly therefore means widening the CPU test and making the
test program target-neutral, so the assembler decides.

That is a change across targets I cannot test, so it is not attempted
here. This defines the macro locally, exactly as
arch/riscv-native/sifive_u already does in its own kernel_startup.c -
and sifive_u has a third variant of the same workaround in
boot/mmakefile.src, plus the mmakefile -D commented out in
kernel/mmakefile.src, which is the clearest evidence that the configure
value has been unusable for some time. Happy to follow up with the
config/features fix if there is appetite, or to have this rejected in
favour of doing that first.

Only visible now because it takes a strict enough assembler to reject it
and a toolchain new enough to build at all on a current host.

Tested on darwin-aarch64 building raspi-aarch64.
@metaneutrons
metaneutrons force-pushed the upstream/aarch64-aros-init-section branch from b44a4a8 to f470b3f Compare August 20, 2026 15:21
@Kalamatee

Copy link
Copy Markdown
Member

Thanks for writing this up so carefully, and for flagging it as a workaround rather than presenting it as the fix. The observations are right: the probe is gated to arm at config/features.in:1649, and the value does arrive empty everywhere else. The built configs here agree, raspi-armhf-gcc16 has it set to the two-slash value while raspi-aarch64-llvm, opensbi-riscv64-gcc16 and pc-x86_64-gcc16 are all empty.

I think the conclusion drawn from that is off in two ways, and both point at the probe rather than at the arch sources.

arm is not the working case either. Running the probe's own test programs through arm-aros-gcc from a raspi-armhf build gives:

plain, no comment   Error: changed section attributes
                    (correct, a comment real

with " #"           Error: internal_relocatied up
                    (that is the ARM ldr in the test program, not comment syntax)                                     
with " @"           arm-aros-ld: uses VFP register arguments                                                                              (fails at link, again no

Both real candidates are rejected for reasons unrelated to comment syntax, so the probe falls through to its untested two-slash fallback. That is the value armhf ative/kernel/kernel_startup.c` alreadyrecords that it is not a comment for clang's integrated assembler. My invocation did not carry the configure-time flags, so the link error may differ in a reaure does not depend on flags.

**The probe cannot tell a working comment fr only checks that the program compiles andlinks. On x86_64 with GNU as every candidate passes, but the objects differ:

suffix " #"     .aros.startup               rrect
suffix " @"     .aros.startup + .aros.startup@       DATA              separate section
suffix " //"    .aros.startup + .aros.startuparate section
suffix newline+hash
                .aros.startup               rrect

The at-sign and two-slash forms comment nothing out. They create a second section named after the suffix, so the
pointers never land in the section the entry armhf is doing today. It also means widening the CPU test on its own would propagate a silently wrong answer to every target rather than fix anything.

On the local define: which spelling works is toolchain dependent. With the aarch64 clang 11 in my tree the polarity inverts:

suffix " #", " @", " //"    single .aros.startup
suffix newline+hash         .aros.startup + he newline and hash

So the value copied from riscv produces a separate section under that assembler while working under GNU as. Yours may
behave differently, which is the point: thisan written into the source.

There is also a structural concern. An #undnal #defineoverrides whatever the buildsystem supplies, so if the probe is fixed later this file will not pick it up. That is roughly how the value became unusable in the first place:x86_64-pc com and added a guarded fallback,riscv-native/sifive_u` undefined it locally, and this would be the third target to opt out.

A probe-side fix looks smaller than it might appear, and needs no hardware testing because it can validate itself:

  • drop the arm-only gate
  • make the test program target neutral, withrective, since the percent versus at-signspelling is itself target dependent for the same comment character reason being probed
  • judge the resulting object rather than com candidate only when there is a single.aros.startup carrying the entry point's attributes and no section named after the suffix
  • do not fall back to an untested value, fai

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants