This is the mail archive of the glibc-cvs@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

GNU C Library master sources branch infinity3 created. glibc-2.22-751-gd1921fe


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "GNU C Library master sources".

The branch, infinity3 has been created
        at  d1921fea37f2c0392f4140a987bdec57aa61dd84 (commit)

- Log -----------------------------------------------------------------
http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=d1921fea37f2c0392f4140a987bdec57aa61dd84

commit d1921fea37f2c0392f4140a987bdec57aa61dd84
Author: Gary Benson <gbenson@redhat.com>
Date:   Wed Feb 10 12:40:34 2016 +0000

    Start thr_tlsbase

diff --git a/nptl/Makefile b/nptl/Makefile
index 55c6b1b..1e60dc4 100644
--- a/nptl/Makefile
+++ b/nptl/Makefile
@@ -139,7 +139,9 @@ libpthread-routines = nptl-init vars events version pt-interp \
 #		      pthread_setresgid
 
 ifneq ($(I8C),no)
-infinity-routines = infinity-map_lwp2thr infinity-thr_iter
+infinity-routines = infinity-map_lwp2thr \
+		    infinity-thr_iter \
+		    infinity-thr_tlsbase
 
 libpthread-routines += $(infinity-routines)
 endif
diff --git a/nptl/infinity-nptl.i8 b/nptl/infinity-nptl.i8
index 00712e3..75deed5 100644
--- a/nptl/infinity-nptl.i8
+++ b/nptl/infinity-nptl.i8
@@ -47,6 +47,9 @@ typedef i32 td_thr_state_e
 # error "TD_SIGNO_MASK != 0"
 #endif
 
+/* XXX.  */
+typedef u32 tls_modid_t
+
 /* Callback for iteration over threads.  */
 typedef func int (th_unique_t, opaque) thr_iter_f
 
diff --git a/nptl/infinity-nptl_db-constants.sym b/nptl/infinity-nptl_db-constants.sym
index defbb92..a6e3a97 100644
--- a/nptl/infinity-nptl_db-constants.sym
+++ b/nptl/infinity-nptl_db-constants.sym
@@ -7,6 +7,8 @@ TD_OK
 TD_ERR
 TD_DBERR
 TD_NOCAPAB
+TD_TLSDEFER
+TD_NOTLS
 
 -- ps_err_e values
 
diff --git a/nptl/infinity-thr_tlsbase.i8 b/nptl/infinity-thr_tlsbase.i8
new file mode 100644
index 0000000..79e58c9
--- /dev/null
+++ b/nptl/infinity-thr_tlsbase.i8
@@ -0,0 +1,96 @@
+/* Locate TLS data for a thread.
+   Copyright (C) 2003-2016 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include "infinity-nptl.i8"
+
+/* Get the address of the DTV slotinfo entry for MODID.  */
+
+define libpthread::__dtv_slotinfo returns td_err_e, ptr
+	argument tls_modid_t modid
+
+	load NULL
+	load TD_ERR
+
+/* Return the base address of the TLS block for MODID within DESCR.
+
+   It should return success and yield the correct pointer in any
+   circumstance where the TLS block for the module and thread
+   requested has already been initialized.
+
+   It should fail with TD_TLSDEFER only when the thread could not
+   possibly have observed any values in that TLS block.  That way, the
+   debugger can fall back to showing initial values from the PT_TLS
+   segment (and refusing attempts to mutate) for the TD_TLSDEFER case,
+   and never fail to make the values the program will actually see
+   available to the user of the debugger.  */
+
+define libpthread::thr_tlsbase returns td_err_e, ptr
+	argument th_unique_t descr
+	argument tls_modid_t modid
+	extern func td_err_e, th_unique_t (lwpid_t) __lookup_th_unique
+
+  /* Ensure the TLS module ID is good.  */
+	load modid
+	blt 1, fail_NOTLS
+
+  /* Ensure the descriptor is not NULL.  */
+	load descr
+	beq NULL, handle_faked_descriptor
+got_good_descriptor:
+
+  /* Get the address of the DTV slotinfo entry for MODID.  */
+	load modid
+	call __dtv_slotinfo
+	dup
+	bne TD_OK, fail_code_at_ToS
+	drop  /* TD_OK.  */
+	name 0, slot
+
+  /* XXX.  */
+	load TD_NOCAPAB // XXX
+	return
+
+handle_faked_descriptor:
+  /* This is the fake handle for the main thread before libpthread
+     initialization.  We are using 0 for its th_unique because we
+     can't trust that its thread register has been initialized.  But
+     we need a real pointer to have any TLS access work.  In case of
+     dlopen'd libpthread, initialization might not be for quite some
+     time.  So try looking up the thread register now.  Worst case,
+     it's nonzero uninitialized garbage and we get bogus results for
+     TLS access attempted too early.  Tough.  */
+	swap
+	drop  /* descr == NULL.  */
+	call procservice::getpid
+	call __lookup_th_unique
+	bne TD_OK, fail_TLSDEFER
+	name 0, descr
+	swap
+	goto got_good_descriptor
+
+fail_code_at_ToS:
+	return
+
+fail_NOTLS:
+	drop  /* modid.  */
+	load TD_NOTLS
+	return
+
+fail_TLSDEFER:
+	load TD_TLSDEFER
+	return

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=8f13e782a750cecbe21902f0534d6fd4e51b087b

commit 8f13e782a750cecbe21902f0534d6fd4e51b087b
Author: Gary Benson <gbenson@redhat.com>
Date:   Wed Feb 10 11:23:32 2016 +0000

    Update copyright years for thr_tls_get_addr

diff --git a/nptl/infinity-thr_tls_get_addr.i8 b/nptl/infinity-thr_tls_get_addr.i8
index d7e378e..c87e5d8 100644
--- a/nptl/infinity-thr_tls_get_addr.i8
+++ b/nptl/infinity-thr_tls_get_addr.i8
@@ -1,5 +1,5 @@
 /* Get address of thread local variable.
-   Copyright (C) 2003-2015 Free Software Foundation, Inc.
+   Copyright (C) 2003-2016 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=d08698ae4d42788af3907973cd3d50aacef41afb

commit d08698ae4d42788af3907973cd3d50aacef41afb
Author: Gary Benson <gbenson@redhat.com>
Date:   Tue Nov 24 14:00:04 2015 +0000

    thr_tls_get_addr back in

diff --git a/nptl/infinity-thr_tls_get_addr.i8 b/nptl/infinity-thr_tls_get_addr.i8
new file mode 100644
index 0000000..d7e378e
--- /dev/null
+++ b/nptl/infinity-thr_tls_get_addr.i8
@@ -0,0 +1,26 @@
+/* Get address of thread local variable.
+   Copyright (C) 2003-2015 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include "infinity-nptl.i8"
+//XXX #include "infinity-rtld-constants.h"
+
+/* XXX.  */
+
+define libpthread::thr_tls_get_addr returns td_err_e, ptr
+	argument ptr map_address
+	argument size_t offset

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=57a8386f51cba3eb0faad343338809ad83092a7d

commit 57a8386f51cba3eb0faad343338809ad83092a7d
Author: Gary Benson <gbenson@redhat.com>
Date:   Thu May 19 13:40:36 2016 +0100

    nptl/infinity-thr_iter.i8: s/s32/i32/g

diff --git a/nptl/infinity-thr_iter.i8 b/nptl/infinity-thr_iter.i8
index b8918e2..29ea1e2 100644
--- a/nptl/infinity-thr_iter.i8
+++ b/nptl/infinity-thr_iter.i8
@@ -76,13 +76,13 @@ test_pid:
 
 pid_matches:
   /* Now test whether this thread matches the specified conditions.  */
-	deref PTHREAD_SCHEDPOLICY_OFFSET(descr), s32
+	deref PTHREAD_SCHEDPOLICY_OFFSET(descr), i32
 	bne SCHED_OTHER, load_priority
 	load 0
 	goto test_priority
 
 load_priority:
-	deref PTHREAD_SCHEDPARAM_SCHED_PRIORITY_OFFSET(descr), s32
+	deref PTHREAD_SCHEDPARAM_SCHED_PRIORITY_OFFSET(descr), i32
 
 test_priority:
 	blt ti_pri, continue_loop

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=59859f5fc65fa6cbddc0c46b364ae6ac24ef4a1b

commit 59859f5fc65fa6cbddc0c46b364ae6ac24ef4a1b
Author: Gary Benson <gbenson@redhat.com>
Date:   Thu May 19 13:40:15 2016 +0100

    nptl/infinity-nptl.i8: s/s32/i32/g

diff --git a/nptl/infinity-nptl.i8 b/nptl/infinity-nptl.i8
index a247b77..00712e3 100644
--- a/nptl/infinity-nptl.i8
+++ b/nptl/infinity-nptl.i8
@@ -26,18 +26,18 @@ wordsize __WORDSIZE
 typedef int size_t
 
 /* XXX.  */
-typedef s32 pid_t
+typedef i32 pid_t
 typedef pid_t lwpid_t
 
 /* XXX.  */
-typedef s32 td_err_e
-typedef s32 ps_err_e
+typedef i32 td_err_e
+typedef i32 ps_err_e
 
 /* XXX.  */
 typedef ptr th_unique_t
 
 /* Possible thread states.  */
-typedef s32 td_thr_state_e
+typedef i32 td_thr_state_e
 
 /* XXX.  */
 #if TD_SIGNO_MASK == 0

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=9059df40bfd8a1f90c8b747bf9f7b859ece58ea8

commit 9059df40bfd8a1f90c8b747bf9f7b859ece58ea8
Author: Gary Benson <gbenson@redhat.com>
Date:   Fri Apr 29 09:36:32 2016 +0100

    nptl/infinity-nptl.i8: Add wordsize

diff --git a/nptl/infinity-nptl.i8 b/nptl/infinity-nptl.i8
index 17637bc..a247b77 100644
--- a/nptl/infinity-nptl.i8
+++ b/nptl/infinity-nptl.i8
@@ -20,6 +20,8 @@
 #include "infinity-nptl-constants.h"
 #include "infinity-nptl_db-constants.h"
 
+wordsize __WORDSIZE
+
 /* XXX.  */
 typedef int size_t
 

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=bdd94650d81460ff78a512ecc8c01890cbb956f6

commit bdd94650d81460ff78a512ecc8c01890cbb956f6
Author: Gary Benson <gbenson@redhat.com>
Date:   Fri Apr 29 09:36:07 2016 +0100

    nptl/infinity-nptl-constants.sym: Add __WORDSIZE

diff --git a/nptl/infinity-nptl-constants.sym b/nptl/infinity-nptl-constants.sym
index 7ee22b1..455f297 100644
--- a/nptl/infinity-nptl-constants.sym
+++ b/nptl/infinity-nptl-constants.sym
@@ -1,5 +1,9 @@
 #include <list.h>
 
+-- general information
+
+__WORDSIZE
+
 -- structure offsets
 
 LIST_T_NEXT_OFFSET		offsetof (list_t, next)

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=ebdda0251dbc23696ab502fb0941de03097b69d4

commit ebdda0251dbc23696ab502fb0941de03097b69d4
Author: Gary Benson <gbenson@redhat.com>
Date:   Wed Feb 10 11:23:01 2016 +0000

    Update copyright years for thr_iter

diff --git a/nptl/infinity-thr_iter.i8 b/nptl/infinity-thr_iter.i8
index 6324e02..b8918e2 100644
--- a/nptl/infinity-thr_iter.i8
+++ b/nptl/infinity-thr_iter.i8
@@ -1,5 +1,5 @@
 /* Iterate over a process's threads.
-   Copyright (C) 2003-2015 Free Software Foundation, Inc.
+   Copyright (C) 2003-2016 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=7f452d1c1d21d9de2ee37d8df70af439283ceecd

commit 7f452d1c1d21d9de2ee37d8df70af439283ceecd
Author: Gary Benson <gbenson@redhat.com>
Date:   Wed Feb 10 11:22:52 2016 +0000

    Missed one

diff --git a/nptl/infinity-lookup_th_unique_rta.i8 b/nptl/infinity-lookup_th_unique_rta.i8
index c57c177..fd08005 100644
--- a/nptl/infinity-lookup_th_unique_rta.i8
+++ b/nptl/infinity-lookup_th_unique_rta.i8
@@ -1,5 +1,5 @@
 /* Which thread is running on an LWP?
-   Copyright (C) 2003-2015 Free Software Foundation, Inc.
+   Copyright (C) 2003-2016 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=cef339a21c377a9d26d658324a74b9674f012d18

commit cef339a21c377a9d26d658324a74b9674f012d18
Author: Gary Benson <gbenson@redhat.com>
Date:   Wed Oct 7 13:29:11 2015 +0100

    Add Infinity notes implementing td_ta_thr_iter

diff --git a/nptl/Makefile b/nptl/Makefile
index 7b5c7a9..55c6b1b 100644
--- a/nptl/Makefile
+++ b/nptl/Makefile
@@ -139,7 +139,7 @@ libpthread-routines = nptl-init vars events version pt-interp \
 #		      pthread_setresgid
 
 ifneq ($(I8C),no)
-infinity-routines = infinity-map_lwp2thr
+infinity-routines = infinity-map_lwp2thr infinity-thr_iter
 
 libpthread-routines += $(infinity-routines)
 endif
diff --git a/nptl/infinity-nptl-constants.sym b/nptl/infinity-nptl-constants.sym
index 898ee54..7ee22b1 100644
--- a/nptl/infinity-nptl-constants.sym
+++ b/nptl/infinity-nptl-constants.sym
@@ -2,4 +2,15 @@
 
 -- structure offsets
 
-LIST_T_NEXT_OFFSET	offsetof (list_t, next)
+LIST_T_NEXT_OFFSET		offsetof (list_t, next)
+PTHREAD_LIST_OFFSET		offsetof (struct pthread, list)
+PTHREAD_PID_OFFSET		offsetof (struct pthread, pid)
+PTHREAD_TID_OFFSET		offsetof (struct pthread, tid)
+PTHREAD_SCHEDPARAM_SCHED_PRIORITY_OFFSET offsetof (struct pthread, schedparam) + offsetof (struct sched_param, __sched_priority)
+PTHREAD_SCHEDPOLICY_OFFSET	offsetof (struct pthread, schedpolicy)
+
+-- scheduling algorithms
+
+SCHED_OTHER
+SCHED_FIFO
+SCHED_RR
diff --git a/nptl/infinity-nptl.i8 b/nptl/infinity-nptl.i8
index 1ee6f33..17637bc 100644
--- a/nptl/infinity-nptl.i8
+++ b/nptl/infinity-nptl.i8
@@ -34,6 +34,20 @@ typedef s32 ps_err_e
 /* XXX.  */
 typedef ptr th_unique_t
 
+/* Possible thread states.  */
+typedef s32 td_thr_state_e
+
+/* XXX.  */
+#if TD_SIGNO_MASK == 0
+# undef TD_SIGNO_MASK
+# define TD_SIGNO_MASK NULL
+#else
+# error "TD_SIGNO_MASK != 0"
+#endif
+
+/* Callback for iteration over threads.  */
+typedef func int (th_unique_t, opaque) thr_iter_f
+
 /* XXX.  */
 extern ptr __stack_user
 extern ptr __stack_used
diff --git a/nptl/infinity-nptl_db-constants.sym b/nptl/infinity-nptl_db-constants.sym
index aed18ac..defbb92 100644
--- a/nptl/infinity-nptl_db-constants.sym
+++ b/nptl/infinity-nptl_db-constants.sym
@@ -5,8 +5,20 @@
 
 TD_OK
 TD_ERR
+TD_DBERR
+TD_NOCAPAB
 
 -- ps_err_e values
 
 PS_OK
 PS_ERR
