Hi Rasmus,

On Tue, 26 May 2026 at 16:41, Rasmus Villemoes <[email protected]> wrote:
>
> On Wed, May 27 2026, Rasmus Villemoes <[email protected]> wrote:
>
> > On Mon, May 25 2026, Simon Glass <[email protected]> wrote:
> >
> >
> >>> diff --git a/include/linker_lists.h b/include/linker_lists.h
> >>> @@ -23,7 +24,45 @@
> >>> +#define ll_emit_type_info(_list, _type) \
> >>> +     __asm__(                                                \
> >>> +             ".pushsection "ll_info_section_name(_list)',\'aw\'\n'   \
> >>> +             ".type "ll_size_symbol_name(_list)", STT_OBJECT\n"      \
> >>> +             ".size "ll_size_symbol_name(_list)", %c0\n"             \
> >>> +             ".type "ll_align_symbol_name(_list)", STT_OBJECT\n"     \
> >>> +             ".size "ll_align_symbol_name(_list)", %c1\n"            \
> >>> +             ll_size_symbol_name(_list)':\n'                         \
> >>> +             ll_align_symbol_name(_list)':\n'                        \
> >>> +             '.popsection\n'                                         \
> >>> +             : : 'i'(sizeof(_type)), 'i'(__alignof__(_type)))
> >>
> >> This is extended asm (it has operand constraints), so GCC requires it
> >> to be inside a function.
> >
> > Not exactly. My 'info gcc' has this to say:
> >
> >   Similarly to basic ‘asm’, extended ‘asm’ statements may be used both
> >   inside a C function or at file scope ("top-level"), where you can use
> >   this technique to emit assembler directives, define assembly language
> >   macros that can be invoked elsewhere in the file, or write entire
> >   functions in assembly language.  Extended ‘asm’ statements outside of
> >   functions may not use any qualifiers, may not specify clobbers, may
> >   not use ‘%’, ‘+’ or ‘&’ modifiers in constraints and can only use
> >   constraints which don't allow using any register.
> >
> > and since the only constraints I use are those that provide an immediate
> > to the asm, that should be ok (and WorksForMe).
>
> Ah, that's actually new in gcc 15 (I'm using gcc
> 16). https://gcc.gnu.org/gcc-15/changes.html says
>
>   Extended inline assembler statements can now be used with some
>   limitations outside of functions as well.
>
> and explicitly calls out
>
>   "i" (sizeof (struct S))); /* It is possible to pass constants to toplevel 
> asm.  */

Oh OK, actually I am still using gcc 14 locally. It didn't occur to me
that something like this would change in the toolchain! Presumably
clang already has this ability?

>
> >> ll_start_decl()/ll_end_decl() pull this into
> >> ll_emit_start_symbol/ll_emit_end_symbol at file scope - see
> >> SUITE_DECL() in test/cmd_ut.c
> >>
> >> One way out is to drop the operands and have the C side emit a
> >> zero-initialised marker object whose array dimensions encode
> >> sizeof/__alignof__ - e.g. a static struct in a dedicated section whose
> >> two members are sized sizeof(_type) and __alignof__(_type). That costs
> >> a few bytes per list per TU but keeps the trick working at file scope.
>
> Yes, but this is the kind of growth that I wanted to avoid. And if I put
> those marker objects in a section of their own, I'll have to modify each
> and every linker script to preserve that to the u-boot binary, but
> ensure that the objcopy step throws it away.
>
> I'll think about this some more.

Also check my RFC which attempts to do this checking with no changes
to linker lists. It certainly found problems but I suspect your
approach is more powerful and will find more?

Regards,
Simon

Reply via email to