Replace FSF snail mail address with URLs.
[glibc.git] / nptl / sysdeps / unix / sysv / linux / i386 / i486 / pthread_cond_timedwait.S
blobff3da370dca10e6360584c304a46508a68813aad
1 /* Copyright (C) 2002-2004,2006-2007,2009,2010 Free Software Foundation, Inc.
2    This file is part of the GNU C Library.
3    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
5    The GNU C Library is free software; you can redistribute it and/or
6    modify it under the terms of the GNU Lesser General Public
7    License as published by the Free Software Foundation; either
8    version 2.1 of the License, or (at your option) any later version.
10    The GNU C Library is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13    Lesser General Public License for more details.
15    You should have received a copy of the GNU Lesser General Public
16    License along with the GNU C Library; if not, see
17    <http://www.gnu.org/licenses/>.  */
19 #include <sysdep.h>
20 #include <shlib-compat.h>
21 #include <lowlevellock.h>
22 #include <lowlevelcond.h>
23 #include <pthread-errnos.h>
24 #include <pthread-pi-defines.h>
25 #include <kernel-features.h>
28         .text
30 /* int pthread_cond_timedwait (pthread_cond_t *cond, pthread_mutex_t *mutex,
31                                const struct timespec *abstime)  */
32         .globl  __pthread_cond_timedwait
33         .type   __pthread_cond_timedwait, @function
34         .align  16
35 __pthread_cond_timedwait:
36 .LSTARTCODE:
37         cfi_startproc
38 #ifdef SHARED
39         cfi_personality(DW_EH_PE_pcrel | DW_EH_PE_sdata4 | DW_EH_PE_indirect,
40                         DW.ref.__gcc_personality_v0)
41         cfi_lsda(DW_EH_PE_pcrel | DW_EH_PE_sdata4, .LexceptSTART)
42 #else
43         cfi_personality(DW_EH_PE_udata4, __gcc_personality_v0)
44         cfi_lsda(DW_EH_PE_udata4, .LexceptSTART)
45 #endif
47         pushl   %ebp
48         cfi_adjust_cfa_offset(4)
49         cfi_rel_offset(%ebp, 0)
50         pushl   %edi
51         cfi_adjust_cfa_offset(4)
52         cfi_rel_offset(%edi, 0)
53         pushl   %esi
54         cfi_adjust_cfa_offset(4)
55         cfi_rel_offset(%esi, 0)
56         pushl   %ebx
57         cfi_adjust_cfa_offset(4)
58         cfi_rel_offset(%ebx, 0)
60         movl    20(%esp), %ebx
61         movl    28(%esp), %ebp
63         cmpl    $1000000000, 4(%ebp)
64         movl    $EINVAL, %eax
65         jae     18f
67         /* Get internal lock.  */
68         movl    $1, %edx
69         xorl    %eax, %eax
70         LOCK
71 #if cond_lock == 0
72         cmpxchgl %edx, (%ebx)
73 #else
74         cmpxchgl %edx, cond_lock(%ebx)
75 #endif
76         jnz     1f
78         /* Store the reference to the mutex.  If there is already a
79            different value in there this is a bad user bug.  */
80 2:      cmpl    $-1, dep_mutex(%ebx)
81         movl    24(%esp), %eax
82         je      17f
83         movl    %eax, dep_mutex(%ebx)
85         /* Unlock the mutex.  */
86 17:     xorl    %edx, %edx
87         call    __pthread_mutex_unlock_usercnt
89         testl   %eax, %eax
90         jne     16f
92         addl    $1, total_seq(%ebx)
93         adcl    $0, total_seq+4(%ebx)
94         addl    $1, cond_futex(%ebx)
95         addl    $(1 << nwaiters_shift), cond_nwaiters(%ebx)
97 #define FRAME_SIZE 32
98         subl    $FRAME_SIZE, %esp
99         cfi_adjust_cfa_offset(FRAME_SIZE)
100         cfi_remember_state
102         /* Get and store current wakeup_seq value.  */
103         movl    wakeup_seq(%ebx), %edi
104         movl    wakeup_seq+4(%ebx), %edx
105         movl    broadcast_seq(%ebx), %eax
106         movl    %edi, 12(%esp)
107         movl    %edx, 16(%esp)
108         movl    %eax, 20(%esp)
110         /* Reset the pi-requeued flag.  */
111 8:      movl    $0, 24(%esp)
112         /* Get the current time.  */
113         movl    %ebx, %edx
114 #ifdef __NR_clock_gettime
115         /* Get the clock number.  */
116         movl    cond_nwaiters(%ebx), %ebx
117         andl    $((1 << nwaiters_shift) - 1), %ebx
118         /* Only clocks 0 and 1 are allowed so far.  Both are handled in the
119            kernel.  */
120         leal    4(%esp), %ecx
121         movl    $__NR_clock_gettime, %eax
122         ENTER_KERNEL
123 # ifndef __ASSUME_POSIX_TIMERS
124         cmpl    $-ENOSYS, %eax
125         je      19f
126 # endif
127         movl    %edx, %ebx
129         /* Compute relative timeout.  */
130         movl    (%ebp), %ecx
131         movl    4(%ebp), %edx
132         subl    4(%esp), %ecx
133         subl    8(%esp), %edx
134 #else
135         /* Get the current time.  */
136         leal    4(%esp), %ebx
137         xorl    %ecx, %ecx
138         movl    $__NR_gettimeofday, %eax
139         ENTER_KERNEL
140         movl    %edx, %ebx
142         /* Compute relative timeout.  */
143         movl    8(%esp), %eax
144         movl    $1000, %edx
145         mul     %edx            /* Milli seconds to nano seconds.  */
146         movl    (%ebp), %ecx
147         movl    4(%ebp), %edx
148         subl    4(%esp), %ecx
149         subl    %eax, %edx
150 #endif
151         jns     12f
152         addl    $1000000000, %edx
153         subl    $1, %ecx
154 12:     testl   %ecx, %ecx
155         movl    $-ETIMEDOUT, %esi
156         js      6f
158         /* Store relative timeout.  */
159 21:     movl    %ecx, 4(%esp)
160         movl    %edx, 8(%esp)
162         movl    cond_futex(%ebx), %edi
163         movl    %edi, 28(%esp)
165         /* Unlock.  */
166         LOCK
167 #if cond_lock == 0
168         subl    $1, (%ebx)
169 #else
170         subl    $1, cond_lock(%ebx)
171 #endif
172         jne     3f
174 .LcleanupSTART:
175 4:      call    __pthread_enable_asynccancel
176         movl    %eax, (%esp)
178 #if FUTEX_PRIVATE_FLAG > 255
179         xorl    %ecx, %ecx
180 #endif
181         cmpl    $-1, dep_mutex(%ebx)
182         sete    %cl
183         je      40f
185         movl    dep_mutex(%ebx), %edi
186         /* Requeue to a non-robust PI mutex if the PI bit is set and
187            the robust bit is not set.  */
188         movl    MUTEX_KIND(%edi), %eax
189         andl    $(ROBUST_BIT|PI_BIT), %eax
190         cmpl    $PI_BIT, %eax
191         jne     40f
193         movl    $(FUTEX_WAIT_REQUEUE_PI|FUTEX_PRIVATE_FLAG), %ecx
194         /* The following only works like this because we only support
195            two clocks, represented using a single bit.  */
196         testl   $1, cond_nwaiters(%ebx)
197         /* XXX Need to implement using sete instead of a jump.  */
198         jne     42f
199         orl     $FUTEX_CLOCK_REALTIME, %ecx
201         /* Requeue-PI uses absolute timeout */
202 42:     leal    (%ebp), %esi
203         movl    28(%esp), %edx
204         addl    $cond_futex, %ebx
205         movl    $SYS_futex, %eax
206         ENTER_KERNEL
207         subl    $cond_futex, %ebx
208         movl    %eax, %esi
209         /* Set the pi-requeued flag only if the kernel has returned 0. The
210            kernel does not hold the mutex on ETIMEDOUT or any other error.  */
211         cmpl    $0, %eax
212         sete    24(%esp)
213         je      41f
215         /* Normal and PI futexes dont mix. Use normal futex functions only
216            if the kernel does not support the PI futex functions.  */
217         cmpl    $-ENOSYS, %eax
218         jne     41f
219         xorl    %ecx, %ecx
221 40:     subl    $1, %ecx
222 #ifdef __ASSUME_PRIVATE_FUTEX
223         andl    $FUTEX_PRIVATE_FLAG, %ecx
224 #else
225         andl    %gs:PRIVATE_FUTEX, %ecx
226 #endif
227 #if FUTEX_WAIT != 0
228         addl    $FUTEX_WAIT, %ecx
229 #endif
230         leal    4(%esp), %esi
231         movl    28(%esp), %edx
232         addl    $cond_futex, %ebx
233 .Ladd_cond_futex:
234         movl    $SYS_futex, %eax
235         ENTER_KERNEL
236         subl    $cond_futex, %ebx
237 .Lsub_cond_futex:
238         movl    %eax, %esi
240 41:     movl    (%esp), %eax
241         call    __pthread_disable_asynccancel
242 .LcleanupEND:
244         /* Lock.  */
245         movl    $1, %edx
246         xorl    %eax, %eax
247         LOCK
248 #if cond_lock == 0
249         cmpxchgl %edx, (%ebx)
250 #else
251         cmpxchgl %edx, cond_lock(%ebx)
252 #endif
253         jnz     5f
255 6:      movl    broadcast_seq(%ebx), %eax
256         cmpl    20(%esp), %eax
257         jne     23f
259         movl    woken_seq(%ebx), %eax
260         movl    woken_seq+4(%ebx), %ecx
262         movl    wakeup_seq(%ebx), %edi
263         movl    wakeup_seq+4(%ebx), %edx
265         cmpl    16(%esp), %edx
266         jne     7f
267         cmpl    12(%esp), %edi
268         je      15f
270 7:      cmpl    %ecx, %edx
271         jne     9f
272         cmp     %eax, %edi
273         jne     9f
275 15:     cmpl    $-ETIMEDOUT, %esi
276         jne     8b
278         addl    $1, wakeup_seq(%ebx)
279         adcl    $0, wakeup_seq+4(%ebx)
280         addl    $1, cond_futex(%ebx)
281         movl    $ETIMEDOUT, %esi
282         jmp     14f
284 23:     xorl    %esi, %esi
285         jmp     24f
287 9:      xorl    %esi, %esi
288 14:     addl    $1, woken_seq(%ebx)
289         adcl    $0, woken_seq+4(%ebx)
291 24:     subl    $(1 << nwaiters_shift), cond_nwaiters(%ebx)
293         /* Wake up a thread which wants to destroy the condvar object.  */
294         movl    total_seq(%ebx), %eax
295         andl    total_seq+4(%ebx), %eax
296         cmpl    $0xffffffff, %eax
297         jne     25f
298         movl    cond_nwaiters(%ebx), %eax
299         andl    $~((1 << nwaiters_shift) - 1), %eax
300         jne     25f
302         addl    $cond_nwaiters, %ebx
303         movl    $SYS_futex, %eax
304 #if FUTEX_PRIVATE_FLAG > 255
305         xorl    %ecx, %ecx
306 #endif
307         cmpl    $-1, dep_mutex-cond_nwaiters(%ebx)
308         sete    %cl
309         subl    $1, %ecx
310 #ifdef __ASSUME_PRIVATE_FUTEX
311         andl    $FUTEX_PRIVATE_FLAG, %ecx
312 #else
313         andl    %gs:PRIVATE_FUTEX, %ecx
314 #endif
315         addl    $FUTEX_WAKE, %ecx
316         movl    $1, %edx
317         ENTER_KERNEL
318         subl    $cond_nwaiters, %ebx
320 25:     LOCK
321 #if cond_lock == 0
322         subl    $1, (%ebx)
323 #else
324         subl    $1, cond_lock(%ebx)
325 #endif
326         jne     10f
328 11:     movl    24+FRAME_SIZE(%esp), %eax
329         /* With requeue_pi, the mutex lock is held in the kernel.  */
330         movl    24(%esp), %ecx
331         testl   %ecx, %ecx
332         jnz     27f
334         call    __pthread_mutex_cond_lock
335 26:     addl    $FRAME_SIZE, %esp
336         cfi_adjust_cfa_offset(-FRAME_SIZE);
338         /* We return the result of the mutex_lock operation if it failed.  */
339         testl   %eax, %eax
340 #ifdef HAVE_CMOV
341         cmovel  %esi, %eax
342 #else
343         jne     22f
344         movl    %esi, %eax
346 #endif
348 18:     popl    %ebx
349         cfi_adjust_cfa_offset(-4)
350         cfi_restore(%ebx)
351         popl    %esi
352         cfi_adjust_cfa_offset(-4)
353         cfi_restore(%esi)
354         popl    %edi
355         cfi_adjust_cfa_offset(-4)
356         cfi_restore(%edi)
357         popl    %ebp
358         cfi_adjust_cfa_offset(-4)
359         cfi_restore(%ebp)
361         ret
363         cfi_restore_state
365 27:     call    __pthread_mutex_cond_lock_adjust
366         xorl    %eax, %eax
367         jmp     26b
369         cfi_adjust_cfa_offset(-FRAME_SIZE);
370         /* Initial locking failed.  */
372 #if cond_lock == 0
373         movl    %ebx, %edx
374 #else
375         leal    cond_lock(%ebx), %edx
376 #endif
377 #if (LLL_SHARED-LLL_PRIVATE) > 255
378         xorl    %ecx, %ecx
379 #endif
380         cmpl    $-1, dep_mutex(%ebx)
381         setne   %cl
382         subl    $1, %ecx
383         andl    $(LLL_SHARED-LLL_PRIVATE), %ecx
384 #if LLL_PRIVATE != 0
385         addl    $LLL_PRIVATE, %ecx
386 #endif
387         call    __lll_lock_wait
388         jmp     2b
390         /* The initial unlocking of the mutex failed.  */
392         LOCK
393 #if cond_lock == 0
394         subl    $1, (%ebx)
395 #else
396         subl    $1, cond_lock(%ebx)
397 #endif
398         jne     18b
400         movl    %eax, %esi
401 #if cond_lock == 0
402         movl    %ebx, %eax
403 #else
404         leal    cond_lock(%ebx), %eax
405 #endif
406 #if (LLL_SHARED-LLL_PRIVATE) > 255
407         xorl    %ecx, %ecx
408 #endif
409         cmpl    $-1, dep_mutex(%ebx)
410         setne   %cl
411         subl    $1, %ecx
412         andl    $(LLL_SHARED-LLL_PRIVATE), %ecx
413 #if LLL_PRIVATE != 0
414         addl    $LLL_PRIVATE, %ecx
415 #endif
416         call    __lll_unlock_wake
418         movl    %esi, %eax
419         jmp     18b
421         cfi_adjust_cfa_offset(FRAME_SIZE)
423         /* Unlock in loop requires wakeup.  */
425 #if cond_lock == 0
426         movl    %ebx, %eax
427 #else
428         leal    cond_lock(%ebx), %eax
429 #endif
430 #if (LLL_SHARED-LLL_PRIVATE) > 255
431         xorl    %ecx, %ecx
432 #endif
433         cmpl    $-1, dep_mutex(%ebx)
434         setne   %cl
435         subl    $1, %ecx
436         andl    $(LLL_SHARED-LLL_PRIVATE), %ecx
437 #if LLL_PRIVATE != 0
438         addl    $LLL_PRIVATE, %ecx
439 #endif
440         call    __lll_unlock_wake
441         jmp     4b
443         /* Locking in loop failed.  */
445 #if cond_lock == 0
446         movl    %ebx, %edx
447 #else
448         leal    cond_lock(%ebx), %edx
449 #endif
450 #if (LLL_SHARED-LLL_PRIVATE) > 255
451         xorl    %ecx, %ecx
452 #endif
453         cmpl    $-1, dep_mutex(%ebx)
454         setne   %cl
455         subl    $1, %ecx
456         andl    $(LLL_SHARED-LLL_PRIVATE), %ecx
457 #if LLL_PRIVATE != 0
458         addl    $LLL_PRIVATE, %ecx
459 #endif
460         call    __lll_lock_wait
461         jmp     6b
463         /* Unlock after loop requires wakeup.  */
465 #if cond_lock == 0
466         movl    %ebx, %eax
467 #else
468         leal    cond_lock(%ebx), %eax
469 #endif
470 #if (LLL_SHARED-LLL_PRIVATE) > 255
471         xorl    %ecx, %ecx
472 #endif
473         cmpl    $-1, dep_mutex(%ebx)
474         setne   %cl
475         subl    $1, %ecx
476         andl    $(LLL_SHARED-LLL_PRIVATE), %ecx
477 #if LLL_PRIVATE != 0
478         addl    $LLL_PRIVATE, %ecx
479 #endif
480         call    __lll_unlock_wake
481         jmp     11b
483 #if defined __NR_clock_gettime && !defined __ASSUME_POSIX_TIMERS
484         /* clock_gettime not available.  */
485 19:     leal    4(%esp), %ebx
486         xorl    %ecx, %ecx
487         movl    $__NR_gettimeofday, %eax
488         ENTER_KERNEL
489         movl    %edx, %ebx
491         /* Compute relative timeout.  */
492         movl    8(%esp), %eax
493         movl    $1000, %edx
494         mul     %edx            /* Milli seconds to nano seconds.  */
495         movl    (%ebp), %ecx
496         movl    4(%ebp), %edx
497         subl    4(%esp), %ecx
498         subl    %eax, %edx
499         jns     20f
500         addl    $1000000000, %edx
501         subl    $1, %ecx
502 20:     testl   %ecx, %ecx
503         movl    $-ETIMEDOUT, %esi
504         js      6b
505         jmp     21b
506 #endif
507         .size   __pthread_cond_timedwait, .-__pthread_cond_timedwait
508 versioned_symbol (libpthread, __pthread_cond_timedwait, pthread_cond_timedwait,
509                   GLIBC_2_3_2)
512         .type   __condvar_tw_cleanup2, @function
513 __condvar_tw_cleanup2:
514         subl    $cond_futex, %ebx
515         .size   __condvar_tw_cleanup2, .-__condvar_tw_cleanup2
516         .type   __condvar_tw_cleanup, @function
517 __condvar_tw_cleanup:
518         movl    %eax, %esi
520         /* Get internal lock.  */
521         movl    $1, %edx
522         xorl    %eax, %eax
523         LOCK
524 #if cond_lock == 0
525         cmpxchgl %edx, (%ebx)
526 #else
527         cmpxchgl %edx, cond_lock(%ebx)
528 #endif
529         jz      1f
531 #if cond_lock == 0
532         movl    %ebx, %edx
533 #else
534         leal    cond_lock(%ebx), %edx
535 #endif
536 #if (LLL_SHARED-LLL_PRIVATE) > 255
537         xorl    %ecx, %ecx
538 #endif
539         cmpl    $-1, dep_mutex(%ebx)
540         setne   %cl
541         subl    $1, %ecx
542         andl    $(LLL_SHARED-LLL_PRIVATE), %ecx
543 #if LLL_PRIVATE != 0
544         addl    $LLL_PRIVATE, %ecx
545 #endif
546         call    __lll_lock_wait
548 1:      movl    broadcast_seq(%ebx), %eax
549         cmpl    20(%esp), %eax
550         jne     3f
552         /* We increment the wakeup_seq counter only if it is lower than
553            total_seq.  If this is not the case the thread was woken and
554            then canceled.  In this case we ignore the signal.  */
555         movl    total_seq(%ebx), %eax
556         movl    total_seq+4(%ebx), %edi
557         cmpl    wakeup_seq+4(%ebx), %edi
558         jb      6f
559         ja      7f
560         cmpl    wakeup_seq(%ebx), %eax
561         jbe     7f
563 6:      addl    $1, wakeup_seq(%ebx)
564         adcl    $0, wakeup_seq+4(%ebx)
565         addl    $1, cond_futex(%ebx)
567 7:      addl    $1, woken_seq(%ebx)
568         adcl    $0, woken_seq+4(%ebx)
570 3:      subl    $(1 << nwaiters_shift), cond_nwaiters(%ebx)
572         /* Wake up a thread which wants to destroy the condvar object.  */
573         xorl    %edi, %edi
574         movl    total_seq(%ebx), %eax
575         andl    total_seq+4(%ebx), %eax
576         cmpl    $0xffffffff, %eax
577         jne     4f
578         movl    cond_nwaiters(%ebx), %eax
579         andl    $~((1 << nwaiters_shift) - 1), %eax
580         jne     4f
582         addl    $cond_nwaiters, %ebx
583         movl    $SYS_futex, %eax
584 #if FUTEX_PRIVATE_FLAG > 255
585         xorl    %ecx, %ecx
586 #endif
587         cmpl    $-1, dep_mutex-cond_nwaiters(%ebx)
588         sete    %cl
589         subl    $1, %ecx
590 #ifdef __ASSUME_PRIVATE_FUTEX
591         andl    $FUTEX_PRIVATE_FLAG, %ecx
592 #else
593         andl    %gs:PRIVATE_FUTEX, %ecx
594 #endif
595         addl    $FUTEX_WAKE, %ecx
596         movl    $1, %edx
597         ENTER_KERNEL
598         subl    $cond_nwaiters, %ebx
599         movl    $1, %edi
601 4:      LOCK
602 #if cond_lock == 0
603         subl    $1, (%ebx)
604 #else
605         subl    $1, cond_lock(%ebx)
606 #endif
607         je      2f
609 #if cond_lock == 0
610         movl    %ebx, %eax
611 #else
612         leal    cond_lock(%ebx), %eax
613 #endif
614 #if (LLL_SHARED-LLL_PRIVATE) > 255
615         xorl    %ecx, %ecx
616 #endif
617         cmpl    $-1, dep_mutex(%ebx)
618         setne   %cl
619         subl    $1, %ecx
620         andl    $(LLL_SHARED-LLL_PRIVATE), %ecx
621 #if LLL_PRIVATE != 0
622         addl    $LLL_PRIVATE, %ecx
623 #endif
624         call    __lll_unlock_wake
626         /* Wake up all waiters to make sure no signal gets lost.  */
627 2:      testl   %edi, %edi
628         jnz     5f
629         addl    $cond_futex, %ebx
630 #if FUTEX_PRIVATE_FLAG > 255
631         xorl    %ecx, %ecx
632 #endif
633         cmpl    $-1, dep_mutex-cond_futex(%ebx)
634         sete    %cl
635         subl    $1, %ecx
636 #ifdef __ASSUME_PRIVATE_FUTEX
637         andl    $FUTEX_PRIVATE_FLAG, %ecx
638 #else
639         andl    %gs:PRIVATE_FUTEX, %ecx
640 #endif
641         addl    $FUTEX_WAKE, %ecx
642         movl    $SYS_futex, %eax
643         movl    $0x7fffffff, %edx
644         ENTER_KERNEL
646 5:      movl    24+FRAME_SIZE(%esp), %eax
647         call    __pthread_mutex_cond_lock
649         movl    %esi, (%esp)
650 .LcallUR:
651         call    _Unwind_Resume
652         hlt
653 .LENDCODE:
654         cfi_endproc
655         .size   __condvar_tw_cleanup, .-__condvar_tw_cleanup
658         .section .gcc_except_table,"a",@progbits
659 .LexceptSTART:
660         .byte   DW_EH_PE_omit                   # @LPStart format (omit)
661         .byte   DW_EH_PE_omit                   # @TType format (omit)
662         .byte   DW_EH_PE_sdata4                 # call-site format
663                                                 # DW_EH_PE_sdata4
664         .uleb128 .Lcstend-.Lcstbegin
665 .Lcstbegin:
666         .long   .LcleanupSTART-.LSTARTCODE
667         .long   .Ladd_cond_futex-.LcleanupSTART
668         .long   __condvar_tw_cleanup-.LSTARTCODE
669         .uleb128  0
670         .long   .Ladd_cond_futex-.LSTARTCODE
671         .long   .Lsub_cond_futex-.Ladd_cond_futex
672         .long   __condvar_tw_cleanup2-.LSTARTCODE
673         .uleb128  0
674         .long   .Lsub_cond_futex-.LSTARTCODE
675         .long   .LcleanupEND-.Lsub_cond_futex
676         .long   __condvar_tw_cleanup-.LSTARTCODE
677         .uleb128  0
678         .long   .LcallUR-.LSTARTCODE
679         .long   .LENDCODE-.LcallUR
680         .long   0
681         .uleb128  0
682 .Lcstend:
685 #ifdef SHARED
686         .hidden DW.ref.__gcc_personality_v0
687         .weak   DW.ref.__gcc_personality_v0
688         .section .gnu.linkonce.d.DW.ref.__gcc_personality_v0,"aw",@progbits
689         .align  4
690         .type   DW.ref.__gcc_personality_v0, @object
691         .size   DW.ref.__gcc_personality_v0, 4
692 DW.ref.__gcc_personality_v0:
693         .long   __gcc_personality_v0
694 #endif