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.  */

>> 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.

Rasmus

Reply via email to