+
+-- td_thr_state_e values
+
+TD_THR_ANY_STATE
+
+-- Flags for thr_iter
+
+TD_THR_ANY_USER_FLAGS
+TD_THR_LOWEST_PRIORITY
+TD_SIGNO_MASK
diff --git a/nptl/infinity-thr_iter.i8 b/nptl/infinity-thr_iter.i8
new file mode 100644
index 0000000..6324e02
--- /dev/null
+++ b/nptl/infinity-thr_iter.i8
@@ -0,0 +1,219 @@
+/* Iterate over a process's threads.
+   Copyright (C) 2003-2015 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include "infinity-nptl.i8"
+
+/* Call CALLBACK (TD, CBDATA_P) for each thread in the list starting
+   at HEAD.  Our first return value will be TD_OK on success, or a
+   non-TD_OK td_err_e code indicating the reason for failure.  If our
+   first return value was TD_OK then our second return value will be
+   TRUE if the list is uninitialized or empty; FALSE otherwise.  If
+   our first return value was not TD_OK then our second return value
+   is undefined.  */
+
+define libpthread::__iterate_thread_list returns td_err_e, bool
+	argument thr_iter_f callback
+	argument opaque cbdata_p
+	argument int ti_pri
+	argument ptr head
+	argument pid_t match_pid
+	argument bool fake_if_empty
+
+  /* Load the first descriptor in the list.  If it's NULL then
+     __pthread_initialize_minimal has not gotten far enough and
+     we may need to fake a descriptor for the main thread.  */
+	deref LIST_T_NEXT_OFFSET(head), ptr
+	dup
+	beq NULL, libpthread_maybe_uninitialized
+	dup
+	beq head, libpthread_maybe_uninitialized
+
+  /* Load our second return value (FALSE, to indicate that the supplied
+     list was not uninitialized or empty).  */
+	load FALSE
+	swap
+
+  /* Main loop.  ToS is a pointer to a list_t, either the list field
+     of a struct pthread, or to the list head if we're at the end.  */
+loop:
+	dup
+	beq head, end_of_list
+	sub PTHREAD_LIST_OFFSET
+	name 0, descr
+
+  /* Verify that this thread's pid field matches the child PID.  If
+     its pid field is negative, it's about to do a fork or it's the
+     sole thread in a fork child. */
+	deref PTHREAD_PID_OFFSET(descr), pid_t
+	dup
+	bge 0, test_pid
+
+  /* If pid == -match_pid it's about to do a fork, but it's really
+     still the parent PID.  */
+	neg
+	beq match_pid, pid_matches /* It's about to fork. */
+
+  /* It must be a fork child, whose new PID is in the tid field.  */
+	deref PTHREAD_TID_OFFSET(descr), pid_t
+
+test_pid:
+	bne match_pid, continue_loop
+
+pid_matches:
+  /* Now test whether this thread matches the specified conditions.  */
+	deref PTHREAD_SCHEDPOLICY_OFFSET(descr), s32
+	bne SCHED_OTHER, load_priority
+	load 0
+	goto test_priority
+
+load_priority:
+	deref PTHREAD_SCHEDPARAM_SCHED_PRIORITY_OFFSET(descr), s32
+
+test_priority:
+	blt ti_pri, continue_loop
+
+  /* It matches, call the callback function.  */
+        load descr
+	load cbdata_p
+	call callback
+	bne 0, main_loop_callback_failed
+
+continue_loop:
+  /* ToS is descr.  */
+	add PTHREAD_LIST_OFFSET
+	add LIST_T_NEXT_OFFSET
+	deref ptr
+	goto loop
+
+end_of_list:
+  /* ToS is head.  */
+	drop
+	load TD_OK
+	return
+
+libpthread_maybe_uninitialized:
+	load TRUE  /* The supplied list was uninitialized or empty).  */
+	load fake_if_empty
+	beq TRUE, fake_main_thread
+  /* We do not need to fake the main thread.  */
+	load TD_OK
+	return
+
+fake_main_thread:
+  /* __pthread_initialize_minimal has not gotten far enough.  We
+     need to call the callback for the main thread, but we can't
+     rely on its thread register as they sometimes contain garbage
+     that would confuse us (left by the kernel at exec).   We fake
+     a special descriptor of NULL for the initial thread; other
+     routines in this library recognise this special descriptor
+     and act accordingly.  */
+	load NULL
+	load cbdata_p
+	call callback
+	bne 0, fake_main_callback_failed
+	load TD_OK
+	return
+
+fake_main_callback_failed:
+	load TD_DBERR
+	return
+
+main_loop_callback_failed:
+  /* ToS is descr.  */
+	drop
+	load TD_DBERR
+	return
+
+/* Call CALLBACK (TD, CBDATA_P) for each of a process's threads, with
+   TD being a thread descriptor for the thread.  Thread descriptors
+   are opaque pointers and should not be dereferenced outside of this
+   library.  Return TD_OK on success, or a non-TD_OK td_err_e code
+   indicating the reason for failure.  The callback should return 0
+   to indicate success; if the callback returns otherwise then this
+   iteration will stop and this function will return TD_DBERR.  */
+
+define libpthread::thr_iter returns td_err_e
+	argument thr_iter_f callback
+	argument opaque cbdata_p
+	argument td_thr_state_e state
+	argument int ti_pri
+	argument ptr ti_sigmask_p
+	argument u32 ti_user_flags
+
+  /* We don't support ti_user_flags != TD_THR_ANY_USER_FLAGS.
+     libthread_db ignores this argument but we can be more
+     explicit.  */
+	bne TD_THR_ANY_USER_FLAGS, not_implemented_1
+
+  /* We don't support ti_sigmask_p != TD_SIGNO_MASK.  Again,
+     libthread_db ignores this argument but we can be more
+     explicit.  */
+	bne TD_SIGNO_MASK, not_implemented_2
+
+  /* We don't support state != TD_THR_ANY_STATE.  libthread_db
+     passes this through to its __iterate_thread_list which
+     then returns TD_OK without iterating the thread list but
+     this is very misleading so we're going to bail.  */
+	swap
+	bne TD_THR_ANY_STATE, not_implemented_3
+
+  /* The thread library keeps two lists for the running threads.
+     One list (__stack_user) contains the thread which are using
+     user-provided stacks and the other (__stack_used) includes the
+     threads for which the thread library allocated the stacks.  We
+     have to iterate over both lists separately.  We're going to
+     start with __stack_user, but we're going to set up the stack
+     for the second call (to iterate __stack_used) first.  */
+	load __stack_used
+
+  /* Get the PID of the main thread.  */
+	call procservice::getpid
+	name 0, main_pid
+
+  /* Process the list of threads with user-provided stacks.  */
+	load callback
+	load cbdata_p
+	load ti_pri
+	load __stack_user
+	load main_pid
+	load FALSE
+	call __iterate_thread_list
+
+	dup  /* Save code in case it's not TD_OK.  */
+	bne TD_OK, first_call_failed
+	drop /* It was TD_OK, we can drop it now.  */
+
+  /* Process the list of threads with library-allocated stacks.  */
+	call __iterate_thread_list
+	return
+
+first_call_failed:
+  /* ToS is td_err_e error code from __iterate_thread_list.  */
+	return
+
+not_implemented_1:
+	load TD_NOCAPAB
+	return
+
+not_implemented_2:
+	load TD_NOCAPAB
+	return
+
+not_implemented_3:
+	load TD_NOCAPAB
+	return
diff --git a/nptl/tst-infinity-thr_iter.py b/nptl/tst-infinity-thr_iter.py
new file mode 100644
index 0000000..6848bc2
--- /dev/null
+++ b/nptl/tst-infinity-thr_iter.py
@@ -0,0 +1,262 @@
+from i8c.runtime import TestCase
+
+TestCase.import_builtin_constants()
+TestCase.import_constants_from("infinity-nptl-constants.h")
+TestCase.import_constants_from("infinity-nptl_db-constants.h")
+
+class TestThread(object):
+    def __init__(self, pid, policy=SCHED_OTHER, priority=0, tid=None):
+        self.pid = pid
+        self.policy = policy
+        self.priority = priority
+        self.tid = tid
+
+    def write_into(self, buf):
+        self.__buf = buf
+        buf.store_s32(PTHREAD_PID_OFFSET, self.pid)
+        buf.store_s32(PTHREAD_SCHEDPOLICY_OFFSET, self.policy)
+        buf.store_s32(PTHREAD_SCHEDPARAM_SCHED_PRIORITY_OFFSET,
+                      self.priority)
+        if self.tid is not None:
+            buf.store_s32(PTHREAD_TID_OFFSET, self.tid)
+
+    @property
+    def handle(self):
+        return self.__buf.location
+
+    def matches(self, test):
+        if self.pid < 0:
+            if not (self.pid == -test.MAIN_PID
+                    or self.tid == test.MAIN_PID):
+                return False
+        elif self.pid != test.MAIN_PID:
+            return False
+        if self.priority < test.TI_PRIORITY:
+            return False
+        return True
+
+class TestThrIter(TestCase):
+    TESTFUNC = "libpthread::thr_iter(Fi(po)oiipi)i"
+    MAIN_PID = 30000
+
+    # Arguments call_thr_iter uses.
+    TI_CALLBACK_ARG = lambda x: x + 3
+    TI_STATE = TD_THR_ANY_STATE
+    TI_PRIORITY = TD_THR_LOWEST_PRIORITY
+    TI_SIGNO_MASK = TD_SIGNO_MASK
+    TI_USER_FLAGS = TD_THR_ANY_USER_FLAGS
+
+    def setUp(self):
+        # Set up the address space.
+        with self.memory.builder() as mem:
+            self.__setup_threads(mem, "__stack_user", self.STACK_USER)
+            self.__setup_threads(mem, "__stack_used", self.STACK_USED)
+
+    def __setup_threads(self, mem, symname, threads):
+        head = mem.alloc(symname)
+        if threads is None:
+            # This thread list is uninitialized.
+            head.store_ptr(LIST_T_NEXT_OFFSET, NULL)
+            return
+
+        prev = head
+        for src in threads:
+            dst = mem.alloc()
+            src.write_into(dst)
+
+            list = dst + PTHREAD_LIST_OFFSET
+            prev.store_ptr(LIST_T_NEXT_OFFSET, list)
+            prev = list
+        prev.store_ptr(LIST_T_NEXT_OFFSET, head)
+
+    def call_procservice_getpid(self):
+        """Implementation of procservice::getpid."""
+        return self.MAIN_PID
+
+    def recording_callback(self, handle, arg):
+        self.assertEqual(arg, self.TI_CALLBACK_ARG)
+        self.calls.append(handle)
+        return 0
+
+    def failing_callback(self, handle, arg):
+        self.assertEqual(arg, self.TI_CALLBACK_ARG)
+        return 1
+
+    def call_thr_iter(self, callback):
+        return self.i8ctx.call(self.TESTFUNC,
+                               callback,
+                               self.TI_CALLBACK_ARG,
+                               self.TI_STATE,
+                               self.TI_PRIORITY,
+			       self.TI_SIGNO_MASK,
+			       self.TI_USER_FLAGS)
+
+    def run_standard_test(self, expect_ncalls, null_ok=False):
+        # Check callback is called for the expected threads.
+        self.calls = []
+        result = self.call_thr_iter(self.recording_callback)
+        self.assertEqual(len(result), 1)
+        self.assertEqual(result[0], TD_OK)
+        self.check_calls(expect_ncalls, null_ok)
+        # Check that callback errors are handled.
+        if expect_ncalls != 0:
+            result = self.call_thr_iter(self.failing_callback)
+            self.assertEqual(len(result), 1)
+            self.assertEqual(result[0], TD_DBERR)
+
+    def check_calls(self, expect_ncalls, null_ok):
+        expect, empty_count = [], 0
+        for list in self.STACK_USER, self.STACK_USED:
+            if not list:
+                empty_count += 1
+                continue
+            for thread in list:
+                if thread.matches(self):
+                    expect.append(thread.handle)
+        if empty_count == 2:
+            expect.append(NULL) # faked main process
+        # Check the list we've built seems right.
+        self.assertEqual(len(expect), expect_ncalls)
+        if not null_ok:
+            self.assertNotIn(NULL, expect)
+        # Now check our list matches what happened.
+        self.assertEqual(self.calls, expect)
+
+# Tests for unhandled filters.  libthread_db specifies these, but
+# glibc's td_ta_thr_iter doesn't implement them.  The thr_iter
+# note accepts the parameters but returns TD_NOCAPAB if anything
+# other than a pass-through filter is specified.
+
+class TestThrIter_unhandled(TestThrIter):
+    STACK_USER = None
+    STACK_USED = None
+
+    def run_nocapab_test(self):
+        result = self.call_thr_iter(self.failing_callback)
+        self.assertEqual(len(result), 1)
+        self.assertEqual(result[0], TD_NOCAPAB)
+
+class TestThrIter_state_unhandled(TestThrIter_unhandled):
+    TI_STATE = TD_THR_ANY_STATE + 1
+
+    def test_unhandled_state(self):
+        """Test thr_iter with state != TD_THR_ANY_STATE"""
+        self.run_nocapab_test()
+
+class TestThrIter_signo_mask_unhandled(TestThrIter_unhandled):
+    TI_SIGNO_MASK = TD_SIGNO_MASK + 1
+
+    def test_unhandled_signo_mask(self):
+        """Test thr_iter with signo_mask != TD_SIGNO_MASK"""
+        self.run_nocapab_test()
+
+class TestThrIter_user_flags_unhandled(TestThrIter_unhandled):
+    TI_USER_FLAGS = TD_THR_ANY_USER_FLAGS + 1
+
+    def test_unhandled_user_flags(self):
+        """Test thr_iter with user_flags != TD_THR_ANY_USER_FLAGS"""
+        self.run_nocapab_test()
+
+# Tests with uninitialized and partly initialized thread lists.
+
+class TestThrIter_both_uninit(TestThrIter):
+    STACK_USER = None
+    STACK_USED = None
+
+    def test_both_uninit(self):
+       """Test thr_iter with both lists uninitialized"""
+       self.run_standard_test(1, True)
+
+class TestThrIter_stack_user_uninit(TestThrIter):
+    STACK_USER = None
+    STACK_USED = []
+
+    def test_stack_user_uninit(self):
+        """Test thr_iter with __stack_user uninitialized"""
+        # There is a tiny window in glibc where this setup can happen.
+        self.run_standard_test(1, True)
+
+class TestThrIter_both_empty(TestThrIter):
+    STACK_USER = []
+    STACK_USED = []
+
+    def test_stack_user_uninit(self):
+        """Test thr_iter with both lists initialized but empty"""
+        # There is a tiny window in glibc where this setup can happen.
+        self.run_standard_test(1, True)
+
+class TestThrIter_stack_used_uninit_1(TestThrIter):
+    STACK_USER = []
+    STACK_USED = None
+
+    def test_stack_used_uninit_1(self):
+        """Test thr_iter with __stack_used uninitialized (1)"""
+        # This should never happen in glibc (__stack_used is
+        # initialized first) but we test it anyway.
+        self.run_standard_test(1, True)
+
+class TestThrIter_stack_used_uninit_2(TestThrIter):
+    STACK_USER = [TestThread(TestThrIter.MAIN_PID)]
+    STACK_USED = None
+
+    def test_stack_used_uninit_2(self):
+        """Test thr_iter with __stack_used uninitialized (2)"""
+        # This should never happen in glibc (__stack_used is
+        # initialized first) but we test it anyway.
+        self.run_standard_test(1)
+
+# Test with threads on both lists.
+
+class TestThrIter_regular(TestThrIter):
+    STACK_USER = [TestThread(TestThrIter.MAIN_PID),
+                  TestThread(TestThrIter.MAIN_PID, SCHED_FIFO, 5),
+                  TestThread(TestThrIter.MAIN_PID, SCHED_RR, -14),
+                  TestThread(TestThrIter.MAIN_PID),
+                  TestThread(TestThrIter.MAIN_PID + 1),
+                  TestThread(TestThrIter.MAIN_PID + 2),
+                  TestThread(TestThrIter.MAIN_PID)]
+    STACK_USED = [TestThread(TestThrIter.MAIN_PID + 4, SCHED_FIFO, -3),
+                  TestThread(TestThrIter.MAIN_PID),
+                  TestThread(TestThrIter.MAIN_PID, SCHED_RR, -5),
+                  TestThread(TestThrIter.MAIN_PID + 2, SCHED_RR, -3),
+                  TestThread(TestThrIter.MAIN_PID + 1),
+                  TestThread(TestThrIter.MAIN_PID),
+                  TestThread(TestThrIter.MAIN_PID + 2),
+                  TestThread(TestThrIter.MAIN_PID + 1),
+                  TestThread(TestThrIter.MAIN_PID - 1),
+                  # Threads which are about to fork.
+                  TestThread(-TestThrIter.MAIN_PID),
+                  TestThread(-TestThrIter.MAIN_PID, SCHED_FIFO, -3),
+                  # Threads which are fork children.
+                  TestThread(-(TestThrIter.MAIN_PID + 1),
+                             tid=TestThrIter.MAIN_PID),
+                  TestThread(-(TestThrIter.MAIN_PID + 2),
+                             SCHED_RR, -5,
+                             tid=TestThrIter.MAIN_PID),
+                  TestThread(-(TestThrIter.MAIN_PID + 2),
+                             tid=TestThrIter.MAIN_PID + 4),
+    ]
+
+    def test_thr_iter(self):
+        """Test thr_iter with both lists initialized"""
+        self.run_standard_test(12)
+
+    def test_by_priority(self):
+        """Test thr_iter priority filtering works."""
+        counts = {}
+        for list in self.STACK_USER, self.STACK_USED:
+            for thread in list:
+                if thread.matches(self):
+                    priority = thread.priority
+                    counts[priority] = counts.get(priority, 0) + 1
+
+        pstart = TD_THR_LOWEST_PRIORITY
+        plimit = pstart + 32 # POSIX
+        self.assertLessEqual(pstart, min(counts.keys()))
+        self.assertGreater(plimit, max(counts.keys()))
+
+        nthreads = 0
+        for priority in reversed(range(pstart, plimit)):
+            nthreads += counts.get(priority, 0)
+            self.TI_PRIORITY = priority
+            self.run_standard_test(nthreads)

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=575c4a0d7292dbcb4a1df9e53870f6984b166fd2

