This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
[patch] Avoid "anonymous" code in pthread_spin_lock
- From: ppluzhnikov at google dot com (Paul Pluzhnikov)
- To: libc-alpha at sourceware dot org
- Cc: ppluzhnikov at google dot com
- Date: Wed, 25 Apr 2012 16:10:25 -0700 (PDT)
- Subject: [patch] Avoid "anonymous" code in pthread_spin_lock
Greetings,
Due to use of .subsection ASM directive in pthread_spin_lock, the code
in that subsection ends up in "anonymous" code region, outside of any
glibc function.
This can be seen in e.g. GDB:
(gdb) p &pthread_spin_lock
$1 = (int (*)(pthread_spinlock_t *)) 0xcb00 <pthread_spin_lock>
(gdb) x/11i 0xcb00
0xcb00 <pthread_spin_lock>: lock decl (%rdi)
0xcb03 <pthread_spin_lock+3>: jne 0xcb10
0xcb05 <pthread_spin_lock+5>: xor %eax,%eax
0xcb07 <pthread_spin_lock+7>: retq
0xcb08: nopl 0x0(%rax,%rax,1)
0xcb10: pause
0xcb12: cmpl $0x0,(%rdi)
0xcb15: jg 0xcb00 <pthread_spin_lock>
0xcb17: jmp 0xcb10
0xcb19: nopl 0x0(%rax)
0xcb20 <pthread_spin_trylock>: mov $0x1,%eax
The instructions in the [0xcb08, 0xcb19] range are in no-man's land.
This is a problem for end-users when they attach GDB and land there,
and also for profilers which can't properly symbolize that address range.
Attached patch introduces a local label, changing above picture to:
(gdb) x/11i 0xcb00
0xcb00 <pthread_spin_lock>: lock decl (%rdi)
0xcb03 <pthread_spin_lock+3>: jne 0xcb10 <_L_pthread_spin_lock>
0xcb05 <pthread_spin_lock+5>: xor %eax,%eax
0xcb07 <pthread_spin_lock+7>: retq
0xcb08: nopl 0x0(%rax,%rax,1)
0xcb10 <_L_pthread_spin_lock>: pause
0xcb12 <_L_pthread_spin_lock+2>: cmpl $0x0,(%rdi)
0xcb15 <_L_pthread_spin_lock+5>: jg 0xcb00 <pthread_spin_lock>
0xcb17 <_L_pthread_spin_lock+7>: jmp 0xcb10 <_L_pthread_spin_lock>
0xcb19: nopl 0x0(%rax)
0xcb20 <pthread_spin_trylock>: mov $0x1,%eax
The same problem appears to exist in
nptl/sparc/sparc{32,64}/pthread_spin_lock.c and
nptl/sysdeps/powerpc/pthread_spin_lock.c, but I am not fixing them as I
can't build/test for them.
Also, elf/tls-macros.h has several single-instruction "anonymous"
regions which could be fixed. The chances of landing on them are pretty
small though.
Thanks,
--
Paul Pluzhnikov
nptl/ChangeLog:
2012-04-25 Paul Pluzhnikov <ppluzhnikov@google.com>
* sysdeps/i386/pthread_spin_lock.c (pthread_spin_lock):
Add _L_pthread_spin_lock local label
diff --git a/nptl/sysdeps/i386/pthread_spin_lock.c b/nptl/sysdeps/i386/pthread_spin_lock.c
index c059e01..ff55b77 100644
--- a/nptl/sysdeps/i386/pthread_spin_lock.c
+++ b/nptl/sysdeps/i386/pthread_spin_lock.c
@@ -36,10 +36,13 @@ pthread_spin_lock (lock)
"jne 2f\n\t"
".subsection 1\n\t"
".align 16\n"
+ ".type _L_pthread_spin_lock,@function\n\t"
+ "_L_pthread_spin_lock:\n\t"
"2:\trep; nop\n\t"
"cmpl $0, %0\n\t"
"jg 1b\n\t"
"jmp 2b\n\t"
+ "3: .size _L_pthread_spin_lock, 3b-2b\n\t"
".previous"
: "=m" (*lock)
: "m" (*lock));