https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66334
Bug ID: 66334
Summary: cleanup block fails to initialize EBX
Product: gcc
Version: 6.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: middle-end
Assignee: unassigned at gcc dot gnu.org
Reporter: hjl.tools at gmail dot com
CC: ubizjak at gmail dot com
Target Milestone: ---
Target: i?86-linux
[hjl@gnu-tools-1 tmp]$ cat x.i
extern int foo (int);
extern void exit (int __status) __attribute__ ((__nothrow__ )) __attribute__
((__noreturn__));
struct __pthread_cleanup_frame
{
void (*__cancel_routine) (void *);
void *__cancel_arg;
int __do_it;
int __cancel_type;
};
extern __inline void
__pthread_cleanup_routine (struct __pthread_cleanup_frame *__frame)
{
if (__frame->__do_it)
__frame->__cancel_routine (__frame->__cancel_arg);
}
static int cl_called;
static void
cl (void *arg)
{
++cl_called;
}
void *
tf_usleep (void *arg)
{
do { struct __pthread_cleanup_frame __clframe __attribute__ ((__cleanup__
(__pthread_cleanup_routine))) = { .__cancel_routine = (cl), .__cancel_arg = (
((void *)0)), .__do_it = 1 };;
foo (arg == ((void *)0) ? (0x7fffffffL * 2UL + 1UL) : 0);
__clframe.__do_it = (0); } while (0);
exit (1);
}
[hjl@gnu-tools-1 tmp]$ /usr/gcc-6.0.0-pie/bin/gcc -fexceptions
-fasynchronous-unwind-tables -m32 -S -O2 /tmp/x.i -fpic
[hjl@gnu-tools-1 tmp]$ cat x.s
.file "x.i"
.section .text.unlikely,"ax",@progbits
.LCOLDB0:
.text
.LHOTB0:
.p2align 4,,15
.type cl, @function
cl:
.LFB1:
.cfi_startproc
call __x86.get_pc_thunk.ax
addl $_GLOBAL_OFFSET_TABLE_, %eax
addl $1, cl_called@GOTOFF(%eax)
ret
.cfi_endproc
.LFE1:
.size cl, .-cl
.section .text.unlikely
.LCOLDE0:
.text
.LHOTE0:
.section .text.unlikely
.LCOLDB1:
.text
.LHOTB1:
.p2align 4,,15
.globl __pthread_cleanup_routine
.type __pthread_cleanup_routine, @function
__pthread_cleanup_routine:
.LFB0:
.cfi_startproc
movl 4(%esp), %eax
movl 8(%eax), %edx
testl %edx, %edx
jne .L5
rep ret
.p2align 4,,10
.p2align 3
.L5:
movl 4(%eax), %edx
movl %edx, 4(%esp)
jmp *(%eax)
.cfi_endproc
.LFE0:
.size __pthread_cleanup_routine, .-__pthread_cleanup_routine
.section .text.unlikely
.LCOLDE1:
.text
.LHOTE1:
.section .text.unlikely
.LCOLDB2:
.text
.LHOTB2:
.p2align 4,,15
.globl tf_usleep
.type tf_usleep, @function
tf_usleep:
.LFB2:
.cfi_startproc
.cfi_personality 0x9b,DW.ref.__gcc_personality_v0
.cfi_lsda 0x1b,.LLSDA2
pushl %ebp
.cfi_def_cfa_offset 8
.cfi_offset 5, -8
xorl %eax, %eax
movl %esp, %ebp
.cfi_def_cfa_register 5
pushl %esi
pushl %ebx
.cfi_offset 6, -12
.cfi_offset 3, -16
movl 8(%ebp), %edx
subl $12, %esp
call __x86.get_pc_thunk.bx
addl $_GLOBAL_OFFSET_TABLE_, %ebx
testl %edx, %edx
sete %al
negl %eax
pushl %eax
.LEHB0:
.cfi_escape 0x2e,0x10
call foo@PLT
.LEHE0:
movl $1, (%esp)
call exit@PLT
.L8:
subl $12, %esp
movl %eax, %esi
pushl $0
call cl
movl %esi, (%esp)
.LEHB1:
call _Unwind_Resume@PLT
.LEHE1:
.cfi_endproc
.LFE2:
.globl __gcc_personality_v0
.section .gcc_except_table,"a",@progbits
.LLSDA2:
.byte 0xff
.byte 0xff
.byte 0x1
.uleb128 .LLSDACSE2-.LLSDACSB2
.LLSDACSB2:
.uleb128 .LEHB0-.LFB2
.uleb128 .LEHE0-.LEHB0
.uleb128 .L8-.LFB2
.uleb128 0
.uleb128 .LEHB1-.LFB2
.uleb128 .LEHE1-.LEHB1
.uleb128 0
.uleb128 0
.LLSDACSE2:
.text
.size tf_usleep, .-tf_usleep
.section .text.unlikely
.LCOLDE2:
.text
.LHOTE2:
.local cl_called
.comm cl_called,4,4
.section
.text.__x86.get_pc_thunk.ax,"axG",@progbits,__x86.get_pc_thunk.ax,comdat
.globl __x86.get_pc_thunk.ax
.hidden __x86.get_pc_thunk.ax
.type __x86.get_pc_thunk.ax, @function
__x86.get_pc_thunk.ax:
.LFB4:
.cfi_startproc
movl (%esp), %eax
ret
.cfi_endproc
.LFE4:
.section
.text.__x86.get_pc_thunk.bx,"axG",@progbits,__x86.get_pc_thunk.bx,comdat
.globl __x86.get_pc_thunk.bx
.hidden __x86.get_pc_thunk.bx
.type __x86.get_pc_thunk.bx, @function
__x86.get_pc_thunk.bx:
.LFB5:
.cfi_startproc
movl (%esp), %ebx
ret
.cfi_endproc
.LFE5:
.hidden DW.ref.__gcc_personality_v0
.weak DW.ref.__gcc_personality_v0
.section
.data.DW.ref.__gcc_personality_v0,"awG",@progbits,DW.ref.__gcc_personality_v0,comdat
.align 4
.type DW.ref.__gcc_personality_v0, @object
.size DW.ref.__gcc_personality_v0, 4
DW.ref.__gcc_personality_v0:
.long __gcc_personality_v0
.ident "GCC: (GNU) 6.0.0 20150528 (experimental)"
.section .note.GNU-stack,"",@progbits
[hjl@gnu-tools-1 tmp]$
The problem is
.L8:
subl $12, %esp
movl %eax, %esi
pushl $0
call cl
movl %esi, (%esp)
.LEHB1:
call _Unwind_Resume@PLT
.LEHE1:
This cleanup block is called via
.section .gcc_except_table,"a",@progbits
.LLSDA2:
.byte 0xff
.byte 0xff
.byte 0x1
.uleb128 .LLSDACSE2-.LLSDACSB2
.LLSDACSB2:
.uleb128 .LEHB0-.LFB2
.uleb128 .LEHE0-.LEHB0
.uleb128 .L8-.LFB2
.uleb128 0
.uleb128 .LEHB1-.LFB2
.uleb128 .LEHE1-.LEHB1
.uleb128 0
.uleb128 0
.LLSDACSE2:
When the cleanup block is entered, EBX isn't valid. In PIC, the cleanup
block must initialize EBX before branching to PLT.