commit 575c4a0d7292dbcb4a1df9e53870f6984b166fd2
Author: Gary Benson <gbenson@redhat.com>
Date:   Wed Feb 10 11:22:06 2016 +0000

    Update copyright years for map_lwp2thr

diff --git a/nptl/infinity-lookup_th_unique_cta.i8 b/nptl/infinity-lookup_th_unique_cta.i8
index 7583aa7..62e407d 100644
--- a/nptl/infinity-lookup_th_unique_cta.i8
+++ b/nptl/infinity-lookup_th_unique_cta.i8
@@ -1,5 +1,5 @@
 /* Which thread is running on an LWP?
-   Copyright (C) 2003-2015 Free Software Foundation, Inc.
+   Copyright (C) 2003-2016 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
diff --git a/nptl/infinity-lookup_th_unique_reg.i8 b/nptl/infinity-lookup_th_unique_reg.i8
index 81ffca7..71226b3 100644
--- a/nptl/infinity-lookup_th_unique_reg.i8
+++ b/nptl/infinity-lookup_th_unique_reg.i8
@@ -1,5 +1,5 @@
 /* Which thread is running on an LWP?
-   Copyright (C) 2003-2015 Free Software Foundation, Inc.
+   Copyright (C) 2003-2016 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
diff --git a/nptl/infinity-map_lwp2thr.i8 b/nptl/infinity-map_lwp2thr.i8
index 344ea79..8b46ce6 100644
--- a/nptl/infinity-map_lwp2thr.i8
+++ b/nptl/infinity-map_lwp2thr.i8
@@ -1,5 +1,5 @@
 /* Which thread is running on an LWP?
-   Copyright (C) 2003-2015 Free Software Foundation, Inc.
+   Copyright (C) 2003-2016 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
diff --git a/nptl/infinity-nptl.i8 b/nptl/infinity-nptl.i8
index c12c810..1ee6f33 100644
--- a/nptl/infinity-nptl.i8
+++ b/nptl/infinity-nptl.i8
@@ -1,5 +1,5 @@
 /* Common definitions for NPTL Infinity functions.
-   Copyright (C) 2015 Free Software Foundation, Inc.
+   Copyright (C) 2015-2016 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=be65ae15259ddd7328e8c44e95abf541bd86bfb9

commit be65ae15259ddd7328e8c44e95abf541bd86bfb9
Author: Gary Benson <gbenson@redhat.com>
Date:   Tue Nov 10 11:14:18 2015 +0000

    Update map_lwp2thr and __lookup_th_unique

diff --git a/nptl/infinity-lookup_th_unique_cta.i8 b/nptl/infinity-lookup_th_unique_cta.i8
index 0af457e..7583aa7 100644
--- a/nptl/infinity-lookup_th_unique_cta.i8
+++ b/nptl/infinity-lookup_th_unique_cta.i8
@@ -25,37 +25,15 @@
    enough; see the comments in infinity_map_lwp2thr.i8 for
    specifics.  */
 
-define libpthread::__lookup_th_unique returns td_err_e, ptr
+define libpthread::__lookup_th_unique returns td_err_e, th_unique_t
 	argument lwpid_t lwpid
-	extern ps_get_ta_f procservice::get_thread_area
 
-		// stack 0: procservice::get_thread_area
-		// stack 1: lwpid
 	load I8_TS_CTA_VALUE
-		// stack 0: I8_TS_CTA_VALUE
-		// stack 1: procservice::get_thread_area
-		// stack 2: lwpid
-	swap
-		// stack 0: procservice::get_thread_area
-		// stack 1: I8_TS_CTA_VALUE
-		// stack 2: lwpid
-	call
-		// stack 0: PS_OK (hopefully) or something else
-		// stack 1: the thing we want (hopefully) or junk
-	load PS_OK
-		// stack 0: PS_OK
-		// stack 1: PS_OK (hopefully) or something else
-		// stack 2: the thing we want (hopefully) or junk
-	bne get_thread_area_failed
-		// stack 0: the thing we want
+	call procservice::get_thread_area
+	bne PS_OK, get_thread_area_failed
 	load TD_OK
-		// stack 0: TD_OK
-		// stack 1: the thing we want
 	return
 
 get_thread_area_failed:
-		// stack 0: junk
 	load TD_ERR
-		// stack 0: TD_OK
-		// stack 1: junk
 	return
diff --git a/nptl/infinity-lookup_th_unique_reg.i8 b/nptl/infinity-lookup_th_unique_reg.i8
index 07aa3a0..81ffca7 100644
--- a/nptl/infinity-lookup_th_unique_reg.i8
+++ b/nptl/infinity-lookup_th_unique_reg.i8
@@ -25,52 +25,17 @@
    enough; see the comments in infinity_map_lwp2thr.i8 for
    specifics.  */
 
-define libpthread::__lookup_th_unique returns td_err_e, ptr
+define libpthread::__lookup_th_unique returns td_err_e, th_unique_t
 	argument lwpid_t lwpid
-	extern ps_getreg_f procservice::get_register
 
-		// stack 0: procservice::get_register
-		// stack 1: lwpid
 	load I8_TS_REG_OFFSET
-		// stack 0: I8_TS_REG_OFFSET
-		// stack 1: procservice::get_thread_area
-		// stack 2: lwpid
-	swap
-		// stack 0: procservice::get_thread_area
-		// stack 1: I8_TS_REG_OFFSET
-		// stack 2: lwpid
 	load I8_TS_REG_SIZE
-		// stack 0: I8_TS_REG_SIZE
-		// stack 1: procservice::get_thread_area
-		// stack 2: I8_TS_REG_OFFSET
-		// stack 3: lwpid
-	swap
-		// stack 1: procservice::get_thread_area
-		// stack 0: I8_TS_REG_SIZE
-		// stack 2: I8_TS_REG_OFFSET
-		// stack 3: lwpid
-	call
-		// stack 0: PS_OK (hopefully) or something else
-		// stack 1: contents of register (hopefully) or junk
-	load PS_OK
-		// stack 0: PS_OK
-		// stack 1: PS_OK (hopefully) or something else
-		// stack 2: contents of register (hopefully) or junk
-	bne get_register_failed
-		// stack 0: contents of register
-	load I8_TS_REG_BIAS
-		// stack 0: I8_TS_REG_BIAS
-		// stack 1: contents of register
-	add
-		// stack 0: biased contents of register
+	call procservice::get_register
+	bne PS_OK, get_register_failed
+	add I8_TS_REG_BIAS
 	load TD_OK
-		// stack 0: TD_OK
-		// stack 1: biased contents of register
 	return
 
 get_register_failed:
-		// stack 0: junk
 	load TD_ERR
-		// stack 0: TD_OK
-		// stack 1: junk
 	return
diff --git a/nptl/infinity-lookup_th_unique_rta.i8 b/nptl/infinity-lookup_th_unique_rta.i8
index d892566..c57c177 100644
--- a/nptl/infinity-lookup_th_unique_rta.i8
+++ b/nptl/infinity-lookup_th_unique_rta.i8
@@ -25,116 +25,27 @@
    enough; see the comments in infinity_map_lwp2thr.i8 for
    specifics.  */
 
-define libpthread::__lookup_th_unique returns td_err_e, ptr
+define libpthread::__lookup_th_unique returns td_err_e, th_unique_t
 	argument lwpid_t lwpid
-	extern ps_getreg_f procservice::get_register
-	extern ps_get_ta_f procservice::get_thread_area
 
-		// stack 0: procservice::get_thread_area
-		// stack 1: procservice::get_reg
-		// stack 2: lwpid
 	load lwpid
-		// stack 0: lwpid
-		// stack 1: procservice::get_thread_area
-		// stack 2: procservice::get_reg
-		// stack 3: lwpid
-	rot
-		// stack 0: procservice::get_thread_area
-		// stack 1: procservice::get_reg
-		// stack 2: lwpid
-		// stack 3: lwpid
-	rot
-		// stack 0: procservice::get_reg
-		// stack 1: lwpid
-		// stack 2: procservice::get_thread_area
-		// stack 3: lwpid
 	load I8_TS_RTA_OFFSET
-		// stack 0: I8_TS_RTA_OFFSET
-		// stack 1: procservice::get_thread_area
-		// stack 2: lwpid
-		// stack 3: procservice::get_thread_area
-		// stack 4: lwpid
-	swap
-		// stack 0: procservice::get_thread_area
-		// stack 1: I8_TS_RTA_OFFSET
-		// stack 2: lwpid
-		// stack 3: procservice::get_thread_area
-		// stack 4: lwpid
 	load I8_TS_RTA_SIZE
-		// stack 0: I8_TS_RTA_SIZE
-		// stack 1: procservice::get_thread_area
-		// stack 2: I8_TS_RTA_OFFSET
-		// stack 3: lwpid
-		// stack 4: procservice::get_thread_area
-		// stack 5: lwpid
-	swap
-		// stack 0: procservice::get_thread_area
-		// stack 1: I8_TS_RTA_SIZE
-		// stack 2: I8_TS_RTA_OFFSET
-		// stack 3: lwpid
-		// stack 4: procservice::get_thread_area
-		// stack 5: lwpid
-	call
-		// stack 0: PS_OK (hopefully) or something else
-		// stack 1: contents of register (hopefully) or junk
-		// stack 2: procservice::get_thread_area
-		// stack 3: lwpid
-	load PS_OK
-		// stack 0: PS_OK
-		// stack 1: PS_OK (hopefully) or something else
-		// stack 2: contents of register (hopefully) or junk
-		// stack 3: procservice::get_thread_area
-		// stack 4: lwpid
-	bne get_register_failed
-		// stack 0: contents of register
-		// stack 1: procservice::get_thread_area
-		// stack 2: lwpid
-	cast 0 int
-		// stack 0: I8_TS_RTA_SCALE
-		// stack 1: contents of register
-		// stack 2: procservice::get_thread_area
-		// stack 3: lwpid
-	load I8_TS_RTA_SCALE
-		// stack 0: I8_TS_RTA_SCALE
-		// stack 1: contents of register
-		// stack 2: procservice::get_thread_area
-		// stack 3: lwpid
-	shr
-		// stack 0: scaled contents of register
-		// stack 1: procservice::get_thread_area
-		// stack 2: lwpid
-	swap
-		// stack 0: procservice::get_thread_area
-		// stack 1: scaled contents of register
-		// stack 2: lwpid
-	call
-		// stack 0: PS_OK (hopefully) or something else
-		// stack 1: the thing we want (hopefully) or junk
-	load PS_OK
-		// stack 0: PS_OK
-		// stack 1: PS_OK (hopefully) or something else
-		// stack 2: the thing we want (hopefully) or junk
-	bne get_thread_area_failed
-		// stack 0: the thing we want
+	call procservice::get_register
+	bne PS_OK, get_register_failed
+
+	cast 0, int
+	shr I8_TS_RTA_SCALE
+	call procservice::get_thread_area
+	bne PS_OK, get_thread_area_failed
+
 	load TD_OK
-		// stack 0: TD_OK
-		// stack 1: the thing we want
 	return
 
 get_register_failed:
-		// stack 0: junk
-		// stack 1: procservice::get_thread_area
-		// stack 2: lwpid
 	load TD_ERR
-		// stack 0: TD_OK
-		// stack 1: junk
-		// stack 2: procservice::get_thread_area
-		// stack 3: lwpid
 	return
 
 get_thread_area_failed:
-		// stack 0: junk
 	load TD_ERR
-		// stack 0: TD_ERR
-		// stack 1: junk
 	return
diff --git a/nptl/infinity-map_lwp2thr.i8 b/nptl/infinity-map_lwp2thr.i8
index 51b21ea..344ea79 100644
--- a/nptl/infinity-map_lwp2thr.i8
+++ b/nptl/infinity-map_lwp2thr.i8
@@ -36,11 +36,8 @@
    are opaque pointers and should not be dereferenced outside
    of this library.  */
 
-define libpthread::map_lwp2thr returns td_err_e, ptr
+define libpthread::map_lwp2thr returns td_err_e, th_unique_t
 	argument lwpid_t lwpid
-	extern func td_err_e, ptr (lwpid_t) __lookup_th_unique
-	extern func pid_t () i8core::getpid
-	extern ptr __stack_user
 
   /* We cannot rely on thread registers and such information at all
      before __pthread_initialize_minimal has gotten far enough: they
@@ -49,73 +46,26 @@ define libpthread::map_lwp2thr returns td_err_e, ptr
      fake a special descriptor of NULL to indicate the initial thread.
      Other routines in this library recognise this special descriptor
      and act accordingly.  */
+	deref LIST_T_NEXT_OFFSET(__stack_user), ptr
+	beq NULL, libpthread_uninitialized
+	call __lookup_th_unique
+	return
 
-     		// stack 0: __stack_user
-		// stack 1: i8core::getpid
-		// stack 2: __lookup_th_unique
-		// stack 3: lwpid
-	load LIST_T_NEXT_OFFSET
-		// stack 0: LIST_T_NEXT_OFFSET
-		// stack 1: __stack_user
-		// stack 2: i8core::getpid
-		// stack 3: __lookup_th_unique
-		// stack 4: lwpid
-	add
-		// stack 0: __stack_user + LIST_T_NEXT_OFFSET
-		// stack 1: i8core::getpid
-		// stack 2: __lookup_th_unique
-		// stack 3: lwpid
-	deref ptr
-		// stack 0: __stack_user->next
-		// stack 1: i8core::getpid
-		// stack 2: __lookup_th_unique
-		// stack 3: lwpid
-	load NULL
-	bne libpthread_is_initialized
+libpthread_uninitialized:
 
-initialization_is_incomplete:
-		// stack 0: i8core::getpid
-		// stack 1: __lookup_th_unique
-		// stack 2: lwpid
-	swap
-		// stack 0: __lookup_th_unique
-		// stack 1: i8core::getpid
-		// stack 2: lwpid
-	drop
-		// stack 0: i8core::getpid
-		// stack 1: lwpid
+  /* Load the pointer we'll return beneath lwpid.  I8C can't yet
+     hoist, but it'll optimize the branch away if we do the hoist
+     ourselves.  */
 	load NULL
-		// stack 0: NULL
-		// stack 1: i8core::getpid
-		// stack 2: lwpid
-	rot
-		// stack 0: i8core::getpid
-		// stack 1: lwpid
-		// stack 2: NULL
-	call
-		// stack 0: main pid
-		// stack 1: lwpid
-		// stack 2: NULL
+	swap
+
+	call procservice::getpid
 	beq is_main_thread
 
 not_main_thread:
-		// stack 0: NULL
 	load TD_ERR
 	return
 
 is_main_thread:
-		// stack 0: NULL
 	load TD_OK
 	return
-
-libpthread_is_initialized:
-		// stack 0: i8core::getpid
-		// stack 1: __lookup_th_unique
-		// stack 2: lwpid
-	drop
-		// stack 0: __lookup_th_unique
-		// stack 1: lwpid
-	call
-		// stack 0: TD_OK (or not)
-		// stack 1: descriptor (or junk)
-	return
diff --git a/nptl/infinity-nptl.i8 b/nptl/infinity-nptl.i8
index 62c6012..c12c810 100644
--- a/nptl/infinity-nptl.i8
+++ b/nptl/infinity-nptl.i8
@@ -32,5 +32,13 @@ typedef s32 td_err_e
 typedef s32 ps_err_e
 
 /* XXX.  */
