https://gcc.gnu.org/bugzilla/show_bug.cgi?id=40115

Per Lundberg <perlun at gmail dot com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |perlun at gmail dot com

--- Comment #4 from Per Lundberg <perlun at gmail dot com> ---
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 00    movl   $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 0c                mov    %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 24                mov    %ebx,(%esp)
  1085b7:       e8 04 f9 ff ff          call   107ec0 <thread_link>
    number_of_tasks++;
  1085bc:       a1 60 44 11 00          mov    0x114460,%eax
  1085c1:       83 c0 01                add    $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 38                mov    %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 00    movl   $0x113a64,(%esp)
  1085d9:       e8 f2 21 00 00          call   10a7d0 <mutex_kernel_signal>
    mutex_kernel_signal(&memory_mutex);
  1085de:       c7 04 24 0c 44 11 00    movl   $0x11440c,(%esp)
  1085e5:       e8 e6 21 00 00          call   10a7d0 <mutex_kernel_signal>
    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?

Reply via email to