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