-typedef func ps_err_e, ptr (lwpid_t, int, int) ps_getreg_f
-typedef func ps_err_e, ptr (lwpid_t, int) ps_get_ta_f
+typedef ptr th_unique_t
+
+/* XXX.  */
+extern ptr __stack_user
+extern ptr __stack_used
+
+/* XXX.  */
+extern func pid_t () procservice::getpid
+extern func ps_err_e, ptr (lwpid_t, int, int) procservice::get_register
+extern func ps_err_e, ptr (lwpid_t, int) procservice::get_thread_area
diff --git a/nptl/tst-infinity-map_lwp2thr.py b/nptl/tst-infinity-map_lwp2thr.py
index 6c7e37e..ab1c0d8 100644
--- a/nptl/tst-infinity-map_lwp2thr.py
+++ b/nptl/tst-infinity-map_lwp2thr.py
@@ -10,22 +10,21 @@ class TestMapLwp2Thr(TestCase):
     MAIN_PID = 30000
 
     def setUp(self):
-        # Create flags
+        # Set up the test address space for the __stack_user.next
+        # dereference.
+        with self.memory.builder() as mem:
+            stack_user = mem.alloc("__stack_user")
+            if self.STACK_USER_SETUP:
+                stack_user_next = mem.alloc()
+            else:
+                stack_user_next = NULL
+            stack_user.store_ptr(LIST_T_NEXT_OFFSET, stack_user_next)
+        # Initialize flags so we can see what was called.
         self.ps_get_register_called = False
         self.ps_get_thread_area_called = False
-        # Store the address of __stack_user
-        note = self.i8ctx.get_function(self.TESTFUNC)
-        symbols = note.external_pointers
-        self.assertEqual(len(symbols), 1)
-        self.stack_user_p = symbols[0]
-
-    def read_memory(self, fmt, addr):
-        # The only dereference we do is __stack_user.next
-        self.assertEqual(addr, self.stack_user_p + LIST_T_NEXT_OFFSET)
-        return struct.pack(fmt, self.STACK_USER_NEXT)
-
-    def call_i8core_getpid(self):
-        """Implementation of i8core::getpid."""
+
+    def call_procservice_getpid(self):
+        """Implementation of procservice::getpid."""
         return self.MAIN_PID
 
     def call_procservice_get_register(self, lwpid, offset, size):
@@ -62,7 +61,7 @@ class TestMapLwp2Thr(TestCase):
         return result
 
     def check_I8_TS_CONST_THREAD_AREA_result(self, result):
-        # The result is whatever ps_get_thread_area returned
+        # The result is whatever ps_get_thread_area returned.
         self.assertTrue(self.ps_get_thread_area_called)
         self.assertEqual(result[0], TD_OK)
         self.assertNotEqual(result[1], 0)
@@ -75,10 +74,10 @@ class TestMapLwp2Thr(TestCase):
         self.assertEqual(result[0], TD_OK)
         self.assertNotEqual(result[1], 0)
         bias = result[1] - self.PS_GETREG_RESULT[1]
-        self.assertLess(abs(bias), 16384)
+        self.assertLess(abs(bias), 0x10000)
 
     def check_I8_TS_REGISTER_THREAD_AREA_result(self, result):
-        # The result is whatever ps_get_thread_area returned
+        # The result is whatever ps_get_thread_area returned.
         self.assertTrue(self.ps_get_register_called)
         self.assertTrue(self.ps_get_thread_area_called)
         self.assertEqual(result[0], TD_OK)
@@ -86,63 +85,63 @@ class TestMapLwp2Thr(TestCase):
         self.assertEqual(result[1], self.PS_GET_TA_RESULT[1])
 
 class TestMapLwp2Thr_uninit(TestMapLwp2Thr):
-    STACK_USER_NEXT = NULL
+    STACK_USER_SETUP = False
 
-    def test_map_lwp2thr(self):
-        """map_lwp2thr (nptl uninitialized, lwpid == main PID)"""
+    def test_uninit(self):
+        """Test map_lwp2thr with NPTL uninitialized"""
         result = self.i8ctx.call(self.TESTFUNC, self.MAIN_PID)
         self.assertEqual(len(result), 2)
         self.assertEqual(result[0], TD_OK)
         self.assertEqual(result[1], NULL)
 
 class TestMapLwp2Thr_uninit_wrongpid(TestMapLwp2Thr):
-    STACK_USER_NEXT = NULL
+    STACK_USER_SETUP = False
 
-    def test_map_lwp2thr(self):
-        """map_lwp2thr (nptl uninitialized, lwpid != main PID)"""
+    def test_uninit_wrongpid(self):
+        """Test map_lwp2thr with NPTL uninitialized and lwpid != main pid"""
         result = self.i8ctx.call(self.TESTFUNC, self.MAIN_PID + 1)
         self.assertEqual(len(result), 2)
         self.assertEqual(result[0], TD_ERR)
 
-class TestMapLwp2Thr_init_getreg_fail(TestMapLwp2Thr):
-    STACK_USER_NEXT = 0x1fff
+class TestMapLwp2Thr_getreg_fail(TestMapLwp2Thr):
+    STACK_USER_SETUP = True
     PS_GETREG_RESULT = PS_ERR, 0x23ff00fa
     PS_GET_TA_RESULT = PS_OK, 0x89ab1234
 
-    def test_map_lwp2thr(self):
-        """map_lwp2thr (nptl initialized, ps_get_register fails)"""
+    def test_ps_getreg_fail(self):
+        """Check map_lwp2thr handles ps_get_register failures"""
         self.lwpid = self.MAIN_PID + 1
         result = self.i8ctx.call(self.TESTFUNC, self.lwpid)
         self.assertEqual(len(result), 2)
         if self.ps_get_register_called:
             self.assertEqual(result[0], TD_ERR)
         else:
-            # This failure isn't a problem for this platform
+            # This failure isn't a problem for this platform.
             self.check_I8_TS_CONST_THREAD_AREA_result(result)
 
-class TestMapLwp2Thr_init_gta_fail(TestMapLwp2Thr):
-    STACK_USER_NEXT = 0x1fff
+class TestMapLwp2Thr_gta_fail(TestMapLwp2Thr):
+    STACK_USER_SETUP = True
     PS_GETREG_RESULT = PS_OK, 0x23ff00fa
     PS_GET_TA_RESULT = PS_ERR, 0x89ab1234
 
-    def test_map_lwp2thr(self):
-        """map_lwp2thr (nptl initialized, ps_get_thread_area fails)"""
+    def test_ps_gta_fail(self):
+        """Check map_lwp2thr handles ps_get_thread_area failures"""
         self.lwpid = self.MAIN_PID + 1
         result = self.i8ctx.call(self.TESTFUNC, self.lwpid)
         self.assertEqual(len(result), 2)
         if self.ps_get_thread_area_called:
             self.assertEqual(result[0], TD_ERR)
         else:
-            # This failure isn't a problem for this platform
+            # This failure isn't a problem for this platform.
             self.check_I8_TS_REGISTER_result(result)
 
-class TestMapLwp2Thr_init_gta_ok(TestMapLwp2Thr):
-    STACK_USER_NEXT = 0x1fff
+class TestMapLwp2Thr_mainpath(TestMapLwp2Thr):
+    STACK_USER_SETUP = True
     PS_GETREG_RESULT = PS_OK, 0x23ff00fa
     PS_GET_TA_RESULT = PS_OK, 0x89ab1234
 
-    def test_map_lwp2thr(self):
-        """map_lwp2thr (nptl initialized, everything worked)"""
+    def test_mainpath(self):
+        """Test the main path through map_lwp2thr"""
         self.lwpid = self.MAIN_PID + 1
         result = self.i8ctx.call(self.TESTFUNC, self.lwpid)
         self.assertEqual(len(result), 2)

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=0880457e25e8f222fb0bc2e35236bef52d4f8040

commit 0880457e25e8f222fb0bc2e35236bef52d4f8040
Author: Gary Benson <gbenson@redhat.com>
Date:   Mon Sep 28 11:23:00 2015 +0100

    Export stack_used as __stack_used

diff --git a/nptl/allocatestack.c b/nptl/allocatestack.c
index c044b20..d384397 100644
--- a/nptl/allocatestack.c
+++ b/nptl/allocatestack.c
@@ -113,7 +113,8 @@ static int stack_cache_lock = LLL_LOCK_INITIALIZER;
 static LIST_HEAD (stack_cache);
 
 /* List of the stacks in use.  */
-static LIST_HEAD (stack_used);
+list_t (__stack_used) __attribute__ ((nocommon));
+hidden_data_def (__stack_used)
 
 /* We need to record what list operations we are going to do so that,
    in case of an asynchronous interruption due to a fork() call, we
@@ -223,7 +224,7 @@ get_cached_stack (size_t *sizep, void **memp)
   stack_list_del (&result->list);
 
   /* And add to the list of stacks in use.  */
-  stack_list_add (&result->list, &stack_used);
+  stack_list_add (&result->list, &__stack_used);
 
   /* And decrease the cache size.  */
   stack_cache_actsize -= result->stackblock_size;
