Summary: | gcc 4.6.0 generates no code for a function with __attribute__((always_inline)) | ||
---|---|---|---|
Product: | gcc | Reporter: | Richard Weinberger <richard> |
Component: | c | Assignee: | Not yet assigned to anyone <unassigned> |
Status: | RESOLVED INVALID | ||
Severity: | major | CC: | matz |
Priority: | P3 | ||
Version: | 4.6.0 | ||
Target Milestone: | --- | ||
Host: | Target: | ||
Build: | Known to work: | ||
Known to fail: | Last reconfirmed: | 2011-04-15 20:11:31 | |
Attachments: |
Testcase for gcc 4.6.0
objdump of softirq.o objdump of __local_bh_enable preprocessed __local_bh_enable function preprocessed softirq.c |
Description
Richard Weinberger
2011-04-15 14:15:38 UTC
Created attachment 23995 [details]
Testcase for gcc 4.6.0
Because current_thread_info() returns garbage (an address derived from an address of a stack local). Instead using static inline struct thread_info *current_thread_info(void) { struct thread_info *ti; void *p; asm volatile ("" : "=r" (p) : "0" (&ti)); ti = (struct thread_info *) (((unsigned long) p) & ~mask); return ti; } might confuse GCC enough and is still architecture independent. Created attachment 24000 [details]
objdump of softirq.o
(In reply to comment #3) It's not that easy. Your trick solves the problem only for the test case. Within the kernel again no code has been produced. I have the objdump of the __local_bh_enable function attached. See line 86. Sorry for not providing a standalone test. Here you can see the source code of __local_bh_enable, it's a pretty simple function. http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=blob;f=kernel/softirq.c;h=174f976c2874a19f1d06fee972468e2c730bc7f9;hb=HEAD#l134 Thanks, //richard Created attachment 24001 [details]
objdump of __local_bh_enable
Please provide preprocessed source for the translation unit that has the broken function. Created attachment 24006 [details]
preprocessed __local_bh_enable function
Created attachment 24007 [details]
preprocessed softirq.c
You didn't change the current_thread_info carefully enough as per comment #3. It still reads: static inline __attribute__((always_inline)) struct thread_info *current_thread_info(void) { struct thread_info *ti; void *p; unsigned long mask = ((1 << 0) * ((1UL) << 12)) - 1; asm volatile ("" : "=r" (p) : "0" (&ti)); ti = (struct thread_info *) (((unsigned long) &ti) & ~mask); return ti; } You have to make use of 'p' of course. Your return value still is based on &ti. (In reply to comment #10) > You have to make use of 'p' of course. Your return value still is based > on &ti. Damn, you're right! Now gcc produces a functional UML kernel. :-) I fear current_thread_info() is not the only function in the kernel which returns a local stack address. Thanks, //richard |