Re: __initcall macros and C token pasting

From: viro
Date: Sat Sep 25 2004 - 13:35:28 EST


On Sat, Sep 25, 2004 at 01:57:37PM -0400, Jon Smirl wrote:
> #define DRM(x) r128_##x
> module_init( DRM(init) );
>
> #define __define_initcall(level,fn) \
> static initcall_t __initcall_##fn __attribute_used__ \
> __attribute__((__section__(".initcall" level ".init"))) = fn
>
> This gives the error:
> {standard input}: Assembler messages:
> {standard input}:104: Error: junk at end of line, first unrecognized
> character is `('
>
> I believe this is because the C macro is not being expanded in the
> assembler context of the section with the fn assignment.

BS. In non-modular case (quoted above) DRM(init) will be expanded _long_
before you get to __define_initcall() expansion.

In the modular case, OTOH, it will _not_. There you get
module_init(DRM(init)) =>
static inline initcall_t __inittest(void) { return initfn; } int init_module(void) __attribute__((alias("DRM(init)")));
since # suppresses expansion of argument. Which leaves you with
.globl init_module
.set init_module, DRM(init)
in assembler output. Which is not going to make as(1) happy.

> Any ideas on how to fix this?

To fix what, exactly? Your beliefs? DRM abuse of cpp? For the former I'd
suggest learning C (or learning to use -S to see what exactly as(1) gets to
deal with). For the latter...

#define DRM_abuses_cpp_too_fscking_much(x) module_init(x)
DRM_abuses_cpp_too_fscking_much(DRM(init))

will force the expansion before it gets to module_init(), which will result in
acceptable alias.
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/