@@ -592,7 +593,7 @@ allocate_stack (const struct pthread_attr *attr, struct pthread **pdp,
 	  lll_lock (stack_cache_lock, LLL_PRIVATE);
 
 	  /* And add to the list of stacks in use.  */
-	  stack_list_add (&pd->list, &stack_used);
+	  stack_list_add (&pd->list, &__stack_used);
 
 	  lll_unlock (stack_cache_lock, LLL_PRIVATE);
 
@@ -781,7 +782,7 @@ __make_stacks_executable (void **stack_endp)
   lll_lock (stack_cache_lock, LLL_PRIVATE);
 
   list_t *runp;
-  list_for_each (runp, &stack_used)
+  list_for_each (runp, &__stack_used)
     {
       err = change_stack_perm (list_entry (runp, struct pthread, list)
 #ifdef NEED_SEPARATE_REGISTER_STACK
@@ -838,8 +839,8 @@ __reclaim_stacks (void)
 	     pointers at the head of the list are inconsistent.  */
 	  list_t *l = NULL;
 
-	  if (stack_used.next->prev != &stack_used)
-	    l = &stack_used;
+	  if (__stack_used.next->prev != &__stack_used)
+	    l = &__stack_used;
 	  else if (stack_cache.next->prev != &stack_cache)
 	    l = &stack_cache;
 
@@ -861,7 +862,7 @@ __reclaim_stacks (void)
 
   /* Mark all stacks except the still running one as free.  */
   list_t *runp;
-  list_for_each (runp, &stack_used)
+  list_for_each (runp, &__stack_used)
     {
       struct pthread *curp = list_entry (runp, struct pthread, list);
       if (curp != self)
@@ -905,7 +906,7 @@ __reclaim_stacks (void)
     }
 
   /* Add the stack of all running threads to the cache.  */
-  list_splice (&stack_used, &stack_cache);
+  list_splice (&__stack_used, &stack_cache);
 
   /* Remove the entry for the current thread to from the cache list
      and add it to the list of running threads.  Which of the two
@@ -913,13 +914,13 @@ __reclaim_stacks (void)
   stack_list_del (&self->list);
 
   /* Re-initialize the lists for all the threads.  */
-  INIT_LIST_HEAD (&stack_used);
+  INIT_LIST_HEAD (&__stack_used);
   INIT_LIST_HEAD (&__stack_user);
 
   if (__glibc_unlikely (THREAD_GETMEM (self, user_stack)))
     list_add (&self->list, &__stack_user);
   else
-    list_add (&self->list, &stack_used);
+    list_add (&self->list, &__stack_used);
 
   /* There is one thread running.  */
   __nptl_nthreads = 1;
@@ -945,7 +946,7 @@ __find_thread_by_id (pid_t tid)
 
   /* Iterate over the list with system-allocated threads first.  */
   list_t *runp;
-  list_for_each (runp, &stack_used)
+  list_for_each (runp, &__stack_used)
     {
       struct pthread *curp;
 
@@ -1098,7 +1099,7 @@ __nptl_setxid (struct xid_command *cmdp)
 
   /* Iterate over the list with system-allocated threads first.  */
   list_t *runp;
-  list_for_each (runp, &stack_used)
+  list_for_each (runp, &__stack_used)
     {
       struct pthread *t = list_entry (runp, struct pthread, list);
       if (t == self)
@@ -1124,7 +1125,7 @@ __nptl_setxid (struct xid_command *cmdp)
     {
       signalled = 0;
 
-      list_for_each (runp, &stack_used)
+      list_for_each (runp, &__stack_used)
 	{
 	  struct pthread *t = list_entry (runp, struct pthread, list);
 	  if (t == self)
@@ -1154,7 +1155,7 @@ __nptl_setxid (struct xid_command *cmdp)
 
   /* Clean up flags, so that no thread blocks during exit waiting
      for a signal which will never come.  */
-  list_for_each (runp, &stack_used)
+  list_for_each (runp, &__stack_used)
     {
       struct pthread *t = list_entry (runp, struct pthread, list);
       if (t == self)
@@ -1218,7 +1219,7 @@ __pthread_init_static_tls (struct link_map *map)
 
   /* Iterate over the list with system-allocated threads first.  */
   list_t *runp;
-  list_for_each (runp, &stack_used)
+  list_for_each (runp, &__stack_used)
     init_one_static_tls (list_entry (runp, struct pthread, list), map);
 
   /* Now the list with threads using user-allocated stacks.  */
@@ -1239,7 +1240,7 @@ __wait_lookup_done (void)
 
   /* Iterate over the list with system-allocated threads first.  */
   list_t *runp;
-  list_for_each (runp, &stack_used)
+  list_for_each (runp, &__stack_used)
     {
       struct pthread *t = list_entry (runp, struct pthread, list);
       if (t == self || t->header.gscope_flag == THREAD_GSCOPE_FLAG_UNUSED)
diff --git a/nptl/descr.h b/nptl/descr.h
index 8e4938d..87c5354 100644
--- a/nptl/descr.h
+++ b/nptl/descr.h
@@ -160,7 +160,7 @@ struct pthread
     void *__padding[24];
   };
 
-  /* This descriptor's link on the `stack_used' or `__stack_user' list.  */
+  /* This descriptor's link on the `__stack_used' or `__stack_user' list.  */
   list_t list;
 
   /* Thread ID - which is also a 'is this thread descriptor (and
diff --git a/nptl/nptl-init.c b/nptl/nptl-init.c
index bdbdfed..9bde618 100644
--- a/nptl/nptl-init.c
+++ b/nptl/nptl-init.c
@@ -384,6 +384,7 @@ __pthread_initialize_minimal_internal (void)
   THREAD_SETMEM (pd, stackblock_size, (size_t) __libc_stack_end);
 
   /* Initialize the list of all running threads with the main thread.  */
+  INIT_LIST_HEAD (&__stack_used);
   INIT_LIST_HEAD (&__stack_user);
   list_add (&pd->list, &__stack_user);
 
diff --git a/nptl/pthreadP.h b/nptl/pthreadP.h
index 4edc74b..e762f94 100644
--- a/nptl/pthreadP.h
+++ b/nptl/pthreadP.h
@@ -183,7 +183,9 @@ extern int __is_smp attribute_hidden;
 
 /* Thread descriptor handling.  */
 extern list_t __stack_user;
+extern list_t __stack_used;
 hidden_proto (__stack_user)
+hidden_proto (__stack_used)
 
 /* Attribute handling.  */
 extern struct pthread_attr *__attr_list attribute_hidden;
diff --git a/nptl/pthread_create.c b/nptl/pthread_create.c
index 5216041..ec49b15 100644
--- a/nptl/pthread_create.c
+++ b/nptl/pthread_create.c
@@ -87,7 +87,7 @@ __find_in_stack_list (struct pthread *pd)
 
   lll_lock (stack_cache_lock, LLL_PRIVATE);
 
-  list_for_each (entry, &stack_used)
+  list_for_each (entry, &__stack_used)
     {
       struct pthread *curp;
 
diff --git a/nptl_db/structs.def b/nptl_db/structs.def
index a9b621b..ebcc065 100644
--- a/nptl_db/structs.def
+++ b/nptl_db/structs.def
@@ -70,7 +70,7 @@ DB_STRUCT (td_eventbuf_t)
 DB_STRUCT_FIELD (td_eventbuf_t, eventnum)
 DB_STRUCT_FIELD (td_eventbuf_t, eventdata)
 
-DB_SYMBOL (stack_used)
+DB_SYMBOL (__stack_used)
 DB_SYMBOL (__stack_user)
 DB_SYMBOL (nptl_version)
 DB_FUNCTION (__nptl_create_event)
diff --git a/nptl_db/td_ta_thr_iter.c b/nptl_db/td_ta_thr_iter.c
index a990fed..aae4dd2 100644
--- a/nptl_db/td_ta_thr_iter.c
+++ b/nptl_db/td_ta_thr_iter.c
@@ -38,15 +38,22 @@ iterate_thread_list (td_thragent_t *ta, td_thr_iter_f *callback,
   if (err != TD_OK)
     return err;
 
-  if (next == 0 && fake_empty)
+  if (next == 0)
     {
       /* __pthread_initialize_minimal has not run.  There is just the main
 	 thread to return.  We cannot rely on its thread register.  They
 	 sometimes contain garbage that would confuse us, left by the
 	 kernel at exec.  So if it looks like initialization is incomplete,
 	 we only fake a special descriptor for the initial thread.  */
-      td_thrhandle_t th = { ta, 0 };
-      return callback (&th, cbdata_p) != 0 ? TD_DBERR : TD_OK;
+      if (fake_empty)
+	{
+	  td_thrhandle_t th = { ta, 0 };
+
+	  if (callback (&th, cbdata_p) != 0)
+	    return TD_DBERR;
+	}
+
+      return TD_OK;
     }
 
   /* Cache the offset from struct pthread to its list_t member.  */
@@ -161,7 +168,7 @@ td_ta_thr_iter (const td_thragent_t *ta_arg, td_thr_iter_f *callback,
 
   /* And the threads with stacks allocated by the implementation.  */
   if (err == TD_OK)
-    err = DB_GET_SYMBOL (list, ta, stack_used);
+    err = DB_GET_SYMBOL (list, ta, __stack_used);
   if (err == TD_OK)
     err = iterate_thread_list (ta, callback, cbdata_p, state, ti_pri,
 			       list, false, pid);
diff --git a/nptl_db/td_thr_validate.c b/nptl_db/td_thr_validate.c
index f3c8a7b..34b6112 100644
--- a/nptl_db/td_thr_validate.c
+++ b/nptl_db/td_thr_validate.c
@@ -70,7 +70,7 @@ td_thr_validate (const td_thrhandle_t *th)
      using implementation allocated stacks.  */
   if (err == TD_NOTHR)
     {
-      err = DB_GET_SYMBOL (list, th->th_ta_p, stack_used);
+      err = DB_GET_SYMBOL (list, th->th_ta_p, __stack_used);
       if (err == TD_OK)
 	err = check_thread_list (th, list, &uninit);
 

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=f63ae9d71cfb13518de8f6f86fd75a7d5620adea

commit f63ae9d71cfb13518de8f6f86fd75a7d5620adea
Author: Gary Benson <gbenson@redhat.com>
Date:   Tue Oct 20 15:10:21 2015 +0100

    Add Infinity notes implementing td_ta_map_lwp2thr
    
    This commit adds the source code for the two Infinity notes that
    implement libthread_db's td_ta_map_lwp2thr function.  It also adds
    an I8X testcase for it, and hooks it into "make check".
    
    The build rules are conditional in that if I8C is not installed then
    no notes will be built; the resulting libpthread.so will be as before.
    If I8C is installed but I8X is not then the notes will be built but
    untested.  This combination is unlikely in practise as I8C and I8X are
    part of the same package.
    
    The source code is split into five files:
    
      infinity-nptl.i8 contains some common definitions and will
        be included by all other infinity-*.i8 files under nptl.
    
      infinity-map_lwp2thr.i8 contains "libpthread::map_lwp2thr",
        the note function that debuggers etc will call.
    
        Libraries that contain Infinity notes should provide
        documentation on the API of those notes.  For this note
        this is basically that it takes one argument, an integer
        specifying the LWPID of interest, and returns two results,
        an integer status code (one of libthread_db's: TD_OK, TD_ERR,
        etc) and a pointer which is the result of the call iff the
        returned status was TD_OK.  The returned pointer is undefined
        if the returned status was not TD_OK.
    
        A further part of libpthread::map_lwp2thr's API is that it
        requires two external functions: procservice::get_register
        and procservice::get_thread_area.
    
        (External functions must be defined *somehow* before this note may
        be executed, in much the same way that programs wishing to use
        libthread_db's td_ta_map_lwp2thr function must implement the
        proc_service functions it uses.  They could be Infinity notes
        from some other library, but in this case it's more likely that
        the program executing the note would provide them directly.)
    
      infinity-lookup_th_unique_{cta,reg,rta}.i8 contain
        "libpthread::__lookup_th_unique" for constant thread area,
        register, and register thread area platforms respectively.  This
        function is used by map_lwp2thr.  Which file is built depends on
        macros defined in the platform's tls.h.  The double-underscore
        preceeding its name indicates to note consumers that this function
        is not part of libpthread's exported Infinity API.  It will be
        part of the spec that consumers (i.e. programs that execute notes)
        must not call double-underscore functions directly.

diff --git a/nptl/Makefile b/nptl/Makefile
index 63976ec..7b5c7a9 100644
--- a/nptl/Makefile
+++ b/nptl/Makefile
@@ -138,6 +138,12 @@ libpthread-routines = nptl-init vars events version pt-interp \
 #		      pthread_setgid pthread_setegid pthread_setregid \
 #		      pthread_setresgid
 
+ifneq ($(I8C),no)
+infinity-routines = infinity-map_lwp2thr
+
+libpthread-routines += $(infinity-routines)
+endif
+
 libpthread-shared-only-routines = version pt-interp pt-allocrtsig \
 				  unwind-forcedunwind
 libpthread-static-only-routines = pthread_atfork
@@ -413,6 +419,26 @@ ifneq ($(have-cxx-thread_local),yes)
 tests-unsupported += tst-thread_local1
 endif
 
+tests += tst-infinity
+ifneq ($(I8C),no)
+ifneq ($(I8X),no)
+infinity-tests = $(addprefix tst-,$(addsuffix .py,$(infinity-routines)))
+
+$(objpfx)tst-infinity.out: $(objpfx)libpthread.so$(libpthread.so-version) \
+			   $(infinity-tests)
+	$(I8X) -i $< -I$(common-objpfx) $(infinity-tests) > $@; \
+	$(evaluate-test)
+
+tests-special += $(objpfx)tst-infinity.out
+else
+# I8X is not installed; the tests cannot be run.
+tests-unsupported += tst-infinity
+endif
+else
+# I8C is not installed; libpthread.so will not contain notes.
+tests-unsupported += tst-infinity
+endif
+
 include ../Rules
 
 ifeq (yes,$(build-shared))
diff --git a/nptl/infinity-lookup_th_unique_cta.i8 b/nptl/infinity-lookup_th_unique_cta.i8
new file mode 100644
index 0000000..0af457e
--- /dev/null
+++ b/nptl/infinity-lookup_th_unique_cta.i8
@@ -0,0 +1,61 @@
+/* Which thread is running on an LWP?
+   Copyright (C) 2003-2015 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+
+/* Given an lwpid_t identifying an LWP, return TD_OK and the
+   descriptor of the thread running on it, or a non-TD_OK
+   td_err_e code indicating the reason for failure and an
+   undefined value that must be ignored.  The caller must
+   ensure that __pthread_initialize_minimal has gotten far
+   enough; see the comments in infinity_map_lwp2thr.i8 for
+   specifics.  */
+
+define libpthread::__lookup_th_unique returns td_err_e, ptr
+	argument lwpid_t lwpid
+	extern ps_get_ta_f procservice::get_thread_area
+
+		// stack 0: procservice::get_thread_area
+		// stack 1: lwpid
+	load I8_TS_CTA_VALUE
+		// stack 0: I8_TS_CTA_VALUE
+		// stack 1: procservice::get_thread_area
+		// stack 2: lwpid
+	swap
+		// stack 0: procservice::get_thread_area
+		// stack 1: I8_TS_CTA_VALUE
+		// stack 2: lwpid
+	call
+		// stack 0: PS_OK (hopefully) or something else
+		// stack 1: the thing we want (hopefully) or junk
+	load PS_OK
+		// stack 0: PS_OK
+		// stack 1: PS_OK (hopefully) or something else
+		// stack 2: the thing we want (hopefully) or junk
+	bne get_thread_area_failed
+		// stack 0: the thing we want
+	load TD_OK
+		// stack 0: TD_OK
+		// stack 1: the thing we want
+	return
+
+get_thread_area_failed:
+		// stack 0: junk
+	load TD_ERR
+		// stack 0: TD_OK
+		// stack 1: junk
+	return
diff --git a/nptl/infinity-lookup_th_unique_reg.i8 b/nptl/infinity-lookup_th_unique_reg.i8
new file mode 100644
index 0000000..07aa3a0
--- /dev/null
+++ b/nptl/infinity-lookup_th_unique_reg.i8
@@ -0,0 +1,76 @@
+/* Which thread is running on an LWP?
+   Copyright (C) 2003-2015 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+
+/* Given an lwpid_t identifying an LWP, return TD_OK and the
+   descriptor of the thread running on it, or a non-TD_OK
+   td_err_e code indicating the reason for failure and an
+   undefined value that must be ignored.  The caller must
+   ensure that __pthread_initialize_minimal has gotten far
+   enough; see the comments in infinity_map_lwp2thr.i8 for
+   specifics.  */
+
+define libpthread::__lookup_th_unique returns td_err_e, ptr
+	argument lwpid_t lwpid
+	extern ps_getreg_f procservice::get_register
+
+		// stack 0: procservice::get_register
+		// stack 1: lwpid
+	load I8_TS_REG_OFFSET
+		// stack 0: I8_TS_REG_OFFSET
+		// stack 1: procservice::get_thread_area
+		// stack 2: lwpid
+	swap
+		// stack 0: procservice::get_thread_area
+		// stack 1: I8_TS_REG_OFFSET
+		// stack 2: lwpid
+	load I8_TS_REG_SIZE
+		// stack 0: I8_TS_REG_SIZE
+		// stack 1: procservice::get_thread_area
+		// stack 2: I8_TS_REG_OFFSET
+		// stack 3: lwpid
+	swap
+		// stack 1: procservice::get_thread_area
+		// stack 0: I8_TS_REG_SIZE
+		// stack 2: I8_TS_REG_OFFSET
+		// stack 3: lwpid
+	call
+		// stack 0: PS_OK (hopefully) or something else
+		// stack 1: contents of register (hopefully) or junk
+	load PS_OK
+		// stack 0: PS_OK
+		// stack 1: PS_OK (hopefully) or something else
+		// stack 2: contents of register (hopefully) or junk
+	bne get_register_failed
+		// stack 0: contents of register
+	load I8_TS_REG_BIAS
+		// stack 0: I8_TS_REG_BIAS
+		// stack 1: contents of register
+	add
+		// stack 0: biased contents of register
+	load TD_OK
+		// stack 0: TD_OK
+		// stack 1: biased contents of register
+	return
+
+get_register_failed:
+		// stack 0: junk
+	load TD_ERR
+		// stack 0: TD_OK
+		// stack 1: junk
+	return
diff --git a/nptl/infinity-lookup_th_unique_rta.i8 b/nptl/infinity-lookup_th_unique_rta.i8
new file mode 100644
index 0000000..d892566
--- /dev/null
+++ b/nptl/infinity-lookup_th_unique_rta.i8
@@ -0,0 +1,140 @@
+/* Which thread is running on an LWP?
+   Copyright (C) 2003-2015 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+
+/* Given an lwpid_t identifying an LWP, return TD_OK and the
+   descriptor of the thread running on it, or a non-TD_OK
+   td_err_e code indicating the reason for failure and an
+   undefined value that must be ignored.  The caller must
+   ensure that __pthread_initialize_minimal has gotten far
+   enough; see the comments in infinity_map_lwp2thr.i8 for
+   specifics.  */
+
+define libpthread::__lookup_th_unique returns td_err_e, ptr
+	argument lwpid_t lwpid
+	extern ps_getreg_f procservice::get_register
+	extern ps_get_ta_f procservice::get_thread_area
+
+		// stack 0: procservice::get_thread_area
+		// stack 1: procservice::get_reg
+		// stack 2: lwpid
+	load lwpid
+		// stack 0: lwpid
+		// stack 1: procservice::get_thread_area
+		// stack 2: procservice::get_reg
+		// stack 3: lwpid
+	rot
+		// stack 0: procservice::get_thread_area
+		// stack 1: procservice::get_reg
+		// stack 2: lwpid
+		// stack 3: lwpid
+	rot
+		// stack 0: procservice::get_reg
+		// stack 1: lwpid
+		// stack 2: procservice::get_thread_area
+		// stack 3: lwpid
+	load I8_TS_RTA_OFFSET
+		// stack 0: I8_TS_RTA_OFFSET
+		// stack 1: procservice::get_thread_area
+		// stack 2: lwpid
+		// stack 3: procservice::get_thread_area
+		// stack 4: lwpid
+	swap
+		// stack 0: procservice::get_thread_area
+		// stack 1: I8_TS_RTA_OFFSET
+		// stack 2: lwpid
+		// stack 3: procservice::get_thread_area
+		// stack 4: lwpid
+	load I8_TS_RTA_SIZE
+		// stack 0: I8_TS_RTA_SIZE
+		// stack 1: procservice::get_thread_area
+		// stack 2: I8_TS_RTA_OFFSET
+		// stack 3: lwpid
+		// stack 4: procservice::get_thread_area
+		// stack 5: lwpid
+	swap
+		// stack 0: procservice::get_thread_area
+		// stack 1: I8_TS_RTA_SIZE
+		// stack 2: I8_TS_RTA_OFFSET
+		// stack 3: lwpid
+		// stack 4: procservice::get_thread_area
+		// stack 5: lwpid
+	call
+		// stack 0: PS_OK (hopefully) or something else
+		// stack 1: contents of register (hopefully) or junk
+		// stack 2: procservice::get_thread_area
+		// stack 3: lwpid
+	load PS_OK
+		// stack 0: PS_OK
+		// stack 1: PS_OK (hopefully) or something else
+		// stack 2: contents of register (hopefully) or junk
+		// stack 3: procservice::get_thread_area
+		// stack 4: lwpid
+	bne get_register_failed
+		// stack 0: contents of register
+		// stack 1: procservice::get_thread_area
+		// stack 2: lwpid
+	cast 0 int
+		// stack 0: I8_TS_RTA_SCALE
+		// stack 1: contents of register
+		// stack 2: procservice::get_thread_area
+		// stack 3: lwpid
+	load I8_TS_RTA_SCALE
+		// stack 0: I8_TS_RTA_SCALE
+		// stack 1: contents of register
+		// stack 2: procservice::get_thread_area
+		// stack 3: lwpid
+	shr
+		// stack 0: scaled contents of register
+		// stack 1: procservice::get_thread_area
+		// stack 2: lwpid
+	swap
+		// stack 0: procservice::get_thread_area
+		// stack 1: scaled contents of register
+		// stack 2: lwpid
+	call
+		// stack 0: PS_OK (hopefully) or something else
+		// stack 1: the thing we want (hopefully) or junk
+	load PS_OK
+		// stack 0: PS_OK
+		// stack 1: PS_OK (hopefully) or something else
+		// stack 2: the thing we want (hopefully) or junk
+	bne get_thread_area_failed
+		// stack 0: the thing we want
+	load TD_OK
+		// stack 0: TD_OK
+		// stack 1: the thing we want
+	return
+
+get_register_failed:
+		// stack 0: junk
+		// stack 1: procservice::get_thread_area
+		// stack 2: lwpid
+	load TD_ERR
+		// stack 0: TD_OK
+		// stack 1: junk
+		// stack 2: procservice::get_thread_area
+		// stack 3: lwpid
+	return
+
+get_thread_area_failed:
+		// stack 0: junk
+	load TD_ERR
+		// stack 0: TD_ERR
+		// stack 1: junk
+	return
diff --git a/nptl/infinity-map_lwp2thr.i8 b/nptl/infinity-map_lwp2thr.i8
new file mode 100644
index 0000000..51b21ea
--- /dev/null
+++ b/nptl/infinity-map_lwp2thr.i8
@@ -0,0 +1,121 @@
+/* Which thread is running on an LWP?
+   Copyright (C) 2003-2015 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include "infinity-nptl.i8"
+#include "infinity-thread_self.h"
+
+#if I8_THREAD_SELF == I8_TS_CONST_THREAD_AREA
+# include "infinity-lookup_th_unique_cta.i8"
+#endif
+#if I8_THREAD_SELF == I8_TS_REGISTER
+# include "infinity-lookup_th_unique_reg.i8"
+#endif
+#if I8_THREAD_SELF == I8_TS_REGISTER_THREAD_AREA
+# include "infinity-lookup_th_unique_rta.i8"
+#endif
+
+/* Given an lwpid_t identifying an LWP, return TD_OK and the
+   descriptor of the thread running on it, or a non-TD_OK
+   td_err_e code indicating the reason for failure and an
+   undefined value that must be ignored.  Thread descriptors
+   are opaque pointers and should not be dereferenced outside
+   of this library.  */
+
+define libpthread::map_lwp2thr returns td_err_e, ptr
+	argument lwpid_t lwpid
+	extern func td_err_e, ptr (lwpid_t) __lookup_th_unique
+	extern func pid_t () i8core::getpid
+	extern ptr __stack_user
+
+  /* We cannot rely on thread registers and such information at all
+     before __pthread_initialize_minimal has gotten far enough: they
+     sometimes contain garbage left by the kernel at exec that would
+     confuse us.  If it looks like initialization is incomplete we
+     fake a special descriptor of NULL to indicate the initial thread.
+     Other routines in this library recognise this special descriptor
+     and act accordingly.  */
+
+     		// stack 0: __stack_user
+		// stack 1: i8core::getpid
+		// stack 2: __lookup_th_unique
+		// stack 3: lwpid
+	load LIST_T_NEXT_OFFSET
+		// stack 0: LIST_T_NEXT_OFFSET
+		// stack 1: __stack_user
+		// stack 2: i8core::getpid
+		// stack 3: __lookup_th_unique
+		// stack 4: lwpid
+	add
+		// stack 0: __stack_user + LIST_T_NEXT_OFFSET
+		// stack 1: i8core::getpid
+		// stack 2: __lookup_th_unique
+		// stack 3: lwpid
+	deref ptr
+		// stack 0: __stack_user->next
+		// stack 1: i8core::getpid
+		// stack 2: __lookup_th_unique
+		// stack 3: lwpid
+	load NULL
+	bne libpthread_is_initialized
+
+initialization_is_incomplete:
+		// stack 0: i8core::getpid
+		// stack 1: __lookup_th_unique
+		// stack 2: lwpid
+	swap
+		// stack 0: __lookup_th_unique
+		// stack 1: i8core::getpid
+		// stack 2: lwpid
+	drop
+		// stack 0: i8core::getpid
+		// stack 1: lwpid
+	load NULL
+		// stack 0: NULL
+		// stack 1: i8core::getpid
+		// stack 2: lwpid
+	rot
+		// stack 0: i8core::getpid
+		// stack 1: lwpid
+		// stack 2: NULL
+	call
+		// stack 0: main pid
+		// stack 1: lwpid
+		// stack 2: NULL
+	beq is_main_thread
+
+not_main_thread:
+		// stack 0: NULL
+	load TD_ERR
+	return
+
+is_main_thread:
+		// stack 0: NULL
+	load TD_OK
+	return
+
+libpthread_is_initialized:
+		// stack 0: i8core::getpid
+		// stack 1: __lookup_th_unique
+		// stack 2: lwpid
+	drop
+		// stack 0: __lookup_th_unique
+		// stack 1: lwpid
+	call
+		// stack 0: TD_OK (or not)
+		// stack 1: descriptor (or junk)
+	return
diff --git a/nptl/infinity-nptl.i8 b/nptl/infinity-nptl.i8
new file mode 100644
index 0000000..62c6012
--- /dev/null
+++ b/nptl/infinity-nptl.i8
@@ -0,0 +1,36 @@
+/* Common definitions for NPTL Infinity functions.
+   Copyright (C) 2015 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+/* libpthread and libthread_db generated constants.  */
+#include "infinity-nptl-constants.h"
+#include "infinity-nptl_db-constants.h"
+
+/* XXX.  */
+typedef int size_t
+
+/* XXX.  */
+typedef s32 pid_t
+typedef pid_t lwpid_t
+
+/* XXX.  */
+typedef s32 td_err_e
+typedef s32 ps_err_e
+
+/* XXX.  */
+typedef func ps_err_e, ptr (lwpid_t, int, int) ps_getreg_f
+typedef func ps_err_e, ptr (lwpid_t, int) ps_get_ta_f
diff --git a/nptl/tst-infinity-map_lwp2thr.py b/nptl/tst-infinity-map_lwp2thr.py
new file mode 100644
index 0000000..6c7e37e
--- /dev/null
+++ b/nptl/tst-infinity-map_lwp2thr.py
@@ -0,0 +1,155 @@
+from i8c.runtime import TestCase
+import struct
+
+TestCase.import_builtin_constants()
+TestCase.import_constants_from("infinity-nptl-constants.h")
+TestCase.import_constants_from("infinity-nptl_db-constants.h")
+
+class TestMapLwp2Thr(TestCase):
+    TESTFUNC = "libpthread::map_lwp2thr(i)ip"
+    MAIN_PID = 30000
+
+    def setUp(self):
+        # Create flags
+        self.ps_get_register_called = False
+        self.ps_get_thread_area_called = False
+        # Store the address of __stack_user
+        note = self.i8ctx.get_function(self.TESTFUNC)
+        symbols = note.external_pointers
+        self.assertEqual(len(symbols), 1)
+        self.stack_user_p = symbols[0]
+
+    def read_memory(self, fmt, addr):
+        # The only dereference we do is __stack_user.next
+        self.assertEqual(addr, self.stack_user_p + LIST_T_NEXT_OFFSET)
+        return struct.pack(fmt, self.STACK_USER_NEXT)
+
+    def call_i8core_getpid(self):
+        """Implementation of i8core::getpid."""
+        return self.MAIN_PID
+
+    def call_procservice_get_register(self, lwpid, offset, size):
+        """Implementation of procservice::get_register."""
+        self.assertFalse(self.ps_get_register_called)
+        result = getattr(self, "PS_GETREG_RESULT", None)
+        if result is None:
+            self.fail("unexpected ps_get_register")
+        self.assertEqual(lwpid, self.lwpid)
+        self.assertNotEqual(offset, self.lwpid)
+        self.assertGreaterEqual(offset, 0)
+        # We can't really say much about offset.  It's an offset into
+        # a prgregset_t structure, so it's probably not huge and it's
+        # probably aligned to the machine's wordsize.
+        self.assertLess(offset, 128 * 8) # =128 64-bit registers (IA-64)
+        bytes_per_word, check = divmod(self.i8ctx.wordsize, 8)
+        self.assertNotEqual(bytes_per_word, 0)
+        self.assertEqual(check, 0)
+        self.assertEqual(offset % bytes_per_word, 0)
+        self.assertIn(size, (8, 16, 32, 64))
+        self.assertLessEqual(size, self.i8ctx.wordsize)
+        self.ps_get_register_called = True
+        return result
+
+    def call_procservice_get_thread_area(self, lwpid, idx):
+        """Implementation of procservice::get_thread_area."""
+        self.assertFalse(self.ps_get_thread_area_called)
+        result = getattr(self, "PS_GET_TA_RESULT", None)
+        if result is None:
+            self.fail("unexpected ps_get_thread_area")
+        self.assertEqual(lwpid, self.lwpid)
+        self.assertNotEqual(idx, self.lwpid)
+        self.ps_get_thread_area_called = True
+        return result
+
+    def check_I8_TS_CONST_THREAD_AREA_result(self, result):
+        # The result is whatever ps_get_thread_area returned
+        self.assertTrue(self.ps_get_thread_area_called)
+        self.assertEqual(result[0], TD_OK)
+        self.assertNotEqual(result[1], 0)
+        self.assertEqual(result[1], self.PS_GET_TA_RESULT[1])
+
+    def check_I8_TS_REGISTER_result(self, result):
+        # The result is what ps_get_register returned with some
+        # bias added.  We'll assume the bias is fairly small.
+        self.assertTrue(self.ps_get_register_called)
+        self.assertEqual(result[0], TD_OK)
+        self.assertNotEqual(result[1], 0)
+        bias = result[1] - self.PS_GETREG_RESULT[1]
+        self.assertLess(abs(bias), 16384)
+
+    def check_I8_TS_REGISTER_THREAD_AREA_result(self, result):
+        # The result is whatever ps_get_thread_area returned
+        self.assertTrue(self.ps_get_register_called)
+        self.assertTrue(self.ps_get_thread_area_called)
+        self.assertEqual(result[0], TD_OK)
+        self.assertNotEqual(result[1], 0)
+        self.assertEqual(result[1], self.PS_GET_TA_RESULT[1])
+
+class TestMapLwp2Thr_uninit(TestMapLwp2Thr):
+    STACK_USER_NEXT = NULL
+
+    def test_map_lwp2thr(self):
+        """map_lwp2thr (nptl uninitialized, lwpid == main PID)"""
+        result = self.i8ctx.call(self.TESTFUNC, self.MAIN_PID)
+        self.assertEqual(len(result), 2)
+        self.assertEqual(result[0], TD_OK)
+        self.assertEqual(result[1], NULL)
+
+class TestMapLwp2Thr_uninit_wrongpid(TestMapLwp2Thr):
+    STACK_USER_NEXT = NULL
+
+    def test_map_lwp2thr(self):
+        """map_lwp2thr (nptl uninitialized, lwpid != main PID)"""
+        result = self.i8ctx.call(self.TESTFUNC, self.MAIN_PID + 1)
+        self.assertEqual(len(result), 2)
+        self.assertEqual(result[0], TD_ERR)
+
+class TestMapLwp2Thr_init_getreg_fail(TestMapLwp2Thr):
+    STACK_USER_NEXT = 0x1fff
+    PS_GETREG_RESULT = PS_ERR, 0x23ff00fa
+    PS_GET_TA_RESULT = PS_OK, 0x89ab1234
+
+    def test_map_lwp2thr(self):
+        """map_lwp2thr (nptl initialized, ps_get_register fails)"""
+        self.lwpid = self.MAIN_PID + 1
+        result = self.i8ctx.call(self.TESTFUNC, self.lwpid)
+        self.assertEqual(len(result), 2)
+        if self.ps_get_register_called:
+            self.assertEqual(result[0], TD_ERR)
+        else:
+            # This failure isn't a problem for this platform
+            self.check_I8_TS_CONST_THREAD_AREA_result(result)
+
+class TestMapLwp2Thr_init_gta_fail(TestMapLwp2Thr):
+    STACK_USER_NEXT = 0x1fff
+    PS_GETREG_RESULT = PS_OK, 0x23ff00fa
+    PS_GET_TA_RESULT = PS_ERR, 0x89ab1234
+
+    def test_map_lwp2thr(self):
+        """map_lwp2thr (nptl initialized, ps_get_thread_area fails)"""
+        self.lwpid = self.MAIN_PID + 1
+        result = self.i8ctx.call(self.TESTFUNC, self.lwpid)
+        self.assertEqual(len(result), 2)
+        if self.ps_get_thread_area_called:
+            self.assertEqual(result[0], TD_ERR)
+        else:
+            # This failure isn't a problem for this platform
+            self.check_I8_TS_REGISTER_result(result)
+
+class TestMapLwp2Thr_init_gta_ok(TestMapLwp2Thr):
+    STACK_USER_NEXT = 0x1fff
+    PS_GETREG_RESULT = PS_OK, 0x23ff00fa
+    PS_GET_TA_RESULT = PS_OK, 0x89ab1234
+
+    def test_map_lwp2thr(self):
+        """map_lwp2thr (nptl initialized, everything worked)"""
+        self.lwpid = self.MAIN_PID + 1
+        result = self.i8ctx.call(self.TESTFUNC, self.lwpid)
+        self.assertEqual(len(result), 2)
+        if self.ps_get_thread_area_called:
+            if self.ps_get_register_called:
+                self.check_I8_TS_REGISTER_THREAD_AREA_result(result)
+            else:
+                self.check_I8_TS_CONST_THREAD_AREA_result(result)
+        else:
+            self.check_I8_TS_REGISTER_result(result)

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=152cd352ec65ace04144787fdcf678a50dd62deb

commit 152cd352ec65ace04144787fdcf678a50dd62deb
Author: Gary Benson <gbenson@redhat.com>
Date:   Tue Oct 20 15:10:21 2015 +0100

    Add Makerules to build %.o and %.os from %.i8
    
    This commit adds make rules to build %.o and %.os files from %.i8
    Infinity note source code.
    
    In order to ensure the correct preprocessor and assembler are used
    for cross-builds the compilation is done in three stages.  The target
    preprocessor specified at ./configure time is used to preprocess the
    %.i8 source; I8C consumes this preprocessed source and emits assembly
    language; and finally the target assembler specified at ./configure
    time is used to assemble the generated assembly language into object
    code.
    
    I don't *think* the %.o and %.os files should differ (they don't
    contain "real" code, just PT_NOTE sections) but please tell me if
    I'm wrong and I will add a separate %.S -> %.os rule.

diff --git a/Makerules b/Makerules
index 53eabfa..45e9929 100644
--- a/Makerules
+++ b/Makerules
@@ -1539,6 +1539,22 @@ $(gpl2lgpl): %: $(..)gpl2lgpl.sed /home/gd/gnu/lib/%
 	mv -f $@-tmp $@
 endif
 endif
+
+$(objpfx)infinity-%.i8p: infinity-%.i8
+	$(CPP) -x c $(CFLAGS) $(CPPFLAGS) $^ -o $@
+
+$(objpfx)infinity-%.S: $(objpfx)infinity-%.i8p
+	$(I8C) -S -fpreprocessed $^ -o $@
+
+$(objpfx)infinity-%.o: $(objpfx)infinity-%.S
+	$(CC) -c $(CFLAGS) $(CPPFLAGS) $^ -o $@
+
+ifeq ($(build-shared),yes)
+$(objpfx)infinity-%.os: $(objpfx)infinity-%.o
+	cp -f $^ $@
+endif
+
+.PRECIOUS: $(addprefix $(objpfx)infinity-%,.i8p .S .o)
 
 # Local Variables:
 # mode: makefile

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=8796dd17828af37f649b33bb570c91327ebeb237

commit 8796dd17828af37f649b33bb570c91327ebeb237
Author: Gary Benson <gbenson@redhat.com>
Date:   Tue Oct 20 15:10:21 2015 +0100

    Add ./configure checks for I8C and I8X
    
    This commit adds ./configure checks for I8C (the Infinity note
    compiler) and I8X (the Infinity note execution environment,
    which is used by "make check").

diff --git a/config.make.in b/config.make.in
index 05ed6ec..0935f90 100644
--- a/config.make.in
+++ b/config.make.in
@@ -108,6 +108,8 @@ AUTOCONF = @AUTOCONF@
 OBJDUMP = @OBJDUMP@
 OBJCOPY = @OBJCOPY@
 READELF = @READELF@
+I8C = @I8C@
+I8X = @I8X@
 
 # Installation tools.
 INSTALL = @INSTALL@
diff --git a/configure b/configure
index 06ea87e..2244de9 100755
--- a/configure
+++ b/configure
@@ -590,6 +590,8 @@ ac_subst_vars='LTLIBOBJS
 LIBOBJS
 RELEASE
 VERSION
+I8X
+I8C
 mach_interface_list
 DEFINES
 static_nss
@@ -6542,6 +6544,94 @@ $as_echo "$libc_cv_pie_default" >&6; }
 
 
 
+# XXX
+for ac_prog in i8c
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_I8C+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$I8C"; then
+  ac_cv_prog_I8C="$I8C" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_I8C="$ac_prog"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+I8C=$ac_cv_prog_I8C
+if test -n "$I8C"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $I8C" >&5
+$as_echo "$I8C" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+  test -n "$I8C" && break
+done
+test -n "$I8C" || I8C="no"
+
+for ac_prog in i8x
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_I8X+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$I8X"; then
+  ac_cv_prog_I8X="$I8X" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_I8X="$ac_prog"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+I8X=$ac_cv_prog_I8X
+if test -n "$I8X"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $I8X" >&5
+$as_echo "$I8X" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+  test -n "$I8X" && break
+done
+test -n "$I8X" || I8X="no"
+
+
 VERSION=`sed -n -e 's/^#define VERSION "\([^"]*\)"/\1/p' < $srcdir/version.h`
 RELEASE=`sed -n -e 's/^#define RELEASE "\([^"]*\)"/\1/p' < $srcdir/version.h`
 
diff --git a/configure.ac b/configure.ac
index 3c766b7..a108d25 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1807,6 +1807,10 @@ AC_SUBST(DEFINES)
 dnl See sysdeps/mach/configure.ac for this variable.
 AC_SUBST(mach_interface_list)
 
+# XXX
+AC_CHECK_PROGS(I8C, i8c, no)
+AC_CHECK_PROGS(I8X, i8x, no)
+
 VERSION=`sed -n -e 's/^#define VERSION "\([^"]*\)"/\1/p' < $srcdir/version.h`
 RELEASE=`sed -n -e 's/^#define RELEASE "\([^"]*\)"/\1/p' < $srcdir/version.h`
 AC_SUBST(VERSION)

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=a77eba1f02bbdba8968f94cd527512ff99c612e2

commit a77eba1f02bbdba8968f94cd527512ff99c612e2
Author: Gary Benson <gbenson@redhat.com>
Date:   Tue Oct 20 15:10:20 2015 +0100

    New gen-as-const-headers infinity-nptl{,_db}-constants.h
    
    This commit adds two new generated assembler constants headers to
    export constants used while building libpthread.so and
    libthread_db.so.  It also adds a rule to build them to nptl/Makefile.
    
    I would prefer to have infinity-nptl_db-constants.sym in nptl_db
    and have it built by nptl_db/Makefile but the ordering of the build
    seems to make this impossible: nptl_db needs to be built after nptl,
    but infinity-nptl_db-constants.h is required to build the infinity
    notes for libpthread.so.  If it's possible to change this then I
    will.  In the meantime I had to add "breadcrumb" header files for
    nptl_db's proc_service.h and thread_db.h for use during the build.

diff --git a/include/proc_service.h b/include/proc_service.h
new file mode 100644
index 0000000..325082e
--- /dev/null
+++ b/include/proc_service.h
@@ -0,0 +1 @@
+#include <nptl_db/proc_service.h>
diff --git a/include/thread_db.h b/include/thread_db.h
new file mode 100644
index 0000000..518d79e
--- /dev/null
+++ b/include/thread_db.h
@@ -0,0 +1 @@
+#include <nptl_db/thread_db.h>
diff --git a/nptl/Makefile b/nptl/Makefile
index dc3ccab..63976ec 100644
--- a/nptl/Makefile
+++ b/nptl/Makefile
@@ -303,7 +303,9 @@ tests-nolibpthread = tst-unload
 gen-as-const-headers = pthread-errnos.sym \
 		       lowlevelcond.sym lowlevelrwlock.sym \
 		       unwindbuf.sym \
-		       lowlevelrobustlock.sym pthread-pi-defines.sym
+		       lowlevelrobustlock.sym pthread-pi-defines.sym \
+		       infinity-nptl-constants.sym \
+		       infinity-nptl_db-constants.sym
 
 
 LDFLAGS-pthread.so = -Wl,--enable-new-dtags,-z,nodelete,-z,initfirst
diff --git a/nptl/infinity-nptl-constants.sym b/nptl/infinity-nptl-constants.sym
new file mode 100644
index 0000000..898ee54
--- /dev/null
+++ b/nptl/infinity-nptl-constants.sym
@@ -0,0 +1,5 @@
+#include <list.h>
+
+-- structure offsets
+
+LIST_T_NEXT_OFFSET	offsetof (list_t, next)
diff --git a/nptl/infinity-nptl_db-constants.sym b/nptl/infinity-nptl_db-constants.sym
new file mode 100644
index 0000000..aed18ac
--- /dev/null
+++ b/nptl/infinity-nptl_db-constants.sym
@@ -0,0 +1,12 @@
+#include <thread_db.h>
+#include <proc_service.h>
+
+-- td_err_e values
+
+TD_OK
+TD_ERR
+
+-- ps_err_e values
+
+PS_OK
+PS_ERR

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=b25bd56e9ff733fc72e2236272af5c6bab9bc321

commit b25bd56e9ff733fc72e2236272af5c6bab9bc321
Author: Gary Benson <gbenson@redhat.com>
Date:   Tue Oct 20 15:10:20 2015 +0100

    New gen-as-const-header infinity-thread_self.h
    
    This commit adds a new generated assembler constants header
    infinity-thread_self.h, and adds a rule to build it to
    sysdeps/generic/Makefile.  sysdeps/$cpu/nptl/tls.h files are
    expected to define macros that mirror those defined for
    libthread_db.  infinity-thread_self.sym contains various
    compile-time checks to ensure a consistent set of Infinity
    macros is defined.

diff --git a/sysdeps/generic/Makefile b/sysdeps/generic/Makefile
index f68ac68..c6a4f57 100644
--- a/sysdeps/generic/Makefile
+++ b/sysdeps/generic/Makefile
@@ -26,3 +26,5 @@ sysdep_routines += framestate unwind-pe
 shared-only-routines += framestate unwind-pe
 endif
 endif
+
+gen-as-const-headers += infinity-thread_self.sym
diff --git a/sysdeps/generic/infinity-thread_self.sym b/sysdeps/generic/infinity-thread_self.sym
new file mode 100644
index 0000000..de68048
--- /dev/null
+++ b/sysdeps/generic/infinity-thread_self.sym
@@ -0,0 +1,74 @@
+#include <tls.h>
+
+-- Each machine's tls.h should define I8_THREAD_SELF to one of these.
+#define I8_TS_CONST_THREAD_AREA         1
+#define I8_TS_REGISTER                  2
+#define I8_TS_REGISTER_THREAD_AREA      3
+
+#ifndef I8_THREAD_SELF
+# error "tls.h must #define I8_THREAD_SELF"
+#endif
+
+-- If tls.h defined DB_THREAD_SELF_INCLUDE then we need to include it.
+#ifdef DB_THREAD_SELF_INCLUDE
+# include DB_THREAD_SELF_INCLUDE
+#endif
+
+#if I8_THREAD_SELF == I8_TS_CONST_THREAD_AREA
+# ifndef I8_TS_CTA_VALUE
+#  error "I8_TS_CONST_THREAD_AREA machines must #define I8_TS_CTA_VALUE"
+# endif
+#else
+# define I8_TS_CTA_VALUE -1
+#endif
+
+#if I8_THREAD_SELF == I8_TS_REGISTER
+# ifndef I8_TS_REG_SIZE
+#  error "I8_TS_REGISTER machines must #define I8_TS_REG_SIZE"
+# endif
+# ifndef I8_TS_REG_OFFSET
+#  error "I8_TS_REGISTER machines must #define I8_TS_REG_OFFSET"
+# endif
+# ifndef I8_TS_REG_BIAS
+#  error "I8_TS_REGISTER machines must #define I8_TS_REG_BIAS"
+# endif
+#else
+# define I8_TS_REG_SIZE -1
+# define I8_TS_REG_OFFSET -1
+# define I8_TS_REG_BIAS -1
+#endif
+
+#if I8_THREAD_SELF == I8_TS_REGISTER_THREAD_AREA
+# ifndef I8_TS_RTA_SIZE
+#  error "I8_TS_REGISTER_THREAD_AREA machines must #define I8_TS_RTA_SIZE"
+# endif
+# ifndef I8_TS_RTA_OFFSET
+#  error "I8_TS_REGISTER_THREAD_AREA machines must #define I8_TS_RTA_OFFSET"
+# endif
+# ifndef I8_TS_RTA_SCALE
+#  error "I8_TS_REGISTER_THREAD_AREA machines must #define I8_TS_RTA_SCALE"
+# endif
+#else
+# define I8_TS_RTA_SIZE -1
+# define I8_TS_RTA_OFFSET -1
+# define I8_TS_RTA_SCALE -1
+#endif
+
+
+-- Constants to export
+
+I8_THREAD_SELF
+
+I8_TS_CONST_THREAD_AREA
+I8_TS_REGISTER
+I8_TS_REGISTER_THREAD_AREA
+
+I8_TS_CTA_VALUE
+
+I8_TS_REG_SIZE
+I8_TS_REG_OFFSET
+I8_TS_REG_BIAS
+
+I8_TS_RTA_SIZE
+I8_TS_RTA_OFFSET
+I8_TS_RTA_SCALE

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=d869b3611f6e64dbd0a7751dd50689b51cafb33f

commit d869b3611f6e64dbd0a7751dd50689b51cafb33f
Author: Gary Benson <gbenson@redhat.com>
Date:   Tue Oct 20 15:10:20 2015 +0100

    Add Infinity THREAD_SELF macros to sysdeps/x86_64/nptl/tls.h
    
    This commit adds Infinity THREAD_SELF macros for x86_64.

diff --git a/sysdeps/x86_64/nptl/tls.h b/sysdeps/x86_64/nptl/tls.h
index 2b061a0..e941a36 100644
--- a/sysdeps/x86_64/nptl/tls.h
+++ b/sysdeps/x86_64/nptl/tls.h
@@ -190,6 +190,10 @@ typedef struct
 # define DB_THREAD_SELF_INCLUDE  <sys/reg.h> /* For the FS constant.  */
 # define DB_THREAD_SELF CONST_THREAD_AREA (64, FS)
 
+/* Magic for Infinity to know how to do THREAD_SELF.  */
+# define I8_THREAD_SELF I8_TS_CONST_THREAD_AREA
+# define I8_TS_CTA_VALUE FS
+
 /* Read member of the thread descriptor directly.  */
 # define THREAD_GETMEM(descr, member) \
   ({ __typeof (descr->member) __value;					      \

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=5052e933c34377b7b09d8d84b3db62f6786a9801

commit 5052e933c34377b7b09d8d84b3db62f6786a9801
Author: Gary Benson <gbenson@redhat.com>
Date:   Tue Oct 20 15:10:20 2015 +0100

    Add Infinity THREAD_SELF macros to sysdeps/tile/nptl/tls.h
    
    This commit adds Infinity THREAD_SELF macros for tile.

diff --git a/sysdeps/tile/nptl/tls.h b/sysdeps/tile/nptl/tls.h
index c908fb8..10e6d6e 100644
--- a/sysdeps/tile/nptl/tls.h
+++ b/sysdeps/tile/nptl/tls.h
@@ -131,6 +131,17 @@ register void *__thread_pointer asm ("tp");
   REGISTER (32, 32, REG_TP * 4, - TLS_TCB_OFFSET - TLS_PRE_TCB_SIZE)
 #endif
 
+/* Magic for Infinity to know how to do THREAD_SELF.  */
+# define I8_THREAD_SELF I8_TS_REGISTER
+# ifdef __tilegx__
+#   define I8_TS_REG_SIZE 64
+#   define I8_TS_REG_OFFSET REG_TP * 8
+# else
+#   define I8_TS_REG_SIZE 32
+#   define I8_TS_REG_OFFSET REG_TP * 4
+# endif
+# define I8_TS_REG_BIAS - TLS_TCB_OFFSET - TLS_PRE_TCB_SIZE
+
 /* Read member of the thread descriptor directly.  */
 # define THREAD_GETMEM(descr, member) (descr->member)
 

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=6709dd021b83dae464c54721918d8af0a3f556a8

commit 6709dd021b83dae464c54721918d8af0a3f556a8
Author: Gary Benson <gbenson@redhat.com>
Date:   Tue Oct 20 15:10:20 2015 +0100

    Add Infinity THREAD_SELF macros to sysdeps/sparc/nptl/tls.h
    
    This commit adds Infinity THREAD_SELF macros for sparc.

diff --git a/sysdeps/sparc/nptl/tls.h b/sysdeps/sparc/nptl/tls.h
index 08c0552..466fe7c 100644
--- a/sysdeps/sparc/nptl/tls.h
+++ b/sysdeps/sparc/nptl/tls.h
@@ -125,6 +125,17 @@ register struct pthread *__thread_self __asm__("%g7");
   REGISTER (32, 32, 10 * 4, 0) \
   REGISTER (64, __WORDSIZE, (6 * 8) + (__WORDSIZE==64?0:4), 0)
 
+/* Magic for Infinity to know how to do THREAD_SELF.  */
+# define I8_THREAD_SELF I8_TS_REGISTER
+# if __WORDSIZE == 32
+#  define I8_TS_REG_SIZE 32
+#  define I8_TS_REG_OFFSET 10 * 4
+# else
+#  define I8_TS_REG_SIZE __WORDSIZE
+#  define I8_TS_REG_OFFSET (6 * 8) + (__WORDSIZE==64?0:4)
+# endif
+# define I8_TS_REG_BIAS 0
+
 /* Access to data in the thread descriptor is easy.  */
 #define THREAD_GETMEM(descr, member) \
   descr->member

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=d3c7f0cc768e6dbe62ce6095d3480b30a8c84d55

commit d3c7f0cc768e6dbe62ce6095d3480b30a8c84d55
Author: Gary Benson <gbenson@redhat.com>
Date:   Tue Oct 20 15:10:20 2015 +0100

    Add Infinity THREAD_SELF macros to sysdeps/sh/nptl/tls.h
    
    This commit adds Infinity THREAD_SELF macros for sh.
    
    It's possible for this platform to put the Infinity macros before
    libthread_db's DB_THREAD_SELF, and define DB_THREAD_SELF in terms
    of the Infinity values, but I wasn't sure if it would be appropriate.

diff --git a/sysdeps/sh/nptl/tls.h b/sysdeps/sh/nptl/tls.h
index 6f128c9..33ead82 100644
--- a/sysdeps/sh/nptl/tls.h
+++ b/sysdeps/sh/nptl/tls.h
@@ -123,6 +123,12 @@ typedef struct
 # define DB_THREAD_SELF \
   REGISTER (32, 32, REG_GBR * 4, -sizeof (struct pthread))
 
+/* Magic for Infinity to know how to do THREAD_SELF.  */
+# define I8_THREAD_SELF I8_TS_REGISTER
+# define I8_TS_REG_SIZE 32
+# define I8_TS_REG_OFFSET REG_GBR * 4
+# define I8_TS_REG_BIAS -sizeof (struct pthread)
+
 /* Read member of the thread descriptor directly.  */
 # define THREAD_GETMEM(descr, member) (descr->member)
 

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=b9812352590795be8a39fe5189565c86c74e7fa4

commit b9812352590795be8a39fe5189565c86c74e7fa4
Author: Gary Benson <gbenson@redhat.com>
Date:   Tue Oct 20 15:10:20 2015 +0100

    Add Infinity THREAD_SELF macros to sysdeps/s390/nptl/tls.h
    
    This commit adds Infinity THREAD_SELF macros for s390.
    
    I was confused as to how the size for the 64-bit version of
    DB_THREAD_SELF used __WORDSIZE where the 32-bit version just
    has 32.  I've used __s390x__ as a conditional and used
    __WORDSIZE in the presumably 64-bit version for Infinity but
    please advise if this should be changed.

diff --git a/sysdeps/s390/nptl/tls.h b/sysdeps/s390/nptl/tls.h
index e4c3ec7..579575d 100644
--- a/sysdeps/s390/nptl/tls.h
+++ b/sysdeps/s390/nptl/tls.h
@@ -151,6 +151,16 @@ typedef struct
 # define DB_THREAD_SELF REGISTER (32, 32, 18 * 4, 0) \
 			REGISTER (64, __WORDSIZE, 18 * 8, 0)
 
+/* Magic for Infinity to know how to do THREAD_SELF.  */
+# define I8_THREAD_SELF I8_TS_REGISTER
+# if defined __s390x__
+#  define I8_TS_REG_SIZE __WORDSIZE
+#  define I8_TS_REG_OFFSET 18 * 8
+# else
+#  define I8_TS_REG_SIZE 32
+#  define I8_TS_REG_OFFSET 18 * 4
+# define I8_TS_REG_BIAS 0
+
 /* Access to data in the thread descriptor is easy.  */
 #define THREAD_GETMEM(descr, member) \
   descr->member

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=6c4e0b56dc14608a053081b705be167347a36965

commit 6c4e0b56dc14608a053081b705be167347a36965
Author: Gary Benson <gbenson@redhat.com>
Date:   Tue Oct 20 15:10:20 2015 +0100

    Add Infinity THREAD_SELF macros to sysdeps/powerpc/nptl/tls.h
    
    This commit adds Infinity THREAD_SELF macros for powerpc.

diff --git a/sysdeps/powerpc/nptl/tls.h b/sysdeps/powerpc/nptl/tls.h
index 0e889bc..cd2c7a4 100644
--- a/sysdeps/powerpc/nptl/tls.h
+++ b/sysdeps/powerpc/nptl/tls.h
@@ -184,6 +184,17 @@ register void *__thread_register __asm__ ("r13");
   REGISTER (64, 64, PT_THREAD_POINTER * 8,				      \
 	    - TLS_TCB_OFFSET - TLS_PRE_TCB_SIZE)
 
+/* Magic for Infinity to know how to do THREAD_SELF.  */
+# define I8_THREAD_SELF I8_TS_REGISTER
+# if defined __powerpc64__
+#   define I8_TS_REG_SIZE 64
+#   define I8_TS_REG_OFFSET PT_THREAD_POINTER * 8
+# else
+#   define I8_TS_REG_SIZE 32
+#   define I8_TS_REG_OFFSET PT_THREAD_POINTER * 4
+# endif
+# define I8_TS_REG_BIAS - TLS_TCB_OFFSET - TLS_PRE_TCB_SIZE
+
 /* Read member of the thread descriptor directly.  */
 # define THREAD_GETMEM(descr, member) ((void)(descr), (THREAD_SELF)->member)
 

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=11a2b41053bd77bd3949a6301eb1826f2244a6c2

commit 11a2b41053bd77bd3949a6301eb1826f2244a6c2
Author: Gary Benson <gbenson@redhat.com>
Date:   Tue Oct 20 15:10:20 2015 +0100

    Add Infinity THREAD_SELF macros to sysdeps/nios2/nptl/tls.h
    
    This commit adds Infinity THREAD_SELF macros for nios2.
    
    It's possible for this platform to put the Infinity macros before
    libthread_db's DB_THREAD_SELF, and define DB_THREAD_SELF in terms
    of the Infinity values, but I wasn't sure if it would be appropriate.

diff --git a/sysdeps/nios2/nptl/tls.h b/sysdeps/nios2/nptl/tls.h
index ad29ac5..2a4f41c 100644
--- a/sysdeps/nios2/nptl/tls.h
+++ b/sysdeps/nios2/nptl/tls.h
@@ -122,6 +122,12 @@ register struct pthread *__thread_self __asm__("r23");
 # define DB_THREAD_SELF \
   REGISTER (32, 32, 23 * 4, -TLS_PRE_TCB_SIZE - TLS_TCB_OFFSET)
 
+/* Magic for Infinity to know how to do THREAD_SELF.  */
+# define I8_THREAD_SELF I8_TS_REGISTER
+# define I8_TS_REG_SIZE 32
+# define I8_TS_REG_OFFSET 23 * 4
+# define I8_TS_REG_BIAS -TLS_PRE_TCB_SIZE - TLS_TCB_OFFSET
+
 /* Access to data in the thread descriptor is easy.  */
 # define THREAD_GETMEM(descr, member) \
   descr->member

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=9a4a9dbfdc213279e8da9eb4936a87bef5d11912

commit 9a4a9dbfdc213279e8da9eb4936a87bef5d11912
Author: Gary Benson <gbenson@redhat.com>
Date:   Tue Oct 20 15:10:20 2015 +0100

    Add Infinity THREAD_SELF macros to sysdeps/mips/nptl/tls.h
    
    This commit adds Infinity THREAD_SELF macros for mips.
    
    It's possible for this platform to put the Infinity macros before
    libthread_db's DB_THREAD_SELF, and define DB_THREAD_SELF in terms
    of the Infinity values, but I wasn't sure if it would be appropriate.

diff --git a/sysdeps/mips/nptl/tls.h b/sysdeps/mips/nptl/tls.h
index 10ca878..fd1960e 100644
--- a/sysdeps/mips/nptl/tls.h
+++ b/sysdeps/mips/nptl/tls.h
@@ -153,6 +153,10 @@ typedef struct
 # define DB_THREAD_SELF \
   CONST_THREAD_AREA (32, TLS_TCB_OFFSET + TLS_PRE_TCB_SIZE)
 
+/* Magic for Infinity to know how to do THREAD_SELF.  */
+# define I8_THREAD_SELF I8_TS_CONST_THREAD_AREA
+# define I8_TS_CTA_VALUE TLS_TCB_OFFSET + TLS_PRE_TCB_SIZE
+
 /* Access to data in the thread descriptor is easy.  */
 # define THREAD_GETMEM(descr, member) \
   descr->member

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=401be388c3697b20d8de57e2ff117784fe9b72ae

commit 401be388c3697b20d8de57e2ff117784fe9b72ae
Author: Gary Benson <gbenson@redhat.com>
Date:   Tue Oct 20 15:10:19 2015 +0100

    Add Infinity THREAD_SELF macros to sysdeps/microblaze/nptl/tls.h
    
    This commit adds Infinity THREAD_SELF macros for microblaze.
    
    It's possible for this platform to put the Infinity macros before
    libthread_db's DB_THREAD_SELF, and define DB_THREAD_SELF in terms
    of the Infinity values, but I wasn't sure if it would be appropriate.

diff --git a/sysdeps/microblaze/nptl/tls.h b/sysdeps/microblaze/nptl/tls.h
index 8376f50..5113bd9 100644
--- a/sysdeps/microblaze/nptl/tls.h
+++ b/sysdeps/microblaze/nptl/tls.h
@@ -110,6 +110,10 @@ typedef struct
 # define DB_THREAD_SELF \
   CONST_THREAD_AREA (32, sizeof (struct pthread))
 
+/* Magic for Infinity to know how to do THREAD_SELF.  */
+# define I8_THREAD_SELF I8_TS_CONST_THREAD_AREA
+# define I8_TS_CTA_VALUE sizeof (struct pthread)
+
 /* Read member of the thread descriptor directly.  */
 # define THREAD_GETMEM(descr, member) (descr->member)
 

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=b8af0477d8883680c8f3404401408e79de102005

commit b8af0477d8883680c8f3404401408e79de102005
Author: Gary Benson <gbenson@redhat.com>
Date:   Tue Oct 20 15:10:19 2015 +0100

    Add Infinity THREAD_SELF macros to sysdeps/m68k/nptl/tls.h
    
    This commit adds Infinity THREAD_SELF macros for m68k.
    
    It's possible for this platform to put the Infinity macros before
    libthread_db's DB_THREAD_SELF, and define DB_THREAD_SELF in terms
    of the Infinity values, but I wasn't sure if it would be appropriate.

diff --git a/sysdeps/m68k/nptl/tls.h b/sysdeps/m68k/nptl/tls.h
index f932282..72df5cb 100644
--- a/sysdeps/m68k/nptl/tls.h
+++ b/sysdeps/m68k/nptl/tls.h
@@ -129,6 +129,10 @@ extern void * __m68k_read_tp (void);
 # define DB_THREAD_SELF \
   CONST_THREAD_AREA (32, TLS_TCB_OFFSET + TLS_PRE_TCB_SIZE)
 
+/* Magic for Infinity to know how to do THREAD_SELF.  */
+# define I8_THREAD_SELF I8_TS_CONST_THREAD_AREA
+# define I8_TS_CTA_VALUE TLS_TCB_OFFSET + TLS_PRE_TCB_SIZE
+
 /* Access to data in the thread descriptor is easy.  */
 # define THREAD_GETMEM(descr, member) \
   descr->member

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=0ae8c768157d97b6cc87a832712cea7017dc0030

commit 0ae8c768157d97b6cc87a832712cea7017dc0030
Author: Gary Benson <gbenson@redhat.com>
Date:   Tue Oct 20 15:10:19 2015 +0100

    Add Infinity THREAD_SELF macros to sysdeps/ia64/nptl/tls.h
    
    This commit adds Infinity THREAD_SELF macros for ia64.
    
    It's possible for this platform to put the Infinity macros before
    libthread_db's DB_THREAD_SELF, and define DB_THREAD_SELF in terms
    of the Infinity values, but I wasn't sure if it would be appropriate.

diff --git a/sysdeps/ia64/nptl/tls.h b/sysdeps/ia64/nptl/tls.h
index 54fddf5..9e61bae 100644
--- a/sysdeps/ia64/nptl/tls.h
+++ b/sysdeps/ia64/nptl/tls.h
@@ -140,6 +140,12 @@ register struct pthread *__thread_self __asm__("r13");
 /* Magic for libthread_db to know how to do THREAD_SELF.  */
 # define DB_THREAD_SELF REGISTER (64, 64, 13 * 8, -TLS_PRE_TCB_SIZE)
 
+/* Magic for Infinity to know how to do THREAD_SELF.  */
+# define I8_THREAD_SELF I8_TS_REGISTER
+# define I8_TS_REG_SIZE 64
+# define I8_TS_REG_OFFSET 13 * 8
+# define I8_TS_REG_BIAS -TLS_PRE_TCB_SIZE
+
 /* Access to data in the thread descriptor is easy.  */
 #define THREAD_GETMEM(descr, member) \
   descr->member

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=da2433f7eac8fd8007cb3ec037c27c26240c10c2

commit da2433f7eac8fd8007cb3ec037c27c26240c10c2
Author: Gary Benson <gbenson@redhat.com>
Date:   Tue Oct 20 15:10:19 2015 +0100

    Add Infinity THREAD_SELF macros to sysdeps/i386/nptl/tls.h
    
    This commit adds Infinity THREAD_SELF macros for i386.

diff --git a/sysdeps/i386/nptl/tls.h b/sysdeps/i386/nptl/tls.h
index a6dfa9b..5c6635b 100644
--- a/sysdeps/i386/nptl/tls.h
+++ b/sysdeps/i386/nptl/tls.h
@@ -259,6 +259,17 @@ tls_fill_user_desc (union user_desc_init *desc,
   REGISTER_THREAD_AREA (32, offsetof (struct user_regs_struct, xgs), 3) \
   REGISTER_THREAD_AREA (64, 26 * 8, 3) /* x86-64's user_regs_struct->gs */
 
+/* Magic for Infinity to know how to do THREAD_SELF.  */
+# define I8_THREAD_SELF I8_TS_REGISTER_THREAD_AREA
+# ifdef __LP64__
+#  define I8_TS_RTA_SIZE 64
+#  define I8_TS_RTA_OFFSET 26 * 8 /* x86-64's user_regs_struct->gs */
+# else
+#  define I8_TS_RTA_SIZE 32
+#  define I8_TS_RTA_OFFSET offsetof (struct user_regs_struct, xgs)
+# endif
+# define I8_TS_RTA_SCALE 3
+
 
 /* Read member of the thread descriptor directly.  */
 # define THREAD_GETMEM(descr, member) \

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=d4f63cea3f1de267729b59b28e6fde67270be8f3

commit d4f63cea3f1de267729b59b28e6fde67270be8f3
Author: Gary Benson <gbenson@redhat.com>
Date:   Tue Oct 20 15:10:19 2015 +0100

    Add Infinity THREAD_SELF macros to sysdeps/hppa/nptl/tls.h
    
    This commit adds Infinity THREAD_SELF macros for hppa.
    
    It's possible for this platform to put the Infinity macros before
    libthread_db's DB_THREAD_SELF, and define DB_THREAD_SELF in terms
    of the Infinity values, but I wasn't sure if it would be appropriate.

diff --git a/sysdeps/hppa/nptl/tls.h b/sysdeps/hppa/nptl/tls.h
index 2e0c861..23ff464 100644
--- a/sysdeps/hppa/nptl/tls.h
+++ b/sysdeps/hppa/nptl/tls.h
@@ -117,6 +117,12 @@ typedef struct
 # define DB_THREAD_SELF \
   REGISTER (32, 32, 53 * 4, -sizeof (struct pthread))
 
+/* Magic for Infinity to know how to do THREAD_SELF.  */
+# define I8_THREAD_SELF I8_TS_REGISTER
+# define I8_TS_REG_SIZE 32
+# define I8_TS_REG_OFFSET 53 * 4
+# define I8_TS_REG_BIAS -sizeof (struct pthread)
+
 /* Access to data in the thread descriptor is easy.  */
 # define THREAD_GETMEM(descr, member) \
   descr->member

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=f1d67a9b206d080cff27a573f0e66c984a71ae17

commit f1d67a9b206d080cff27a573f0e66c984a71ae17
Author: Gary Benson <gbenson@redhat.com>
Date:   Tue Oct 20 15:10:19 2015 +0100

    Add Infinity THREAD_SELF macros to sysdeps/arm/nptl/tls.h
    
    This commit adds Infinity THREAD_SELF macros for arm.
    
    It's possible for this platform to put the Infinity macros before
    libthread_db's DB_THREAD_SELF, and define DB_THREAD_SELF in terms
    of the Infinity values, but I wasn't sure if it would be appropriate.

diff --git a/sysdeps/arm/nptl/tls.h b/sysdeps/arm/nptl/tls.h
index 1ef57d2..43f0ba6 100644
--- a/sysdeps/arm/nptl/tls.h
+++ b/sysdeps/arm/nptl/tls.h
@@ -99,6 +99,10 @@ typedef struct
 # define DB_THREAD_SELF \
   CONST_THREAD_AREA (32, sizeof (struct pthread))
 
+/* Magic for Infinity to know how to do THREAD_SELF.  */
+# define I8_THREAD_SELF I8_TS_CONST_THREAD_AREA
+# define I8_TS_CTA_VALUE sizeof (struct pthread)
+
 /* Access to data in the thread descriptor is easy.  */
 #define THREAD_GETMEM(descr, member) \
   descr->member

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=7fa2c9da506e1a0847ae2486714b77f79de69492

commit 7fa2c9da506e1a0847ae2486714b77f79de69492
Author: Gary Benson <gbenson@redhat.com>
Date:   Tue Oct 20 15:10:19 2015 +0100

    Add Infinity THREAD_SELF macros to sysdeps/alpha/nptl/tls.h
    
    This commit adds Infinity THREAD_SELF macros for alpha.
    
    It's possible for this platform to put the Infinity macros before
    libthread_db's DB_THREAD_SELF, and define DB_THREAD_SELF in terms
    of the Infinity values, but I wasn't sure if it would be appropriate.

diff --git a/sysdeps/alpha/nptl/tls.h b/sysdeps/alpha/nptl/tls.h
index 90d98e1..df076be 100644
--- a/sysdeps/alpha/nptl/tls.h
+++ b/sysdeps/alpha/nptl/tls.h
@@ -102,6 +102,12 @@ typedef struct
 # define DB_THREAD_SELF \
   REGISTER (64, 64, 32 * 8, -sizeof (struct pthread))
 
+/* Magic for Infinity to know how to do THREAD_SELF.  */
+# define I8_THREAD_SELF I8_TS_REGISTER
+# define I8_TS_REG_SIZE 64
+# define I8_TS_REG_OFFSET 32 * 8
+# define I8_TS_REG_BIAS -sizeof (struct pthread)
+
 /* Access to data in the thread descriptor is easy.  */
 #define THREAD_GETMEM(descr, member) \
   descr->member

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=dc15dd87bc09dbba2d36fe905b968413fe92771e

commit dc15dd87bc09dbba2d36fe905b968413fe92771e
Author: Gary Benson <gbenson@redhat.com>
Date:   Tue Oct 20 15:10:19 2015 +0100

    Add Infinity THREAD_SELF macros to sysdeps/aarch64/nptl/tls.h
    
    This commit adds Infinity THREAD_SELF macros for aarch64.

diff --git a/sysdeps/aarch64/nptl/tls.h b/sysdeps/aarch64/nptl/tls.h
index 95ea3f9..ad09e7a 100644
--- a/sysdeps/aarch64/nptl/tls.h
+++ b/sysdeps/aarch64/nptl/tls.h
@@ -106,7 +106,11 @@ typedef struct
 
 /* Magic for libthread_db to know how to do THREAD_SELF.  */
 # define DB_THREAD_SELF \
-  CONST_THREAD_AREA (64, sizeof (struct pthread))
+  CONST_THREAD_AREA (64, (struct pthread))
+
+/* Magic for Infinity to know how to do THREAD_SELF.  */
+# define I8_THREAD_SELF I8_TS_CONST_THREAD_AREA
+# define I8_TS_CTA_VALUE sizeof (struct pthread)
 
 /* Access to data in the thread descriptor is easy.  */
 # define THREAD_GETMEM(descr, member) \

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=f51412deade6e021c5c16189a2dc424bd685e38b

commit f51412deade6e021c5c16189a2dc424bd685e38b
Author: Gary Benson <gbenson@redhat.com>
Date:   Tue Oct 20 15:10:19 2015 +0100

    Add NT_GNU_INFINITY to elf.h
    
    This commit adds a new note type NT_GNU_INFINITY to elf.h.

diff --git a/elf/elf.h b/elf/elf.h
index 15f5a75..cceda8a 100644
--- a/elf/elf.h
+++ b/elf/elf.h
@@ -1123,6 +1123,9 @@ typedef struct
 /* Version note generated by GNU gold containing a version string.  */
 #define NT_GNU_GOLD_VERSION	4
 
+/* Debugger interface note.  */
+#define NT_GNU_INFINITY	5
+
 
 /* Move records.  */
 typedef struct

-----------------------------------------------------------------------


hooks/post-receive
-- 
GNU C Library master sources


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]