On Thursday 21. December 2017 00.08.09 Paul Boddie wrote: > On Wednesday 20. December 2017 14.46.12 James Cowgill wrote: > > It would be useful to have a reduced .c file which can reproduce this > > bug and then decide if its a bug in gcc or binutils. > > The offending program is this one: > > https://svn.l4re.org/repos/oc/l4re/trunk/l4/pkg/examples/sys/utcb-ipc/main.c
I've been trying to work towards identifying the code that might cause the problem, but progress has been slower than desired. What happens is that a macro (L4UTIL_THREAD_STATIC_FUNC) is employed to add a kind of wrapper function around an existing function: L4UTIL_THREAD_STATIC_FUNC(thread2) { /* thread2 function body */ } It looks like this when expanded by hand: EXTERN_C_BEGIN void __attribute__((visibility("internal"))) thread2(void); static void __attribute__((used)) thread2_worker_function(void); asm ( ".type thread2, function \n" "thread2 : \n .set push; .set noreorder;" L4UTIL_THREAD_START_SETUP_GP "la $t9, thread2_worker_function\n" " jal $t9 \n" " nop \n" ".set pop" ); EXTERN_C_END static L4_NORETURN void thread2_worker_function(void) { /* thread2 function body */ } It seems that the problem is caused by the declaration of thread2 involving the visibility attribute: void __attribute__((visibility("internal"))) thread2(void); If I replace that declaration with this (as it used to be)... static void thread2(void); ...the error associated with the output goes away (although I get a warning from the compiler about thread2 not being defined, which happens in the assembly language code, of course). Changing the visibility type of thread2 to any of the other acceptable values ("default", "hidden", and so on) does not eliminate the error. Only using a static qualifier does so. The actual code added for the wrapper function isn't so interesting - I guess it has to set up t9 to let position-independent code work, which is actually something I had to change elsewhere in L4Re when compiling with gcc - but I wonder if the introduction of the assembly language object confuses the compiler in some way. Meanwhile, if I put the core of the assembly language within a function, like this... void __attribute__((visibility("internal"))) thread2(void) { asm ( ".set push; .set noreorder;" L4UTIL_THREAD_START_SETUP_GP "la $t9, thread2_worker_function\n" " jal $t9 \n" " nop \n" ".set pop" ); } ...the error is also avoided. Of course, various extra instructions get generated for this wrapper function, which is probably what the assembly language definition of a function is meant to avoid, but the register initialisation and invocation of the "real" function are probably still correct. So might it be the case that the assembly language definition gets "lost" somewhere? Sorry not to be more specific about this: I don't usually have to debug compilers other than my own! Paul