https://gcc.gnu.org/bugzilla/show_bug.cgi?id=40115
Per Lundberg changed:
What|Removed |Added
CC||perlun at gmail dot com
--- Comment #4 from Per Lundberg ---
Hi,
Andrew - with all due respect, this bug should *not* have been closed. It it
still present (at least with gcc 4.7.2). Here is some code (very simplified):
new_tss->eip = (u32) &&new_thread_entry;
new_tss->cr3 = page_directory_physical_page * SIZE_PAGE;
// ...
mutex_kernel_signal(&tss_tree_mutex);
mutex_kernel_signal(&memory_mutex);
new_thread_entry:
DEBUG_MESSAGE(DEBUG, "Enabling interrupts");
cpu_interrupts_enable();
Without -O2, the new_tss->eip gets the proper value of the code line right
below new_thread_entry. With -O2, I get this (objdump -S output):
new_tss->eip = (u32) &&new_thread_entry;
108314: c7 43 20 b1 85 10 00movl $0x1085b1,0x20(%ebx)
Here is where it points to. A number of instructions too early, causing the
code to entirely break down.
*list = tss_list_node;
1085b1: 89 46 0cmov%eax,0xc(%esi)
mutex_kernel_wait(&memory_mutex);
mutex_kernel_wait(&tss_tree_mutex);
process_info = (process_info_type *) new_tss->process_info;
thread_link_list(&process_info->thread_list, new_tss);
thread_link(new_tss);
1085b4: 89 1c 24mov%ebx,(%esp)
1085b7: e8 04 f9 ff ff call 107ec0
number_of_tasks++;
1085bc: a1 60 44 11 00 mov0x114460,%eax
1085c1: 83 c0 01add$0x1,%eax
1085c4: a3 60 44 11 00 mov%eax,0x114460
static inline u32 cpu_get_esp(void)
{
u32 return_value;
asm volatile ("movl %%esp, %0"
1085c9: 89 e0 mov%esp,%eax
new_tss->esp = cpu_get_esp();
1085cb: 89 43 38mov%eax,0x38(%ebx)
process_info->number_of_threads++;
1085ce: 83 46 10 01 addl $0x1,0x10(%esi)
mutex_kernel_signal(&tss_tree_mutex);
1085d2: c7 04 24 64 3a 11 00movl $0x113a64,(%esp)
1085d9: e8 f2 21 00 00 call 10a7d0
mutex_kernel_signal(&memory_mutex);
1085de: c7 04 24 0c 44 11 00movl $0x11440c,(%esp)
1085e5: e8 e6 21 00 00 call 10a7d0
asm ("cli");
}
static inline void cpu_interrupts_enable(void)
{
asm ("sti");
1085ea: fb sti
(the last instruction here is where it *should* have pointed at. :)
This used to work with older versions of gcc (last known "good" version is
something like 2.95), so obviously something relating to goto labels/O2 has
gotten broken during the years.
IMHO, this is a clear bug. In my case, I use the address for "jumping" but with
indirect jumping (in the new thread being created). Would you say that this is
not supported?
Does direct jumping (i.e. goto *&&foo) even work at the moment, with -O2? Are
there any unit tests or similar for this?