From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: "Linas Vepstas" Newsgroups: gmane.lisp.guile.bugs Subject: [PATCH] Final: thread lock nesting debugging Date: Sun, 16 Nov 2008 22:42:00 -0600 Message-ID: <3ae3aa420811162042n4b5d50e3i136a9f7b00262a69@mail.gmail.com> Reply-To: linasvepstas@gmail.com NNTP-Posting-Host: lo.gmane.org Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="----=_Part_29533_16888018.1226896920611" X-Trace: ger.gmane.org 1226896942 6391 80.91.229.12 (17 Nov 2008 04:42:22 GMT) X-Complaints-To: usenet@ger.gmane.org NNTP-Posting-Date: Mon, 17 Nov 2008 04:42:22 +0000 (UTC) To: bug-guile@gnu.org Original-X-From: bug-guile-bounces+guile-bugs=m.gmane.org@gnu.org Mon Nov 17 05:43:23 2008 Return-path: Envelope-to: guile-bugs@m.gmane.org Original-Received: from lists.gnu.org ([199.232.76.165]) by lo.gmane.org with esmtp (Exim 4.50) id 1L1vxH-0002RC-0M for guile-bugs@m.gmane.org; Mon, 17 Nov 2008 05:43:23 +0100 Original-Received: from localhost ([127.0.0.1]:47624 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1L1vw8-0002LY-LP for guile-bugs@m.gmane.org; Sun, 16 Nov 2008 23:42:08 -0500 Original-Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1L1vw3-0002Ko-KX for bug-guile@gnu.org; Sun, 16 Nov 2008 23:42:03 -0500 Original-Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1L1vw2-0002Kc-PU for bug-guile@gnu.org; Sun, 16 Nov 2008 23:42:03 -0500 Original-Received: from [199.232.76.173] (port=35372 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1L1vw2-0002KZ-KH for bug-guile@gnu.org; Sun, 16 Nov 2008 23:42:02 -0500 Original-Received: from yw-out-1718.google.com ([74.125.46.158]:6059) by monty-python.gnu.org with esmtp (Exim 4.60) (envelope-from ) id 1L1vw1-0005pq-VY for bug-guile@gnu.org; Sun, 16 Nov 2008 23:42:02 -0500 Original-Received: by yw-out-1718.google.com with SMTP id 9so1159166ywk.66 for ; Sun, 16 Nov 2008 20:42:00 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:received:received:message-id:date:from:reply-to :to:subject:mime-version:content-type; bh=ALnAwqkmByUDb+85aMGLnrVjFEyvwXDlF7eNpW766GQ=; b=FfSyq73N21buLEI07xyunoxe9ul8xlXzcDyGXeYGMYwi26HPPjZDgRS+psYbvIYY4m J9jl8P98oJ6xoukkU8FdibCJhG9/gGhTo/hblWkI17u/sSavumG6io1F69cO9ch6X+4E rNs3oPUqY+qCTPrFUH+NZD1l75DNOk8Ac4GjM= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=message-id:date:from:reply-to:to:subject:mime-version:content-type; b=SB4n9XH9BXxGZ8dgLnJ39XhFNQqdMotzyu/3v+5++Q+dvoHOItH3SXSHrwkmoSe/oA 0WvPcOuqlGjxBUqXR8mCdEeV/X0YCoSQRgcMZ2JUVTP/5dpGckd219VFAPZ1r+RpMGv2 fKyvyGB4P/odu4ypQi4vADg5TIZbB7V7y3W0U= Original-Received: by 10.100.122.12 with SMTP id u12mr1446358anc.78.1226896920620; Sun, 16 Nov 2008 20:42:00 -0800 (PST) Original-Received: by 10.100.249.18 with HTTP; Sun, 16 Nov 2008 20:42:00 -0800 (PST) X-detected-operating-system: by monty-python.gnu.org: GNU/Linux 2.6 (newer, 2) X-BeenThere: bug-guile@gnu.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "Bug reports for GUILE, GNU's Ubiquitous Extension Language" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Original-Sender: bug-guile-bounces+guile-bugs=m.gmane.org@gnu.org Errors-To: bug-guile-bounces+guile-bugs=m.gmane.org@gnu.org Xref: news.gmane.org gmane.lisp.guile.bugs:4104 Archived-At: ------=_Part_29533_16888018.1226896920611 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 7bit Content-Disposition: inline I've been seeing all sorts of deadlocks in guile, and so I wrote a small debugging utility to try to track down the problems. I'd like to see this patch included in future versions of guile. I found one bug with this tool, and have submitted a patch for that already. It looks like there's another bug involving signals -- there is a probably deadlock in garbage collection if a signal is sent at just the wrong time. The bug can be seen by enabling this patch, and then running 'make check'. I'm going to ignore this, as I'm not worried about signals right now. This is my "final" version of this patch, I'd sent a beta version a few days ago. Its "final" because I'm not anticipating any further changes. --linas Add a deadlock debugging facility to guile. Signed-off-by: Linas Vepstas --- config.h.in | 3 configure.in | 11 +++ libguile/Makefile.am | 2 libguile/debug-locks.c | 159 +++++++++++++++++++++++++++++++++++++++++++++ libguile/pthread-threads.h | 15 ++++ libguile/threads.c | 53 +++++++++++++++ libguile/threads.h | 8 ++ 7 files changed, 250 insertions(+), 1 deletion(-) Index: guile-1.8.5/libguile/pthread-threads.h =================================================================== --- guile-1.8.5.orig/libguile/pthread-threads.h 2008-11-16 18:57:19.000000000 -0600 +++ guile-1.8.5/libguile/pthread-threads.h 2008-11-16 18:57:48.000000000 -0600 @@ -91,6 +91,21 @@ extern pthread_mutexattr_t scm_i_pthread #define scm_i_scm_pthread_cond_wait scm_pthread_cond_wait #define scm_i_scm_pthread_cond_timedwait scm_pthread_cond_timedwait +#ifdef GUILE_DEBUG_LOCKS +#undef scm_i_pthread_mutex_lock +#define scm_i_pthread_mutex_lock(ARG) scm_i_pthread_mutex_lock_dbg(ARG, #ARG) + +#undef scm_i_pthread_mutex_unlock +#define scm_i_pthread_mutex_unlock(ARG) scm_i_pthread_mutex_unlock_dbg(ARG, #ARG) + +int scm_i_pthread_mutex_lock_dbg(pthread_mutex_t *, const char *); +int scm_i_pthread_mutex_unlock_dbg(pthread_mutex_t *, const char *); + +void prt_lockholders(void); +void prt_this_lockholder(void); + +#endif + #endif /* SCM_PTHREADS_THREADS_H */ /* Index: guile-1.8.5/libguile/threads.c =================================================================== --- guile-1.8.5.orig/libguile/threads.c 2008-11-16 18:57:19.000000000 -0600 +++ guile-1.8.5/libguile/threads.c 2008-11-16 18:57:48.000000000 -0600 @@ -441,6 +441,24 @@ guilify_self_1 (SCM_STACKITEM *base) SCM_SET_FREELIST_LOC (scm_i_freelist, &t->freelist); SCM_SET_FREELIST_LOC (scm_i_freelist2, &t->freelist2); +#ifdef GUILE_DEBUG_LOCKS + int i, j; + for(i=0; ilockname[i] = NULL; + t->lockmutex[i] = NULL; + for(j=0; jlockholder[i][j] = NULL; + } + } + if (scm_initialized_p == 0) + { + t->lockname[0] = "&scm_i_init_mutex"; + t->lockmutex[0] = &scm_i_init_mutex; + } +#endif + scm_i_pthread_setspecific (scm_i_thread_key, t); scm_i_pthread_mutex_lock (&t->heap_mutex); @@ -1624,8 +1642,21 @@ scm_i_thread_wake_up () scm_i_thread *t; scm_i_pthread_cond_broadcast (&wake_up_cond); +#ifndef GUILE_DEBUG_LOCKS for (t = all_threads; t; t = t->next_thread) scm_i_pthread_mutex_unlock (&t->heap_mutex); +#else + /* Unlock in reverse order from locking */ + scm_i_thread *tt = NULL; + while (tt != all_threads) + { + scm_i_thread *tp = NULL; + for (t = all_threads; t != tt; t = t->next_thread) + tp = t; + scm_i_pthread_mutex_unlock (&tp->heap_mutex); + tt = tp; + } +#endif scm_i_pthread_mutex_unlock (&thread_admin_mutex); scm_enter_guile ((scm_t_guile_ticket) SCM_I_CURRENT_THREAD); } @@ -1721,6 +1752,28 @@ scm_init_threads_default_dynamic_state ( scm_i_default_dynamic_state = scm_permanent_object (state); } +#ifdef GUILE_DEBUG_LOCKS +extern int guile_do_abort_on_badlock; + +void prt_one_lockholder(scm_i_thread *); +void prt_lockholders(void) +{ + scm_i_thread *t; + + if (!guile_do_abort_on_badlock) return; + + for (t = all_threads; t; t = t->next_thread) + { + prt_one_lockholder(t); + } +} + +void prt_this_lockholder(void) +{ + prt_one_lockholder(SCM_I_CURRENT_THREAD); +} +#endif + void scm_init_thread_procs () { Index: guile-1.8.5/libguile/threads.h =================================================================== --- guile-1.8.5.orig/libguile/threads.h 2008-11-16 18:57:19.000000000 -0600 +++ guile-1.8.5/libguile/threads.h 2008-11-16 18:57:48.000000000 -0600 @@ -108,6 +108,14 @@ typedef struct scm_i_thread { SCM_STACKITEM *top; jmp_buf regs; +#ifdef GUILE_DEBUG_LOCKS +#define LOCK_STACK_DEPTH 250 +#define TRACE_STACK_DEPTH 4 + const char *lockname[LOCK_STACK_DEPTH]; + char *lockholder[LOCK_STACK_DEPTH][TRACE_STACK_DEPTH]; + pthread_mutex_t *lockmutex[LOCK_STACK_DEPTH]; +#endif + } scm_i_thread; #define SCM_I_IS_THREAD(x) SCM_SMOB_PREDICATE (scm_tc16_thread, x) Index: guile-1.8.5/configure.in =================================================================== --- guile-1.8.5.orig/configure.in 2008-11-16 18:57:19.000000000 -0600 +++ guile-1.8.5/configure.in 2008-11-16 18:57:48.000000000 -0600 @@ -122,6 +122,13 @@ AC_ARG_ENABLE(debug-malloc, [Define this if you want to debug scm_must_malloc/realloc/free calls.]) fi) +AC_ARG_ENABLE(debug-locks, + [ --enable-debug-locks include thread lock debugging code], + if test "$enable_debug_locks" = y || test "$enable_debug_locks" = yes; then + AC_DEFINE(GUILE_DEBUG_LOCKS, 1, + [Define this if you want to debug pthread lock nesting and deadlock trouble.]) + fi) + SCM_I_GSC_GUILE_DEBUG=0 AC_ARG_ENABLE(guile-debug, [AC_HELP_STRING([--enable-guile-debug], @@ -263,6 +270,10 @@ if test "$enable_debug_malloc" = yes; th AC_LIBOBJ([debug-malloc]) fi +if test "$enable_debug_locks" = yes; then + AC_LIBOBJ([debug-locks]) +fi + if test "$enable_elisp" = yes; then SCM_I_GSC_ENABLE_ELISP=1 else Index: guile-1.8.5/config.h.in =================================================================== --- guile-1.8.5.orig/config.h.in 2008-11-16 18:57:19.000000000 -0600 +++ guile-1.8.5/config.h.in 2008-11-16 18:57:48.000000000 -0600 @@ -42,6 +42,9 @@ Boston, MA 02110-1301, USA. /* Define this if you want to debug scm_must_malloc/realloc/free calls. */ #undef GUILE_DEBUG_MALLOC +/* Define this if you want to debug thread locking and deadlocks. */ +#undef GUILE_DEBUG_LOCKS + /* The imaginary unit (positive square root of -1). */ #undef GUILE_I Index: guile-1.8.5/libguile/Makefile.am =================================================================== --- guile-1.8.5.orig/libguile/Makefile.am 2008-11-16 18:57:19.000000000 -0600 +++ guile-1.8.5/libguile/Makefile.am 2008-11-16 18:57:48.000000000 -0600 @@ -159,7 +159,7 @@ EXTRA_libguile_la_SOURCES = _scm.h \ inet_aton.c memmove.c putenv.c strerror.c \ dynl.c regex-posix.c \ filesys.c posix.c net_db.c socket.c \ - debug-malloc.c mkstemp.c \ + debug-locks.c debug-malloc.c mkstemp.c \ win32-uname.c win32-dirent.c win32-socket.c ## delete guile-snarf.awk from the installation bindir, in case it's Index: guile-1.8.5/libguile/debug-locks.c =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ guile-1.8.5/libguile/debug-locks.c 2008-11-16 20:36:22.000000000 -0600 @@ -0,0 +1,159 @@ +/* Copyright (C) 2008 Free Software Foundation, Inc. + * + * This 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. + * + * This 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 this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ +/* + * Utilities for tracing/debugging deadlocks. Conditionally compiled by + * requesting ./configure --enable-debug-locks. The functions here + * replace the pthred mutex lock and unlock routines to record where + * a lock is taken, by recording a short snippet of the stack. The + * logs of held locks are on a thread-by-thread basis, so that deadlocks + * across different threads can be debugged. + * + * The primary check is to make sure that locks are always unlocked in + * reverse order (nested order), as out-of-sequence locks typically + * result in deadlocks. One exception is made: if the lock is the + * thread heap_mutex lock (i.e. the lock that defines "guile mode"), + * its allowed to be unlocked in reversed sequence, as a special case. + * If a bad unlock sequence is detected, then abort is called, to put + * the system into the debugger. + * + * If guile still deadlocks, without triggering an error, you might + * find the prt_lockholders() function to be useful: from within gdb, + * just say "call prt_lockholders()" to list all locks held by all + * threads. + * + * CAUTION: Turning this on leads to a *severe* performance degradation. + */ + +#include +#include +#include "_scm.h" + +extern void prt_lockholders(void); + +int guile_do_abort_on_badlock = 0; + +void prt_one_lockholder(scm_i_thread *); +void prt_one_lockholder(scm_i_thread *t) +{ + int i, j; + + fprintf (stderr, "\nThread %p\n", (void *) t->pthread); + for (i=0; ilockname[i]) break; + fprintf(stderr, "%d: %s (%p) in:\n", i, t->lockname[i], t->lockmutex[i]); + for (j=0; jlockholder[i][j]) break; + fprintf(stderr, "\t%s\n", t->lockholder[i][j]); + } + } +} + + +int scm_i_pthread_mutex_lock_dbg(pthread_mutex_t *mtx, const char *lockstr) +{ + int i,j; + int rc = pthread_mutex_lock(mtx); + scm_i_thread *tp = SCM_I_CURRENT_THREAD; + + if (NULL == tp) + return rc; + + for (i=0; ilockname[i]) + { + void * b[TRACE_STACK_DEPTH+1]; + int sz = backtrace(b, TRACE_STACK_DEPTH+1); + char **s = backtrace_symbols(b, sz); + for (j=0; jlockholder[i][j] = strdup(s[j+1]); + } + tp->lockname[i] = lockstr; + tp->lockmutex[i] = mtx; + free (s); + break; + } + } + + if (LOCK_STACK_DEPTH <= i) + { + fprintf(stderr, "Error: thread is holding too many locks\n"); + prt_lockholders(); + if (guile_do_abort_on_badlock) abort(); + } + + return rc; +} + +int scm_i_pthread_mutex_unlock_dbg(pthread_mutex_t *mtx, const char * lockstr) +{ + int i,j; + + scm_i_thread *tp = SCM_I_CURRENT_THREAD; + if (NULL == tp) + return pthread_mutex_unlock(mtx); + + for(i=LOCK_STACK_DEPTH-1; i>=0; i--) + { + if (0x0 == tp->lockname[i]) + continue; + + /* Allows the crazy nested two-step invloving the heap_mutex */ + if ((tp->lockmutex[i] != mtx) && + ((tp->lockmutex[i] != &tp->heap_mutex) || (0 == i) || + (tp->lockmutex[i-1] != mtx))) + { + fprintf(stderr, "Error: unlocking is badly nested: " + "Attempting to unlock %s (%p)\n", + lockstr, mtx); + prt_one_lockholder(tp); + // prt_lockholders(); + if (guile_do_abort_on_badlock) abort(); + } + if (tp->lockmutex[i-1] == mtx) + { + tp->lockname[i-1] = tp->lockname[i]; + tp->lockmutex[i-1] = tp->lockmutex[i]; + for (j=0; jlockholder[i-1][j]; + tp->lockholder[i-1][j] = tp->lockholder[i][j]; + tp->lockholder[i][j] = tmp; + } + } + tp->lockname[i] = NULL; + tp->lockmutex[i] = NULL; + for (j=0; jlockholder[i][j]) free(tp->lockholder[i][j]); + tp->lockholder[i][j] = NULL; + } + break; + } + + if (0 > i) + { + fprintf(stderr, "Error: unlocking a lock that's not held\n"); + prt_lockholders(); + if (guile_do_abort_on_badlock) abort(); + } + + return pthread_mutex_unlock(mtx); +} ------=_Part_29533_16888018.1226896920611 Content-Type: text/x-diff; name=thread-dbg.patch Content-Transfer-Encoding: base64 X-Attachment-Id: f_fnmmpd5t0 Content-Disposition: attachment; filename=thread-dbg.patch U3ViamVjdDogW1BBVENIXSBGaW5hbDogdGhyZWFkIGxvY2sgbmVzdGluZyBkZWJ1Z2dpbmcKRGF0 ZTogMTYgTm92IDIwMDgKVG86IGJ1Zy1ndWlsZUBnbnUub3JnCgpJJ3ZlIGJlZW4gc2VlaW5nIGFs bCBzb3J0cyBvZiBkZWFkbG9ja3MgaW4gZ3VpbGUsIGFuZCBzbyBJIHdyb3RlIGEgc21hbGwKZGVi dWdnaW5nIHV0aWxpdHkgdG8gdHJ5IHRvIHRyYWNrIGRvd24gdGhlIHByb2JsZW1zLiAgSSdkIGxp a2UgdG8gc2VlCnRoaXMgcGF0Y2ggaW5jbHVkZWQgaW4gZnV0dXJlIHZlcnNpb25zIG9mIGd1aWxl LgoKSSBmb3VuZCBvbmUgYnVnIHdpdGggdGhpcyB0b29sLCBhbmQgaGF2ZSBzdWJtaXR0ZWQgYSBw YXRjaCBmb3IgdGhhdAphbHJlYWR5LiAgSXQgbG9va3MgbGlrZSB0aGVyZSdzIGFub3RoZXIgYnVn IGludm9sdmluZyBzaWduYWxzIC0tIAp0aGVyZSBpcyBhIHByb2JhYmx5IGRlYWRsb2NrIGluIGdh cmJhZ2UgY29sbGVjdGlvbiBpZiBhIHNpZ25hbAppcyBzZW50IGF0IGp1c3QgdGhlIHdyb25nIHRp bWUuIFRoZSBidWcgY2FuIGJlIHNlZW4gYnkgZW5hYmxpbmcKdGhpcyBwYXRjaCwgYW5kIHRoZW4g cnVubmluZyAnbWFrZSBjaGVjaycuICBJJ20gZ29pbmcgdG8gaWdub3JlCnRoaXMsIGFzIEknbSBu b3Qgd29ycmllZCBhYm91dCBzaWduYWxzIHJpZ2h0IG5vdy4KClRoaXMgaXMgbXkgImZpbmFsIiB2 ZXJzaW9uIG9mIHRoaXMgcGF0Y2gsIEknZCBzZW50IGEgYmV0YSB2ZXJzaW9uCmEgZmV3IGRheXMg YWdvLiBJdHMgImZpbmFsIiBiZWNhdXNlIEknbSBub3QgYW50aWNpcGF0aW5nIGFueSAKZnVydGhl ciBjaGFuZ2VzLgoKLS1saW5hcwoKQWRkIGEgZGVhZGxvY2sgZGVidWdnaW5nIGZhY2lsaXR5IHRv IGd1aWxlLgoKU2lnbmVkLW9mZi1ieTogTGluYXMgVmVwc3RhcyA8bGluYXN2ZXBzdGFzQGdtYWls LmNvbT4KCi0tLQogY29uZmlnLmguaW4gICAgICAgICAgICAgICAgfCAgICAzIAogY29uZmlndXJl LmluICAgICAgICAgICAgICAgfCAgIDExICsrKwogbGliZ3VpbGUvTWFrZWZpbGUuYW0gICAgICAg fCAgICAyIAogbGliZ3VpbGUvZGVidWctbG9ja3MuYyAgICAgfCAgMTU5ICsrKysrKysrKysrKysr KysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKwogbGliZ3VpbGUvcHRocmVhZC10aHJlYWRz LmggfCAgIDE1ICsrKysKIGxpYmd1aWxlL3RocmVhZHMuYyAgICAgICAgIHwgICA1MyArKysrKysr KysrKysrKysKIGxpYmd1aWxlL3RocmVhZHMuaCAgICAgICAgIHwgICAgOCArKwogNyBmaWxlcyBj aGFuZ2VkLCAyNTAgaW5zZXJ0aW9ucygrKSwgMSBkZWxldGlvbigtKQoKSW5kZXg6IGd1aWxlLTEu OC41L2xpYmd1aWxlL3B0aHJlYWQtdGhyZWFkcy5oCj09PT09PT09PT09PT09PT09PT09PT09PT09 PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLS0tIGd1aWxlLTEuOC41 Lm9yaWcvbGliZ3VpbGUvcHRocmVhZC10aHJlYWRzLmgJMjAwOC0xMS0xNiAxODo1NzoxOS4wMDAw MDAwMDAgLTA2MDAKKysrIGd1aWxlLTEuOC41L2xpYmd1aWxlL3B0aHJlYWQtdGhyZWFkcy5oCTIw MDgtMTEtMTYgMTg6NTc6NDguMDAwMDAwMDAwIC0wNjAwCkBAIC05MSw2ICs5MSwyMSBAQCBleHRl cm4gcHRocmVhZF9tdXRleGF0dHJfdCBzY21faV9wdGhyZWFkCiAjZGVmaW5lIHNjbV9pX3NjbV9w dGhyZWFkX2NvbmRfd2FpdCAgICAgICAgIHNjbV9wdGhyZWFkX2NvbmRfd2FpdAogI2RlZmluZSBz Y21faV9zY21fcHRocmVhZF9jb25kX3RpbWVkd2FpdCAgICBzY21fcHRocmVhZF9jb25kX3RpbWVk d2FpdAogCisjaWZkZWYgR1VJTEVfREVCVUdfTE9DS1MKKyN1bmRlZiBzY21faV9wdGhyZWFkX211 dGV4X2xvY2sKKyNkZWZpbmUgc2NtX2lfcHRocmVhZF9tdXRleF9sb2NrKEFSRykgc2NtX2lfcHRo cmVhZF9tdXRleF9sb2NrX2RiZyhBUkcsICNBUkcpCisKKyN1bmRlZiBzY21faV9wdGhyZWFkX211 dGV4X3VubG9jaworI2RlZmluZSBzY21faV9wdGhyZWFkX211dGV4X3VubG9jayhBUkcpIHNjbV9p X3B0aHJlYWRfbXV0ZXhfdW5sb2NrX2RiZyhBUkcsICNBUkcpCisKK2ludCBzY21faV9wdGhyZWFk X211dGV4X2xvY2tfZGJnKHB0aHJlYWRfbXV0ZXhfdCAqLCBjb25zdCBjaGFyICopOworaW50IHNj bV9pX3B0aHJlYWRfbXV0ZXhfdW5sb2NrX2RiZyhwdGhyZWFkX211dGV4X3QgKiwgY29uc3QgY2hh ciAqKTsKKwordm9pZCBwcnRfbG9ja2hvbGRlcnModm9pZCk7Cit2b2lkIHBydF90aGlzX2xvY2to b2xkZXIodm9pZCk7CisKKyNlbmRpZgorCiAjZW5kaWYgIC8qIFNDTV9QVEhSRUFEU19USFJFQURT X0ggKi8KIAogLyoKSW5kZXg6IGd1aWxlLTEuOC41L2xpYmd1aWxlL3RocmVhZHMuYwo9PT09PT09 PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09 PT09Ci0tLSBndWlsZS0xLjguNS5vcmlnL2xpYmd1aWxlL3RocmVhZHMuYwkyMDA4LTExLTE2IDE4 OjU3OjE5LjAwMDAwMDAwMCAtMDYwMAorKysgZ3VpbGUtMS44LjUvbGliZ3VpbGUvdGhyZWFkcy5j CTIwMDgtMTEtMTYgMTg6NTc6NDguMDAwMDAwMDAwIC0wNjAwCkBAIC00NDEsNiArNDQxLDI0IEBA IGd1aWxpZnlfc2VsZl8xIChTQ01fU1RBQ0tJVEVNICpiYXNlKQogICBTQ01fU0VUX0ZSRUVMSVNU X0xPQyAoc2NtX2lfZnJlZWxpc3QsICZ0LT5mcmVlbGlzdCk7CiAgIFNDTV9TRVRfRlJFRUxJU1Rf TE9DIChzY21faV9mcmVlbGlzdDIsICZ0LT5mcmVlbGlzdDIpOwogCisjaWZkZWYgR1VJTEVfREVC VUdfTE9DS1MKKyAgaW50IGksIGo7CisgIGZvcihpPTA7IGk8TE9DS19TVEFDS19ERVBUSDsgaSsr KQorICAgIHsKKyAgICAgIHQtPmxvY2tuYW1lW2ldID0gTlVMTDsKKyAgICAgIHQtPmxvY2ttdXRl eFtpXSA9IE5VTEw7CisgICAgICBmb3Ioaj0wOyBqPFRSQUNFX1NUQUNLX0RFUFRIOyBqKyspCisg ICAgICAgIHsKKyAgICAgICAgICB0LT5sb2NraG9sZGVyW2ldW2pdID0gTlVMTDsKKyAgICAgICAg fQorICAgIH0KKyAgaWYgKHNjbV9pbml0aWFsaXplZF9wID09IDApCisgICAgeworICAgICAgdC0+ bG9ja25hbWVbMF0gPSAiJnNjbV9pX2luaXRfbXV0ZXgiOworICAgICAgdC0+bG9ja211dGV4WzBd ID0gJnNjbV9pX2luaXRfbXV0ZXg7CisgICAgfQorI2VuZGlmCisKICAgc2NtX2lfcHRocmVhZF9z ZXRzcGVjaWZpYyAoc2NtX2lfdGhyZWFkX2tleSwgdCk7CiAKICAgc2NtX2lfcHRocmVhZF9tdXRl eF9sb2NrICgmdC0+aGVhcF9tdXRleCk7CkBAIC0xNjI0LDggKzE2NDIsMjEgQEAgc2NtX2lfdGhy ZWFkX3dha2VfdXAgKCkKICAgICAgIHNjbV9pX3RocmVhZCAqdDsKIAogICAgICAgc2NtX2lfcHRo cmVhZF9jb25kX2Jyb2FkY2FzdCAoJndha2VfdXBfY29uZCk7CisjaWZuZGVmIEdVSUxFX0RFQlVH X0xPQ0tTCiAgICAgICBmb3IgKHQgPSBhbGxfdGhyZWFkczsgdDsgdCA9IHQtPm5leHRfdGhyZWFk KQogCXNjbV9pX3B0aHJlYWRfbXV0ZXhfdW5sb2NrICgmdC0+aGVhcF9tdXRleCk7CisjZWxzZQor ICAgICAgLyogVW5sb2NrIGluIHJldmVyc2Ugb3JkZXIgZnJvbSBsb2NraW5nICovCisgICAgICBz Y21faV90aHJlYWQgKnR0ID0gTlVMTDsKKyAgICAgIHdoaWxlICh0dCAhPSBhbGxfdGhyZWFkcykK KyAgICAgICAgeworICAgICAgICAgIHNjbV9pX3RocmVhZCAqdHAgPSBOVUxMOworICAgICAgICAg IGZvciAodCA9IGFsbF90aHJlYWRzOyB0ICE9IHR0OyB0ID0gdC0+bmV4dF90aHJlYWQpCisgICAg ICAgICAgICAgdHAgPSB0OworICAgICAgICAgIHNjbV9pX3B0aHJlYWRfbXV0ZXhfdW5sb2NrICgm dHAtPmhlYXBfbXV0ZXgpOworICAgICAgICAgIHR0ID0gdHA7CisgICAgICAgIH0KKyNlbmRpZgog ICAgICAgc2NtX2lfcHRocmVhZF9tdXRleF91bmxvY2sgKCZ0aHJlYWRfYWRtaW5fbXV0ZXgpOwog ICAgICAgc2NtX2VudGVyX2d1aWxlICgoc2NtX3RfZ3VpbGVfdGlja2V0KSBTQ01fSV9DVVJSRU5U X1RIUkVBRCk7CiAgICAgfQpAQCAtMTcyMSw2ICsxNzUyLDI4IEBAIHNjbV9pbml0X3RocmVhZHNf ZGVmYXVsdF9keW5hbWljX3N0YXRlICgKICAgc2NtX2lfZGVmYXVsdF9keW5hbWljX3N0YXRlID0g c2NtX3Blcm1hbmVudF9vYmplY3QgKHN0YXRlKTsKIH0KIAorI2lmZGVmIEdVSUxFX0RFQlVHX0xP Q0tTCitleHRlcm4gaW50IGd1aWxlX2RvX2Fib3J0X29uX2JhZGxvY2s7CisKK3ZvaWQgcHJ0X29u ZV9sb2NraG9sZGVyKHNjbV9pX3RocmVhZCAqKTsKK3ZvaWQgcHJ0X2xvY2tob2xkZXJzKHZvaWQp Cit7CisgIHNjbV9pX3RocmVhZCAqdDsKKworICBpZiAoIWd1aWxlX2RvX2Fib3J0X29uX2JhZGxv Y2spIHJldHVybjsKKworICBmb3IgKHQgPSBhbGxfdGhyZWFkczsgdDsgdCA9IHQtPm5leHRfdGhy ZWFkKQorICAgIHsKKyAgICAgIHBydF9vbmVfbG9ja2hvbGRlcih0KTsKKyAgICB9Cit9CisKK3Zv aWQgcHJ0X3RoaXNfbG9ja2hvbGRlcih2b2lkKQoreworICBwcnRfb25lX2xvY2tob2xkZXIoU0NN X0lfQ1VSUkVOVF9USFJFQUQpOworfQorI2VuZGlmCisKIHZvaWQKIHNjbV9pbml0X3RocmVhZF9w cm9jcyAoKQogewpJbmRleDogZ3VpbGUtMS44LjUvbGliZ3VpbGUvdGhyZWFkcy5oCj09PT09PT09 PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09 PT0KLS0tIGd1aWxlLTEuOC41Lm9yaWcvbGliZ3VpbGUvdGhyZWFkcy5oCTIwMDgtMTEtMTYgMTg6 NTc6MTkuMDAwMDAwMDAwIC0wNjAwCisrKyBndWlsZS0xLjguNS9saWJndWlsZS90aHJlYWRzLmgJ MjAwOC0xMS0xNiAxODo1Nzo0OC4wMDAwMDAwMDAgLTA2MDAKQEAgLTEwOCw2ICsxMDgsMTQgQEAg dHlwZWRlZiBzdHJ1Y3Qgc2NtX2lfdGhyZWFkIHsKICAgU0NNX1NUQUNLSVRFTSAqdG9wOwogICBq bXBfYnVmIHJlZ3M7CiAKKyNpZmRlZiBHVUlMRV9ERUJVR19MT0NLUworI2RlZmluZSBMT0NLX1NU QUNLX0RFUFRIIDI1MAorI2RlZmluZSBUUkFDRV9TVEFDS19ERVBUSCA0CisgIGNvbnN0IGNoYXIg KmxvY2tuYW1lW0xPQ0tfU1RBQ0tfREVQVEhdOworICBjaGFyICpsb2NraG9sZGVyW0xPQ0tfU1RB Q0tfREVQVEhdW1RSQUNFX1NUQUNLX0RFUFRIXTsKKyAgcHRocmVhZF9tdXRleF90ICpsb2NrbXV0 ZXhbTE9DS19TVEFDS19ERVBUSF07CisjZW5kaWYKKwogfSBzY21faV90aHJlYWQ7CiAKICNkZWZp bmUgU0NNX0lfSVNfVEhSRUFEKHgpICAgIFNDTV9TTU9CX1BSRURJQ0FURSAoc2NtX3RjMTZfdGhy ZWFkLCB4KQpJbmRleDogZ3VpbGUtMS44LjUvY29uZmlndXJlLmluCj09PT09PT09PT09PT09PT09 PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLS0tIGd1 aWxlLTEuOC41Lm9yaWcvY29uZmlndXJlLmluCTIwMDgtMTEtMTYgMTg6NTc6MTkuMDAwMDAwMDAw IC0wNjAwCisrKyBndWlsZS0xLjguNS9jb25maWd1cmUuaW4JMjAwOC0xMS0xNiAxODo1Nzo0OC4w MDAwMDAwMDAgLTA2MDAKQEAgLTEyMiw2ICsxMjIsMTMgQEAgQUNfQVJHX0VOQUJMRShkZWJ1Zy1t YWxsb2MsCiAgICAgICBbRGVmaW5lIHRoaXMgaWYgeW91IHdhbnQgdG8gZGVidWcgc2NtX211c3Rf bWFsbG9jL3JlYWxsb2MvZnJlZSBjYWxscy5dKQogICBmaSkKIAorQUNfQVJHX0VOQUJMRShkZWJ1 Zy1sb2NrcywKKyAgWyAgLS1lbmFibGUtZGVidWctbG9ja3MgICAgaW5jbHVkZSB0aHJlYWQgbG9j ayBkZWJ1Z2dpbmcgY29kZV0sCisgIGlmIHRlc3QgIiRlbmFibGVfZGVidWdfbG9ja3MiID0geSB8 fCB0ZXN0ICIkZW5hYmxlX2RlYnVnX2xvY2tzIiA9IHllczsgdGhlbgorICAgIEFDX0RFRklORShH VUlMRV9ERUJVR19MT0NLUywgMSwKKyAgICAgIFtEZWZpbmUgdGhpcyBpZiB5b3Ugd2FudCB0byBk ZWJ1ZyBwdGhyZWFkIGxvY2sgbmVzdGluZyBhbmQgZGVhZGxvY2sgdHJvdWJsZS5dKQorICBmaSkK KwogU0NNX0lfR1NDX0dVSUxFX0RFQlVHPTAKIEFDX0FSR19FTkFCTEUoZ3VpbGUtZGVidWcsCiAg IFtBQ19IRUxQX1NUUklORyhbLS1lbmFibGUtZ3VpbGUtZGVidWddLApAQCAtMjYzLDYgKzI3MCwx MCBAQCBpZiB0ZXN0ICIkZW5hYmxlX2RlYnVnX21hbGxvYyIgPSB5ZXM7IHRoCiAgICBBQ19MSUJP QkooW2RlYnVnLW1hbGxvY10pCiBmaQogCitpZiB0ZXN0ICIkZW5hYmxlX2RlYnVnX2xvY2tzIiA9 IHllczsgdGhlbgorICAgQUNfTElCT0JKKFtkZWJ1Zy1sb2Nrc10pCitmaQorCiBpZiB0ZXN0ICIk ZW5hYmxlX2VsaXNwIiA9IHllczsgdGhlbgogICBTQ01fSV9HU0NfRU5BQkxFX0VMSVNQPTEKIGVs c2UKSW5kZXg6IGd1aWxlLTEuOC41L2NvbmZpZy5oLmluCj09PT09PT09PT09PT09PT09PT09PT09 PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLS0tIGd1aWxlLTEu OC41Lm9yaWcvY29uZmlnLmguaW4JMjAwOC0xMS0xNiAxODo1NzoxOS4wMDAwMDAwMDAgLTA2MDAK KysrIGd1aWxlLTEuOC41L2NvbmZpZy5oLmluCTIwMDgtMTEtMTYgMTg6NTc6NDguMDAwMDAwMDAw IC0wNjAwCkBAIC00Miw2ICs0Miw5IEBAIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSwgVVNBLgogLyog RGVmaW5lIHRoaXMgaWYgeW91IHdhbnQgdG8gZGVidWcgc2NtX211c3RfbWFsbG9jL3JlYWxsb2Mv ZnJlZSBjYWxscy4gKi8KICN1bmRlZiBHVUlMRV9ERUJVR19NQUxMT0MKIAorLyogRGVmaW5lIHRo aXMgaWYgeW91IHdhbnQgdG8gZGVidWcgdGhyZWFkIGxvY2tpbmcgYW5kIGRlYWRsb2Nrcy4gKi8K KyN1bmRlZiBHVUlMRV9ERUJVR19MT0NLUworCiAvKiBUaGUgaW1hZ2luYXJ5IHVuaXQgKHBvc2l0 aXZlIHNxdWFyZSByb290IG9mIC0xKS4gKi8KICN1bmRlZiBHVUlMRV9JCiAKSW5kZXg6IGd1aWxl LTEuOC41L2xpYmd1aWxlL01ha2VmaWxlLmFtCj09PT09PT09PT09PT09PT09PT09PT09PT09PT09 PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLS0tIGd1aWxlLTEuOC41Lm9y aWcvbGliZ3VpbGUvTWFrZWZpbGUuYW0JMjAwOC0xMS0xNiAxODo1NzoxOS4wMDAwMDAwMDAgLTA2 MDAKKysrIGd1aWxlLTEuOC41L2xpYmd1aWxlL01ha2VmaWxlLmFtCTIwMDgtMTEtMTYgMTg6NTc6 NDguMDAwMDAwMDAwIC0wNjAwCkBAIC0xNTksNyArMTU5LDcgQEAgRVhUUkFfbGliZ3VpbGVfbGFf U09VUkNFUyA9IF9zY20uaAkJXAogICAgIGluZXRfYXRvbi5jIG1lbW1vdmUuYyBwdXRlbnYuYyBz dHJlcnJvci5jCVwKICAgICBkeW5sLmMgcmVnZXgtcG9zaXguYwkJCVwKICAgICBmaWxlc3lzLmMg cG9zaXguYyBuZXRfZGIuYyBzb2NrZXQuYwkJXAotICAgIGRlYnVnLW1hbGxvYy5jIG1rc3RlbXAu YwlcCisgICAgZGVidWctbG9ja3MuYyBkZWJ1Zy1tYWxsb2MuYyBta3N0ZW1wLmMJXAogICAgIHdp bjMyLXVuYW1lLmMgd2luMzItZGlyZW50LmMgd2luMzItc29ja2V0LmMKIAogIyMgZGVsZXRlIGd1 aWxlLXNuYXJmLmF3ayBmcm9tIHRoZSBpbnN0YWxsYXRpb24gYmluZGlyLCBpbiBjYXNlIGl0J3MK SW5kZXg6IGd1aWxlLTEuOC41L2xpYmd1aWxlL2RlYnVnLWxvY2tzLmMKPT09PT09PT09PT09PT09 PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotLS0g L2Rldi9udWxsCTE5NzAtMDEtMDEgMDA6MDA6MDAuMDAwMDAwMDAwICswMDAwCisrKyBndWlsZS0x LjguNS9saWJndWlsZS9kZWJ1Zy1sb2Nrcy5jCTIwMDgtMTEtMTYgMjA6MzY6MjIuMDAwMDAwMDAw IC0wNjAwCkBAIC0wLDAgKzEsMTU5IEBACisvKiBDb3B5cmlnaHQgKEMpIDIwMDggRnJlZSBTb2Z0 d2FyZSBGb3VuZGF0aW9uLCBJbmMuCisgKgorICogVGhpcyBsaWJyYXJ5IGlzIGZyZWUgc29mdHdh cmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vcgorICogbW9kaWZ5IGl0IHVuZGVyIHRo ZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYworICogTGljZW5zZSBhcyBw dWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyCisgKiB2ZXJz aW9uIDIuMSBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVy c2lvbi4KKyAqCisgKiBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhh dCBpdCB3aWxsIGJlIHVzZWZ1bCwKKyAqIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91 dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mCisgKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklU TkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVQorICogTGVzc2VyIEdl bmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4KKyAqCisgKiBZb3Ugc2hvdWxk IGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCisg KiBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBG cmVlIFNvZnR3YXJlCisgKiBGb3VuZGF0aW9uLCBJbmMuLCA1MSBGcmFua2xpbiBTdHJlZXQsIEZp ZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBCisgKi8KKy8qCisgKiBVdGlsaXRp ZXMgZm9yIHRyYWNpbmcvZGVidWdnaW5nIGRlYWRsb2Nrcy4gQ29uZGl0aW9uYWxseSBjb21waWxl ZCBieQorICogcmVxdWVzdGluZyAuL2NvbmZpZ3VyZSAtLWVuYWJsZS1kZWJ1Zy1sb2Nrcy4gIFRo ZSBmdW5jdGlvbnMgaGVyZQorICogcmVwbGFjZSB0aGUgcHRocmVkIG11dGV4IGxvY2sgYW5kIHVu bG9jayByb3V0aW5lcyB0byByZWNvcmQgd2hlcmUKKyAqIGEgbG9jayBpcyB0YWtlbiwgYnkgcmVj b3JkaW5nIGEgc2hvcnQgc25pcHBldCBvZiB0aGUgc3RhY2suIFRoZQorICogbG9ncyBvZiBoZWxk IGxvY2tzIGFyZSBvbiBhIHRocmVhZC1ieS10aHJlYWQgYmFzaXMsIHNvIHRoYXQgZGVhZGxvY2tz CisgKiBhY3Jvc3MgZGlmZmVyZW50IHRocmVhZHMgY2FuIGJlIGRlYnVnZ2VkLgorICoKKyAqIFRo ZSBwcmltYXJ5IGNoZWNrIGlzIHRvIG1ha2Ugc3VyZSB0aGF0IGxvY2tzIGFyZSBhbHdheXMgdW5s b2NrZWQgaW4KKyAqIHJldmVyc2Ugb3JkZXIgKG5lc3RlZCBvcmRlciksIGFzIG91dC1vZi1zZXF1 ZW5jZSBsb2NrcyB0eXBpY2FsbHkKKyAqIHJlc3VsdCBpbiBkZWFkbG9ja3MuIE9uZSBleGNlcHRp b24gaXMgbWFkZTogaWYgdGhlIGxvY2sgaXMgdGhlCisgKiB0aHJlYWQgaGVhcF9tdXRleCBsb2Nr IChpLmUuIHRoZSBsb2NrIHRoYXQgZGVmaW5lcyAiZ3VpbGUgbW9kZSIpLAorICogaXRzIGFsbG93 ZWQgdG8gYmUgdW5sb2NrZWQgaW4gcmV2ZXJzZWQgc2VxdWVuY2UsIGFzIGEgc3BlY2lhbCBjYXNl LgorICogSWYgYSBiYWQgdW5sb2NrIHNlcXVlbmNlIGlzIGRldGVjdGVkLCB0aGVuIGFib3J0IGlz IGNhbGxlZCwgdG8gcHV0CisgKiB0aGUgc3lzdGVtIGludG8gdGhlIGRlYnVnZ2VyLgorICoKKyAq IElmIGd1aWxlIHN0aWxsIGRlYWRsb2Nrcywgd2l0aG91dCB0cmlnZ2VyaW5nIGFuIGVycm9yLCB5 b3UgbWlnaHQKKyAqIGZpbmQgdGhlIHBydF9sb2NraG9sZGVycygpIGZ1bmN0aW9uIHRvIGJlIHVz ZWZ1bDogZnJvbSB3aXRoaW4gZ2RiLAorICoganVzdCBzYXkgImNhbGwgcHJ0X2xvY2tob2xkZXJz KCkiIHRvIGxpc3QgYWxsIGxvY2tzIGhlbGQgYnkgYWxsCisgKiB0aHJlYWRzLgorICoKKyAqIENB VVRJT046IFR1cm5pbmcgdGhpcyBvbiBsZWFkcyB0byBhICpzZXZlcmUqIHBlcmZvcm1hbmNlIGRl Z3JhZGF0aW9uLgorICovCisKKyNpbmNsdWRlIDxwdGhyZWFkLmg+CisjaW5jbHVkZSA8ZXhlY2lu Zm8uaD4KKyNpbmNsdWRlICJfc2NtLmgiCisKK2V4dGVybiB2b2lkIHBydF9sb2NraG9sZGVycyh2 b2lkKTsKKworaW50IGd1aWxlX2RvX2Fib3J0X29uX2JhZGxvY2sgPSAwOworCit2b2lkIHBydF9v bmVfbG9ja2hvbGRlcihzY21faV90aHJlYWQgKik7Cit2b2lkIHBydF9vbmVfbG9ja2hvbGRlcihz Y21faV90aHJlYWQgKnQpCit7CisgIGludCBpLCBqOworCisgIGZwcmludGYgKHN0ZGVyciwgIlxu VGhyZWFkICVwXG4iLCAodm9pZCAqKSB0LT5wdGhyZWFkKTsKKyAgZm9yIChpPTA7IGk8TE9DS19T VEFDS19ERVBUSDsgaSsrKQorICAgIHsKKyAgICAgIGlmIChOVUxMID09IHQtPmxvY2tuYW1lW2ld KSBicmVhazsKKyAgICAgIGZwcmludGYoc3RkZXJyLCAiJWQ6ICVzICglcCkgaW46XG4iLCBpLCB0 LT5sb2NrbmFtZVtpXSwgdC0+bG9ja211dGV4W2ldKTsKKyAgICAgIGZvciAoaj0wOyBqPFRSQUNF X1NUQUNLX0RFUFRIOyBqKyspCisgICAgICAgIHsKKyAgICAgICAgICBpZiAoTlVMTCA9PSB0LT5s b2NraG9sZGVyW2ldW2pdKSBicmVhazsKKyAgICAgICAgICBmcHJpbnRmKHN0ZGVyciwgIlx0JXNc biIsIHQtPmxvY2tob2xkZXJbaV1bal0pOworICAgICAgICB9CisgICAgfQorfQorCisKK2ludCBz Y21faV9wdGhyZWFkX211dGV4X2xvY2tfZGJnKHB0aHJlYWRfbXV0ZXhfdCAqbXR4LCBjb25zdCBj aGFyICpsb2Nrc3RyKQoreworICBpbnQgaSxqOworICBpbnQgcmMgPSBwdGhyZWFkX211dGV4X2xv Y2sobXR4KTsKKyAgc2NtX2lfdGhyZWFkICp0cCA9IFNDTV9JX0NVUlJFTlRfVEhSRUFEOworCisg IGlmIChOVUxMID09IHRwKQorICAgICAgIHJldHVybiByYzsKKworICBmb3IgKGk9MDsgaTxMT0NL X1NUQUNLX0RFUFRIOyBpKyspCisgICAgeworICAgICAgaWYgKDB4MCA9PSB0cC0+bG9ja25hbWVb aV0pCisgICAgICAgIHsKKyAgICAgICAgICB2b2lkICogYltUUkFDRV9TVEFDS19ERVBUSCsxXTsK KyAgICAgICAgICBpbnQgc3ogPSBiYWNrdHJhY2UoYiwgVFJBQ0VfU1RBQ0tfREVQVEgrMSk7Cisg ICAgICAgICAgY2hhciAqKnMgPSBiYWNrdHJhY2Vfc3ltYm9scyhiLCBzeik7CisgICAgICAgICAg Zm9yIChqPTA7IGo8c3otMTsgaisrKQorICAgICAgICAgICAgeworICAgICAgICAgICAgICB0cC0+ bG9ja2hvbGRlcltpXVtqXSA9IHN0cmR1cChzW2orMV0pOworICAgICAgICAgICAgfQorICAgICAg ICAgIHRwLT5sb2NrbmFtZVtpXSA9IGxvY2tzdHI7CisgICAgICAgICAgdHAtPmxvY2ttdXRleFtp XSA9IG10eDsKKyAgICAgICAgICBmcmVlIChzKTsKKyAgICAgICAgICBicmVhazsKKyAgICAgICAg fQorICAgIH0KKworICBpZiAoTE9DS19TVEFDS19ERVBUSCA8PSBpKQorICAgIHsKKyAgICAgIGZw cmludGYoc3RkZXJyLCAiRXJyb3I6IHRocmVhZCBpcyBob2xkaW5nIHRvbyBtYW55IGxvY2tzXG4i KTsKKyAgICAgIHBydF9sb2NraG9sZGVycygpOworICAgICAgaWYgKGd1aWxlX2RvX2Fib3J0X29u X2JhZGxvY2spIGFib3J0KCk7CisgICAgfQorCisgIHJldHVybiByYzsKK30KKworaW50IHNjbV9p X3B0aHJlYWRfbXV0ZXhfdW5sb2NrX2RiZyhwdGhyZWFkX211dGV4X3QgKm10eCwgY29uc3QgY2hh ciAqIGxvY2tzdHIpCit7CisgIGludCBpLGo7CisKKyAgc2NtX2lfdGhyZWFkICp0cCA9IFNDTV9J X0NVUlJFTlRfVEhSRUFEOworICBpZiAoTlVMTCA9PSB0cCkKKyAgICAgIHJldHVybiBwdGhyZWFk X211dGV4X3VubG9jayhtdHgpOworCisgIGZvcihpPUxPQ0tfU1RBQ0tfREVQVEgtMTsgaT49MDsg aS0tKQorICAgIHsKKyAgICAgIGlmICgweDAgPT0gdHAtPmxvY2tuYW1lW2ldKQorICAgICAgICAg IGNvbnRpbnVlOworCisJCS8qIEFsbG93cyB0aGUgY3JhenkgbmVzdGVkIHR3by1zdGVwIGludmxv dmluZyB0aGUgaGVhcF9tdXRleCAqLworICAgICAgaWYgKCh0cC0+bG9ja211dGV4W2ldICE9IG10 eCkgJiYKKyAgICAgICAgICAoKHRwLT5sb2NrbXV0ZXhbaV0gIT0gJnRwLT5oZWFwX211dGV4KSB8 fCAoMCA9PSBpKSB8fAorICAgICAgICAgICAodHAtPmxvY2ttdXRleFtpLTFdICE9IG10eCkpKQor ICAgICAgICB7CisgICAgICAgICAgZnByaW50ZihzdGRlcnIsICJFcnJvcjogdW5sb2NraW5nIGlz IGJhZGx5IG5lc3RlZDogIgorICAgICAgICAgICAgICAgICAgICAgICAgICAiQXR0ZW1wdGluZyB0 byB1bmxvY2sgJXMgKCVwKVxuIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgbG9ja3N0ciwg bXR4KTsKKyAgICAgICAgICBwcnRfb25lX2xvY2tob2xkZXIodHApOworICAgICAgICAgIC8vIHBy dF9sb2NraG9sZGVycygpOworICAgICAgICAgIGlmIChndWlsZV9kb19hYm9ydF9vbl9iYWRsb2Nr KSBhYm9ydCgpOworICAgICAgICB9CisgICAgICBpZiAodHAtPmxvY2ttdXRleFtpLTFdID09IG10 eCkKKyAgICAgICAgeworICAgICAgICAgIHRwLT5sb2NrbmFtZVtpLTFdID0gdHAtPmxvY2tuYW1l W2ldOworICAgICAgICAgIHRwLT5sb2NrbXV0ZXhbaS0xXSA9IHRwLT5sb2NrbXV0ZXhbaV07Cisg ICAgICAgICAgZm9yIChqPTA7IGo8VFJBQ0VfU1RBQ0tfREVQVEg7IGorKykKKyAgICAgICAgICAg IHsKKyAgICAgICAgICAgICAgY2hhciAqIHRtcCA9IHRwLT5sb2NraG9sZGVyW2ktMV1bal07Cisg ICAgICAgICAgICAgIHRwLT5sb2NraG9sZGVyW2ktMV1bal0gPSB0cC0+bG9ja2hvbGRlcltpXVtq XTsKKyAgICAgICAgICAgICAgdHAtPmxvY2tob2xkZXJbaV1bal0gPSB0bXA7CisgICAgICAgICAg ICB9CisgICAgICAgIH0KKyAgICAgIHRwLT5sb2NrbmFtZVtpXSA9IE5VTEw7CisgICAgICB0cC0+ bG9ja211dGV4W2ldID0gTlVMTDsKKyAgICAgIGZvciAoaj0wOyBqPFRSQUNFX1NUQUNLX0RFUFRI OyBqKyspCisgICAgICAgIHsKKyAgICAgICAgICBpZih0cC0+bG9ja2hvbGRlcltpXVtqXSkgZnJl ZSh0cC0+bG9ja2hvbGRlcltpXVtqXSk7CisgICAgICAgICAgdHAtPmxvY2tob2xkZXJbaV1bal0g PSBOVUxMOworICAgICAgICB9CisgICAgICBicmVhazsKKyAgICB9CisKKyAgaWYgKDAgPiBpKQor ICAgIHsKKyAgICAgIGZwcmludGYoc3RkZXJyLCAiRXJyb3I6IHVubG9ja2luZyBhIGxvY2sgdGhh dCdzIG5vdCBoZWxkXG4iKTsKKyAgICAgIHBydF9sb2NraG9sZGVycygpOworICAgICAgaWYgKGd1 aWxlX2RvX2Fib3J0X29uX2JhZGxvY2spIGFib3J0KCk7CisgICAgfQorCisgIHJldHVybiBwdGhy ZWFkX211dGV4X3VubG9jayhtdHgpOworfQo= ------=_Part_29533_16888018.1226896920611--