Discussion:
[ast-developers] The crux with the |ast.tmp_*| variables...
Roland Mainz
2013-08-28 06:22:00 UTC
Permalink
Hi!

----

Olga Kryzhanovska and Jennifer Pioch dug-out a performance and
footprint killer: The |ast.tmp_*| variables... ;-(

The basic issue looks like this:
- the |ast| structure is a global variable
- accessing it on CPU architectures with only few registers or no
support for complex indirect accesses can quickly exhaust registers
(that's not 100% true... but the number of available registers which
could be used for other stuff becomes... limited)
- typically (for embedded architectures) |ast| is not part of the L1
data cache when other code has been walked for some time. Per Jenny on
ARM CPUs with <= 16k of data cache |ast.tmp_*| were 97.2% times
outside L1 when accessed the first time in a function running a simple
multibyte character test
- The AST macros accessing the |ast.tmp_*| variables look small but
consume more code than writing the same code as |static inline|
function because of the read/write "far" accesses to the |ast.tmp_*|
variables (avoiding accesses to |ast| is not possible but it should be
minimised and preferably restricted to read-only accesses).

Question is... how can be fix this ?

AFAIK one way is to turn the "offending" CPP macros into |static
inline| functions (compilers which do not support |inline| just define
the functions as |static| ... at the expense of producing less
optimised code). The amount of code used is either the same as the CPP
macros or even less because we can use temporary variables on the
stack instead of "far" read/write accesses to the |ast.tmp_*|
structure.
The other advantage would be that without the |ast.tmp_*|-variables
instrumentation tools like "valgrind" or Rational Purify can track
values much better...

I've attached (as "astksh20130814_no_ast_tmp001.diff.txt") a prototype
patch which does this for the |mbchar()| macro (with some ugly mess
caused by the issue that |register| variables don't have an address,
e.g. |&var| doesn't work) which gives an interesting footprint
reduction (note that you have to compile with gcc -Os + use strip(1)
(to remove any extra symbol/debug info stuff) to get valid results (ad
note that padding is likely hiding individual size reduction benefits,
e.g. the code itself may become smaller but the compiler may "pad" ELF
chunks a bit to make sure the size is some kind of multiple of 2**n)):
$ ls -l ./arch/linux.i386-64/bin/ksh*
-rwxr-xr-x 1 test001 users 1844952 Aug 28 07:27
./arch/linux.i386-64/bin/ksh_mbchar_cpp
-rwxr-xr-x 1 test001 users 1841880 Aug 28 07:03
./arch/linux.i386-64/bin/ksh_mbchar_inline

$ print $((1844952 - 1841880))
3072

3072 bytes saved... and killing-off the other |ast.tmp_*| variables
and replacing them with function-local variables may likely yield a
similar code reduction...

----

Bye,
Roland
--
__ . . __
(o.\ \/ /.o) roland.mainz at nrubsig.org
\__\/\/__/ MPEG specialist, C&&JAVA&&Sun&&Unix programmer
/O /==\ O\ TEL +49 641 3992797
(;O/ \/ \O;)
-------------- next part --------------
diff -r -u original/src/cmd/ksh93/edit/completion.c build_noasttmp/src/cmd/ksh93/edit/completion.c
--- original/src/cmd/ksh93/edit/completion.c 2012-08-03 20:47:02.000000000 +0200
+++ build_noasttmp/src/cmd/ksh93/edit/completion.c 2013-08-28 07:05:24.476837824 +0200
@@ -37,7 +37,7 @@

static char *fmtx(Shell_t *shp,const char *string)
{
- register const char *cp = string;
+ const char *cp = string;
register int n,c;
unsigned char *state = (unsigned char*)sh_lexstates[2];
int offset = stktell(shp->stk);
@@ -97,7 +97,7 @@
*/
static char *find_begin(char outbuff[], char *last, int endchar, int *type)
{
- register char *cp=outbuff, *bp, *xp;
+ char *cp=outbuff, *bp, *xp;
register int c,inquote = 0, inassign=0;
int mode=*type;
bp = outbuff;
@@ -208,7 +208,7 @@
{
struct comnod *comptr;
struct argnod *ap;
- register char *out;
+ char *out;
char *av[2], *begin , *dir=0;
int addstar=0, rval=0, var=0, strip=1;
int nomarkdirs = !sh_isoption(ep->sh,SH_MARKDIRS);
diff -r -u original/src/cmd/ksh93/edit/edit.c build_noasttmp/src/cmd/ksh93/edit/edit.c
--- original/src/cmd/ksh93/edit/edit.c 2013-08-02 17:37:12.000000000 +0200
+++ build_noasttmp/src/cmd/ksh93/edit/edit.c 2013-08-28 07:06:08.665065251 +0200
@@ -584,7 +584,7 @@
{
Shell_t *shp = ep->sh;
register char *pp;
- register char *last, *prev;
+ char *last, *prev;
char *ppmax;
int myquote = 0;
size_t n;
@@ -1379,7 +1379,7 @@

int ed_internal(const char *src, genchar *dest)
{
- register const unsigned char *cp = (unsigned char *)src;
+ const unsigned char *cp = (unsigned char *)src;
register int c;
register wchar_t *dp = (wchar_t*)dest;
if(dest == (genchar*)roundof(cp-(unsigned char*)0,sizeof(genchar)))
diff -r -u original/src/cmd/ksh93/sh/arith.c build_noasttmp/src/cmd/ksh93/sh/arith.c
--- original/src/cmd/ksh93/sh/arith.c 2013-08-12 16:43:47.000000000 +0200
+++ build_noasttmp/src/cmd/ksh93/sh/arith.c 2013-08-28 07:04:19.645571327 +0200
@@ -62,7 +62,7 @@
static Namval_t *scope(register Namval_t *np,register struct lval *lvalue,int assign)
{
register int flag = lvalue->flag;
- register char *sub=0, *cp=(char*)np;
+ char *sub=0, *cp=(char*)np;
register Namval_t *mp;
Shell_t *shp = lvalue->shp;
int flags = HASH_NOSCOPE|HASH_SCOPE|HASH_BUCKET;
diff -r -u original/src/cmd/ksh93/sh/macro.c build_noasttmp/src/cmd/ksh93/sh/macro.c
--- original/src/cmd/ksh93/sh/macro.c 2013-07-31 22:08:40.000000000 +0200
+++ build_noasttmp/src/cmd/ksh93/sh/macro.c 2013-08-28 07:07:27.822053070 +0200
@@ -1104,7 +1104,7 @@
{
register int c;
register int type=0; /* M_xxx */
- register char *v,*argp=0;
+ char *v,*argp=0;
register Namval_t *np = NIL(Namval_t*);
register int dolg=0, mode=0;
Lex_t *lp = (Lex_t*)mp->shp->lex_context;
@@ -2655,7 +2655,7 @@
#if SHOPT_MULTIBYTE
if(mbwide())
{
- register const char *str = string, *strmax=string+len;
+ const char *str = string, *strmax=string+len;
register int n=0;
mbinit();
if(len>0)
diff -r -u original/src/cmd/ksh93/sh/name.c build_noasttmp/src/cmd/ksh93/sh/name.c
--- original/src/cmd/ksh93/sh/name.c 2013-08-12 16:33:09.000000000 +0200
+++ build_noasttmp/src/cmd/ksh93/sh/name.c 2013-08-28 07:07:51.718256643 +0200
@@ -2151,7 +2151,7 @@

static int ja_size(char *str,int size,int type)
{
- register char *cp = str;
+ char *cp = str;
register int c, n=size;
register int outsize;
register char *oldcp=cp;
diff -r -u original/src/cmd/ksh93/sh/string.c build_noasttmp/src/cmd/ksh93/sh/string.c
--- original/src/cmd/ksh93/sh/string.c 2013-06-12 22:53:57.000000000 +0200
+++ build_noasttmp/src/cmd/ksh93/sh/string.c 2013-08-28 07:10:00.752758147 +0200
@@ -294,7 +294,7 @@
*/
static char *sh_fmtcsv(const char *string)
{
- register const char *cp = string;
+ const char *cp = string;
register int c;
int offset;
if(!cp)
@@ -330,7 +330,7 @@
*/
char *sh_fmtstr(const char *string, int quote)
{
- register const char *cp = string, *op;
+ const char *cp = string, *op;
register int c, state, type=quote;
int offset;
if(!cp)
@@ -483,7 +483,7 @@
*/
char *sh_fmtqf(const char *string, int single, int fold)
{
- register const char *cp = string;
+ const char *cp = string;
register const char *bp;
register const char *vp;
register int c;
@@ -684,10 +684,10 @@
}

#if SHOPT_MULTIBYTE
- int sh_strchr(const char *string, register const char *dp)
+ int sh_strchr(const char *string, const char *dp)
{
wchar_t c, d;
- register const char *cp=string;
+ const char *cp=string;
mbinit();
d = mbchar(dp);
mbinit();
@@ -722,9 +722,9 @@
*/
char *sh_checkid(char *str, char *last)
{
- register unsigned char *cp = (unsigned char*)str;
- register unsigned char *v = cp;
- register int c;
+ unsigned char *cp = (unsigned char*)str;
+ unsigned char *v = cp;
+ int c;
if(c=mbchar(cp),isaletter(c))
while(c=mbchar(cp),isaname(c));
if(c==']' && (!last || ((char*)cp==last)))
Only in build_noasttmp/src/cmd/ksh93/tests: arrays.sh
diff -r -u original/src/lib/libast/include/ast.h build_noasttmp/src/lib/libast/include/ast.h
--- original/src/lib/libast/include/ast.h 2013-08-09 17:26:20.000000000 +0200
+++ build_noasttmp/src/lib/libast/include/ast.h 2013-08-28 07:16:32.963513021 +0200
@@ -200,14 +200,46 @@
*/

#define mbmax() (ast.mb_cur_max)
-#define mberr() (ast.tmp_int<0)

#define mbcoll() (ast.mb_xfrm!=0)
#define mbwide() (mbmax()>1)

#define mb2wc(w,p,n) (*ast.mb_towc)(&(w),(char*)(p),(n))
+#if 1
+#define mbchar(p) _mbchar(&(p))
+static inline int _mbchar(char **p)
+{
+ int tmp;
+ wchar_t wc;
+
+ if (mbwide())
+ {
+ char *dp = *p;
+ if ((tmp=(*ast.mb_towc)(&wc, dp, mbmax()))>0)
+ {
+ dp+=tmp;
+ *p=dp;
+ return wc;
+ }
+ else
+ {
+ dp+=ast.mb_sync+1;
+ *p=dp;
+ return tmp;
+ }
+ }
+ else
+ {
+ return *(unsigned char*)((*p)++);
+ }
+}
+
+#define mbnchar(p,n) (mbwide()?((ast.tmp_int=(*ast.mb_towc)(&ast.tmp_wchar,(char*)(p),n))>0?((p+=ast.tmp_int),ast.tmp_wchar):(p+=ast.mb_sync+1,ast.tmp_int)):(*(unsigned char*)(p++)))
+
+#else
#define mbchar(p) (mbwide()?((ast.tmp_int=(*ast.mb_towc)(&ast.tmp_wchar,(char*)(p),mbmax()))>0?((p+=ast.tmp_int),ast.tmp_wchar):(p+=ast.mb_sync+1,ast.tmp_int)):(*(unsigned char*)(p++)))
#define mbnchar(p,n) (mbwide()?((ast.tmp_int=(*ast.mb_towc)(&ast.tmp_wchar,(char*)(p),n))>0?((p+=ast.tmp_int),ast.tmp_wchar):(p+=ast.mb_sync+1,ast.tmp_int)):(*(unsigned char*)(p++)))
+#endif
#define mbinit() (mbwide()?(*ast.mb_towc)((wchar_t*)0,(char*)0,mbmax()):0)
#define mbsize(p) (mbwide()?(*ast.mb_len)((char*)(p),mbmax()):((p),1))
#define mbnsize(p,n) (mbwide()?(*ast.mb_len)((char*)(p),n):((p),1))
diff -r -u original/src/lib/libast/regex/regcoll.c build_noasttmp/src/lib/libast/regex/regcoll.c
--- original/src/lib/libast/regex/regcoll.c 2012-05-11 16:43:14.000000000 +0200
+++ build_noasttmp/src/lib/libast/regex/regcoll.c 2013-08-28 06:47:07.356459448 +0200
@@ -39,7 +39,7 @@
*/

int
-regcollate(register const char* s, char** e, char* buf, size_t size, wchar_t* wc)
+regcollate(const char* s, char** e, char* buf, size_t size, wchar_t* wc)
{
register int c;
register char* b;
diff -r -u original/src/lib/libast/regex/regcomp.c build_noasttmp/src/lib/libast/regex/regcomp.c
--- original/src/lib/libast/regex/regcomp.c 2013-05-31 08:38:29.000000000 +0200
+++ build_noasttmp/src/lib/libast/regex/regcomp.c 2013-08-28 06:47:55.848910629 +0200
@@ -1031,11 +1031,11 @@
static Celt_t*
col(Celt_t* ce, int ic, unsigned char* bp, int bw, int bc, unsigned char* ep, int ew, int ec)
{
- register char* s;
- register unsigned char* k;
- register unsigned char* e;
- register int c;
- register int cc;
+ char* s;
+ unsigned char * k;
+ unsigned char * e;
+ int c;
+ int cc;
int bt;
int et;
Ckey_t key;
diff -r -u original/src/lib/libast/string/chresc.c build_noasttmp/src/lib/libast/string/chresc.c
--- original/src/lib/libast/string/chresc.c 2013-07-16 20:02:13.000000000 +0200
+++ build_noasttmp/src/lib/libast/string/chresc.c 2013-08-28 06:41:52.603543286 +0200
@@ -39,7 +39,7 @@
#endif

int
-chrexp(register const char* s, char** p, int* m, register int flags)
+chrexp(const char* s, char** p, int* m, register int flags)
{
register const char* q;
register int c;
diff -r -u original/src/lib/libast/string/fmtesc.c build_noasttmp/src/lib/libast/string/fmtesc.c
--- original/src/lib/libast/string/fmtesc.c 2011-01-27 22:20:45.000000000 +0100
+++ build_noasttmp/src/lib/libast/string/fmtesc.c 2013-08-28 06:46:17.186922496 +0200
@@ -47,18 +47,18 @@
char*
fmtquote(const char* as, const char* qb, const char* qe, size_t n, int flags)
{
- register unsigned char* s = (unsigned char*)as;
- register unsigned char* e = s + n;
- register char* b;
- register int c;
- register int m;
- register int escaped;
- register int spaced;
- register int doublequote;
- register int singlequote;
- int shell;
- char* f;
- char* buf;
+ unsigned char * s = (unsigned char*)as;
+ unsigned char * e = s + n;
+ char* b;
+ int c;
+ int m;
+ int escaped;
+ int spaced;
+ int doublequote;
+ int singlequote;
+ int shell;
+ char *f;
+ char *buf;

c = 4 * (n + 1);
if (qb)
diff -r -u original/src/lib/libcmd/join.c build_noasttmp/src/lib/libcmd/join.c
--- original/src/lib/libcmd/join.c 2012-01-10 19:54:21.000000000 +0100
+++ build_noasttmp/src/lib/libcmd/join.c 2013-08-28 06:57:54.183128798 +0200
@@ -298,7 +298,7 @@
register File_t* fp = &jp->file[index];
register Field_t* field = fp->fields;
register Field_t* fieldmax = field + fp->maxfields;
- register char* cp;
+ char* cp;
register int n;
char* tp;

@@ -816,7 +816,7 @@
b_join(int argc, char** argv, Shbltin_t* context)
{
register int n;
- register char* cp;
+ char* cp;
register Join_t* jp;
char* e;

diff -r -u original/src/lib/libcmd/paste.c build_noasttmp/src/lib/libcmd/paste.c
--- original/src/lib/libcmd/paste.c 2012-01-10 19:55:31.000000000 +0100
+++ build_noasttmp/src/lib/libcmd/paste.c 2013-08-28 06:52:05.263509322 +0200
@@ -176,7 +176,7 @@
{
register int n, sflag=0;
register Sfio_t *fp, **streams;
- register char *cp, *delim;
+ char *cp, *delim;
char *ep;
Delim_t *mp;
int dlen, dsiz;
diff -r -u original/src/lib/libcmd/rev.c build_noasttmp/src/lib/libcmd/rev.c
--- original/src/lib/libcmd/rev.c 2012-01-10 19:55:48.000000000 +0100
+++ build_noasttmp/src/lib/libcmd/rev.c 2013-08-28 06:52:37.669147613 +0200
@@ -60,7 +60,7 @@
static int rev_char(Sfio_t *in, Sfio_t *out)
{
register int c;
- register char *ep, *bp, *cp;
+ char *ep, *bp, *cp;
register wchar_t *wp, *xp;
register size_t n;
register size_t w;
diff -r -u original/src/lib/libcmd/uniq.c build_noasttmp/src/lib/libcmd/uniq.c
--- original/src/lib/libcmd/uniq.c 2012-03-08 02:38:36.000000000 +0100
+++ build_noasttmp/src/lib/libcmd/uniq.c 2013-08-28 06:53:11.215842002 +0200
@@ -85,7 +85,7 @@
static int uniq(Sfio_t *fdin, Sfio_t *fdout, int fields, int chars, int width, int mode, int* all, Compare_f compare)
{
register int n, f, outsize=0, mb = mbwide();
- register char *cp, *ep, *mp, *bufp, *outp;
+ char *cp, *ep, *mp, *bufp, *outp;
char *orecp, *sbufp=0, *outbuff;
int reclen,oreclen= -1,count=0,cwidth=0,sep,next;
if(mode&C_FLAG)
diff -r -u original/src/lib/libcmd/wclib.c build_noasttmp/src/lib/libcmd/wclib.c
--- original/src/lib/libcmd/wclib.c 2012-11-22 05:33:44.000000000 +0100
+++ build_noasttmp/src/lib/libcmd/wclib.c 2013-08-28 06:53:55.452076766 +0200
@@ -164,7 +164,7 @@
wc_count(Wc_t *wp, Sfio_t *fd, const char* file)
{
register char* type = wp->type;
- register unsigned char* cp;
+ unsigned char* cp;
register Sfoff_t nbytes;
register Sfoff_t nchars;
register Sfoff_t nwords;
Glenn Fowler
2013-08-28 13:19:43 UTC
Permalink
yes, ast.tmp is a problem, especially for threads
I know the s++ part is a problem too and requires an api redesign

before doing *any* patch I'd like to see side test timing/memory/etc results of
current bad situation vs inline vs static function vs global function
for a loop that emulates mbchar(p)
the function forms would look something like

#define mbchar(p,wp) (p+=_text_mbchar_fun(p,wp),*(wp))

where the caller provides the address of a wchar_t : &w
w == -1 would signal error and p would be advanced past the bad bytes

remember that somewhere a vector of locale-specific ast intercept functions needs to be accessed
I don't know how you escape the global var access problems there

anyway, I'm not going to communcate any more today until I get the alpha out
not enough hours ...
--047d7bd6b65ad2056104e4fc0110
Content-Type: text/plain; charset=ISO-8859-1
Hi!
----
Olga Kryzhanovska and Jennifer Pioch dug-out a performance and
footprint killer: The |ast.tmp_*| variables... ;-(
- the |ast| structure is a global variable
- accessing it on CPU architectures with only few registers or no
support for complex indirect accesses can quickly exhaust registers
(that's not 100% true... but the number of available registers which
could be used for other stuff becomes... limited)
- typically (for embedded architectures) |ast| is not part of the L1
data cache when other code has been walked for some time. Per Jenny on
ARM CPUs with <= 16k of data cache |ast.tmp_*| were 97.2% times
outside L1 when accessed the first time in a function running a simple
multibyte character test
- The AST macros accessing the |ast.tmp_*| variables look small but
consume more code than writing the same code as |static inline|
function because of the read/write "far" accesses to the |ast.tmp_*|
variables (avoiding accesses to |ast| is not possible but it should be
minimised and preferably restricted to read-only accesses).
Question is... how can be fix this ?
AFAIK one way is to turn the "offending" CPP macros into |static
inline| functions (compilers which do not support |inline| just define
the functions as |static| ... at the expense of producing less
optimised code). The amount of code used is either the same as the CPP
macros or even less because we can use temporary variables on the
stack instead of "far" read/write accesses to the |ast.tmp_*|
structure.
The other advantage would be that without the |ast.tmp_*|-variables
instrumentation tools like "valgrind" or Rational Purify can track
values much better...
I've attached (as "astksh20130814_no_ast_tmp001.diff.txt") a prototype
patch which does this for the |mbchar()| macro (with some ugly mess
caused by the issue that |register| variables don't have an address,
e.g. |&var| doesn't work) which gives an interesting footprint
reduction (note that you have to compile with gcc -Os + use strip(1)
(to remove any extra symbol/debug info stuff) to get valid results (ad
note that padding is likely hiding individual size reduction benefits,
e.g. the code itself may become smaller but the compiler may "pad" ELF
$ ls -l ./arch/linux.i386-64/bin/ksh*
-rwxr-xr-x 1 test001 users 1844952 Aug 28 07:27
./arch/linux.i386-64/bin/ksh_mbchar_cpp
-rwxr-xr-x 1 test001 users 1841880 Aug 28 07:03
./arch/linux.i386-64/bin/ksh_mbchar_inline
$ print $((1844952 - 1841880))
3072
3072 bytes saved... and killing-off the other |ast.tmp_*| variables
and replacing them with function-local variables may likely yield a
similar code reduction...
----
Bye,
Roland
--
__ . . __
(o.\ \/ /.o) roland.mainz at nrubsig.org
\__\/\/__/ MPEG specialist, C&&JAVA&&Sun&&Unix programmer
/O /==\ O\ TEL +49 641 3992797
(;O/ \/ \O;)
--047d7bd6b65ad2056104e4fc0110
Content-Type: text/plain; charset=US-ASCII; name="astksh20130814_no_ast_tmp001.diff.txt"
Content-Disposition: attachment;
filename="astksh20130814_no_ast_tmp001.diff.txt"
Content-Transfer-Encoding: base64
X-Attachment-Id: f_hkw5247i0
ZGlmZiAtciAtdSBvcmlnaW5hbC9zcmMvY21kL2tzaDkzL2VkaXQvY29tcGxldGlvbi5jIGJ1aWxk
X25vYXN0dG1wL3NyYy9jbWQva3NoOTMvZWRpdC9jb21wbGV0aW9uLmMKLS0tIG9yaWdpbmFsL3Ny
Yy9jbWQva3NoOTMvZWRpdC9jb21wbGV0aW9uLmMJMjAxMi0wOC0wMyAyMDo0NzowMi4wMDAwMDAw
MDAgKzAyMDAKKysrIGJ1aWxkX25vYXN0dG1wL3NyYy9jbWQva3NoOTMvZWRpdC9jb21wbGV0aW9u
LmMJMjAxMy0wOC0yOCAwNzowNToyNC40NzY4Mzc4MjQgKzAyMDAKQEAgLTM3LDcgKzM3LDcgQEAK
IAogc3RhdGljIGNoYXIgKmZtdHgoU2hlbGxfdCAqc2hwLGNvbnN0IGNoYXIgKnN0cmluZykKIHsK
LQlyZWdpc3RlciBjb25zdCBjaGFyCSpjcCA9IHN0cmluZzsKKwljb25zdCBjaGFyCSpjcCA9IHN0
cmluZzsKIAlyZWdpc3RlciBpbnQJIAluLGM7CiAJdW5zaWduZWQgY2hhciAJCSpzdGF0ZSA9ICh1
bnNpZ25lZCBjaGFyKilzaF9sZXhzdGF0ZXNbMl07IAogCWludCBvZmZzZXQgPSBzdGt0ZWxsKHNo
cC0+c3RrKTsKQEAgLTk3LDcgKzk3LDcgQEAKICAqLwogc3RhdGljIGNoYXIgKmZpbmRfYmVnaW4o
Y2hhciBvdXRidWZmW10sIGNoYXIgKmxhc3QsIGludCBlbmRjaGFyLCBpbnQgKnR5cGUpCiB7Ci0J
cmVnaXN0ZXIgY2hhcgkqY3A9b3V0YnVmZiwgKmJwLCAqeHA7CisJY2hhcgkqY3A9b3V0YnVmZiwg
KmJwLCAqeHA7CiAJcmVnaXN0ZXIgaW50IAljLGlucXVvdGUgPSAwLCBpbmFzc2lnbj0wOwogCWlu
dAkJbW9kZT0qdHlwZTsKIAlicCA9IG91dGJ1ZmY7CkBAIC0yMDgsNyArMjA4LDcgQEAKIHsKIAlz
dHJ1Y3QgY29tbm9kCSpjb21wdHI7CiAJc3RydWN0IGFyZ25vZAkqYXA7Ci0JcmVnaXN0ZXIgY2hh
cgkqb3V0OworCWNoYXIJCSpvdXQ7CiAJY2hhciAJCSphdlsyXSwgKmJlZ2luICwgKmRpcj0wOwog
CWludAkJYWRkc3Rhcj0wLCBydmFsPTAsIHZhcj0wLCBzdHJpcD0xOwogCWludCAJCW5vbWFya2Rp
cnMgPSAhc2hfaXNvcHRpb24oZXAtPnNoLFNIX01BUktESVJTKTsKZGlmZiAtciAtdSBvcmlnaW5h
bC9zcmMvY21kL2tzaDkzL2VkaXQvZWRpdC5jIGJ1aWxkX25vYXN0dG1wL3NyYy9jbWQva3NoOTMv
ZWRpdC9lZGl0LmMKLS0tIG9yaWdpbmFsL3NyYy9jbWQva3NoOTMvZWRpdC9lZGl0LmMJMjAxMy0w
OC0wMiAxNzozNzoxMi4wMDAwMDAwMDAgKzAyMDAKKysrIGJ1aWxkX25vYXN0dG1wL3NyYy9jbWQv
a3NoOTMvZWRpdC9lZGl0LmMJMjAxMy0wOC0yOCAwNzowNjowOC42NjUwNjUyNTEgKzAyMDAKQEAg
LTU4NCw3ICs1ODQsNyBAQAogewogCVNoZWxsX3QgKnNocCA9IGVwLT5zaDsKIAlyZWdpc3RlciBj
aGFyICpwcDsKLQlyZWdpc3RlciBjaGFyICpsYXN0LCAqcHJldjsKKwljaGFyICpsYXN0LCAqcHJl
djsKIAljaGFyICpwcG1heDsKIAlpbnQgbXlxdW90ZSA9IDA7CiAJc2l6ZV90IG47CkBAIC0xMzc5
LDcgKzEzNzksNyBAQAogCiBpbnQJZWRfaW50ZXJuYWwoY29uc3QgY2hhciAqc3JjLCBnZW5jaGFy
ICpkZXN0KQogewotCXJlZ2lzdGVyIGNvbnN0IHVuc2lnbmVkIGNoYXIgKmNwID0gKHVuc2lnbmVk
IGNoYXIgKilzcmM7CisJY29uc3QgdW5zaWduZWQgY2hhciAqY3AgPSAodW5zaWduZWQgY2hhciAq
KXNyYzsKIAlyZWdpc3RlciBpbnQgYzsKIAlyZWdpc3RlciB3Y2hhcl90ICpkcCA9ICh3Y2hhcl90
KilkZXN0OwogCWlmKGRlc3QgPT0gKGdlbmNoYXIqKXJvdW5kb2YoY3AtKHVuc2lnbmVkIGNoYXIq
KTAsc2l6ZW9mKGdlbmNoYXIpKSkKZGlmZiAtciAtdSBvcmlnaW5hbC9zcmMvY21kL2tzaDkzL3No
L2FyaXRoLmMgYnVpbGRfbm9hc3R0bXAvc3JjL2NtZC9rc2g5My9zaC9hcml0aC5jCi0tLSBvcmln
aW5hbC9zcmMvY21kL2tzaDkzL3NoL2FyaXRoLmMJMjAxMy0wOC0xMiAxNjo0Mzo0Ny4wMDAwMDAw
MDAgKzAyMDAKKysrIGJ1aWxkX25vYXN0dG1wL3NyYy9jbWQva3NoOTMvc2gvYXJpdGguYwkyMDEz
LTA4LTI4IDA3OjA0OjE5LjY0NTU3MTMyNyArMDIwMApAQCAtNjIsNyArNjIsNyBAQAogc3RhdGlj
IE5hbXZhbF90ICpzY29wZShyZWdpc3RlciBOYW12YWxfdCAqbnAscmVnaXN0ZXIgc3RydWN0IGx2
YWwgKmx2YWx1ZSxpbnQgYXNzaWduKQogewogCXJlZ2lzdGVyIGludCBmbGFnID0gbHZhbHVlLT5m
bGFnOwotCXJlZ2lzdGVyIGNoYXIgKnN1Yj0wLCAqY3A9KGNoYXIqKW5wOworCWNoYXIgKnN1Yj0w
LCAqY3A9KGNoYXIqKW5wOwogCXJlZ2lzdGVyIE5hbXZhbF90ICptcDsKIAlTaGVsbF90CQkqc2hw
ID0gbHZhbHVlLT5zaHA7CiAJaW50CWZsYWdzID0gSEFTSF9OT1NDT1BFfEhBU0hfU0NPUEV8SEFT
SF9CVUNLRVQ7CmRpZmYgLXIgLXUgb3JpZ2luYWwvc3JjL2NtZC9rc2g5My9zaC9tYWNyby5jIGJ1
aWxkX25vYXN0dG1wL3NyYy9jbWQva3NoOTMvc2gvbWFjcm8uYwotLS0gb3JpZ2luYWwvc3JjL2Nt
ZC9rc2g5My9zaC9tYWNyby5jCTIwMTMtMDctMzEgMjI6MDg6NDAuMDAwMDAwMDAwICswMjAwCisr
KyBidWlsZF9ub2FzdHRtcC9zcmMvY21kL2tzaDkzL3NoL21hY3JvLmMJMjAxMy0wOC0yOCAwNzow
NzoyNy44MjIwNTMwNzAgKzAyMDAKQEAgLTExMDQsNyArMTEwNCw3IEBACiB7CiAJcmVnaXN0ZXIg
aW50CWM7CiAJcmVnaXN0ZXIgaW50CXR5cGU9MDsgLyogTV94eHggKi8KLQlyZWdpc3RlciBjaGFy
CSp2LCphcmdwPTA7CisJY2hhcgkJKnYsKmFyZ3A9MDsKIAlyZWdpc3RlciBOYW12YWxfdAkqbnAg
PSBOSUwoTmFtdmFsX3QqKTsKIAlyZWdpc3RlciBpbnQgCWRvbGc9MCwgbW9kZT0wOwogCUxleF90
CQkqbHAgPSAoTGV4X3QqKW1wLT5zaHAtPmxleF9jb250ZXh0OwpAQCAtMjY1NSw3ICsyNjU1LDcg
QEAKICNpZiBTSE9QVF9NVUxUSUJZVEUKIAlpZihtYndpZGUoKSkKIAl7Ci0JCXJlZ2lzdGVyIGNv
bnN0IGNoYXIgKnN0ciA9IHN0cmluZywgKnN0cm1heD1zdHJpbmcrbGVuOworCQljb25zdCBjaGFy
ICpzdHIgPSBzdHJpbmcsICpzdHJtYXg9c3RyaW5nK2xlbjsKIAkJcmVnaXN0ZXIgaW50IG49MDsK
IAkJbWJpbml0KCk7CiAJCWlmKGxlbj4wKQpkaWZmIC1yIC11IG9yaWdpbmFsL3NyYy9jbWQva3No
OTMvc2gvbmFtZS5jIGJ1aWxkX25vYXN0dG1wL3NyYy9jbWQva3NoOTMvc2gvbmFtZS5jCi0tLSBv
cmlnaW5hbC9zcmMvY21kL2tzaDkzL3NoL25hbWUuYwkyMDEzLTA4LTEyIDE2OjMzOjA5LjAwMDAw
MDAwMCArMDIwMAorKysgYnVpbGRfbm9hc3R0bXAvc3JjL2NtZC9rc2g5My9zaC9uYW1lLmMJMjAx
My0wOC0yOCAwNzowNzo1MS43MTgyNTY2NDMgKzAyMDAKQEAgLTIxNTEsNyArMjE1MSw3IEBACiAK
ICAgICBzdGF0aWMgaW50IGphX3NpemUoY2hhciAqc3RyLGludCBzaXplLGludCB0eXBlKQogICAg
IHsKLQlyZWdpc3RlciBjaGFyICpjcCA9IHN0cjsKKwljaGFyICpjcCA9IHN0cjsKIAlyZWdpc3Rl
ciBpbnQgYywgbj1zaXplOwogCXJlZ2lzdGVyIGludCBvdXRzaXplOwogCXJlZ2lzdGVyIGNoYXIg
Km9sZGNwPWNwOwpkaWZmIC1yIC11IG9yaWdpbmFsL3NyYy9jbWQva3NoOTMvc2gvc3RyaW5nLmMg
YnVpbGRfbm9hc3R0bXAvc3JjL2NtZC9rc2g5My9zaC9zdHJpbmcuYwotLS0gb3JpZ2luYWwvc3Jj
L2NtZC9rc2g5My9zaC9zdHJpbmcuYwkyMDEzLTA2LTEyIDIyOjUzOjU3LjAwMDAwMDAwMCArMDIw
MAorKysgYnVpbGRfbm9hc3R0bXAvc3JjL2NtZC9rc2g5My9zaC9zdHJpbmcuYwkyMDEzLTA4LTI4
IDA3OjEwOjAwLjc1Mjc1ODE0NyArMDIwMApAQCAtMjk0LDcgKzI5NCw3IEBACiAgKi8KIHN0YXRp
YyBjaGFyCSpzaF9mbXRjc3YoY29uc3QgY2hhciAqc3RyaW5nKQogewotCXJlZ2lzdGVyIGNvbnN0
IGNoYXIgKmNwID0gc3RyaW5nOworCWNvbnN0IGNoYXIgKmNwID0gc3RyaW5nOwogCXJlZ2lzdGVy
IGludCBjOwogCWludCBvZmZzZXQ7CiAJaWYoIWNwKQpAQCAtMzMwLDcgKzMzMCw3IEBACiAgKi8K
IGNoYXIgKnNoX2ZtdHN0cihjb25zdCBjaGFyICpzdHJpbmcsIGludCBxdW90ZSkKIHsKLQlyZWdp
c3RlciBjb25zdCBjaGFyICpjcCA9IHN0cmluZywgKm9wOworCWNvbnN0IGNoYXIgKmNwID0gc3Ry
aW5nLCAqb3A7CiAJcmVnaXN0ZXIgaW50IGMsIHN0YXRlLCB0eXBlPXF1b3RlOwogCWludCBvZmZz
ZXQ7CiAJaWYoIWNwKQpAQCAtNDgzLDcgKzQ4Myw3IEBACiAgKi8KIGNoYXIJKnNoX2ZtdHFmKGNv
bnN0IGNoYXIgKnN0cmluZywgaW50IHNpbmdsZSwgaW50IGZvbGQpCiB7Ci0JcmVnaXN0ZXIgY29u
c3QgY2hhciAqY3AgPSBzdHJpbmc7CisJY29uc3QgY2hhciAqY3AgPSBzdHJpbmc7CiAJcmVnaXN0
ZXIgY29uc3QgY2hhciAqYnA7CiAJcmVnaXN0ZXIgY29uc3QgY2hhciAqdnA7CiAJcmVnaXN0ZXIg
aW50IGM7CkBAIC02ODQsMTAgKzY4NCwxMCBAQAogfQogCiAjaWYgU0hPUFRfTVVMVElCWVRFCi0J
aW50IHNoX3N0cmNocihjb25zdCBjaGFyICpzdHJpbmcsIHJlZ2lzdGVyIGNvbnN0IGNoYXIgKmRw
KQorCWludCBzaF9zdHJjaHIoY29uc3QgY2hhciAqc3RyaW5nLCBjb25zdCBjaGFyICpkcCkKIAl7
CiAJCXdjaGFyX3QgYywgZDsKLQkJcmVnaXN0ZXIgY29uc3QgY2hhciAqY3A9c3RyaW5nOworCQlj
b25zdCBjaGFyICpjcD1zdHJpbmc7CiAJCW1iaW5pdCgpOwogCQlkID0gbWJjaGFyKGRwKTsgCiAJ
CW1iaW5pdCgpOwpAQCAtNzIyLDkgKzcyMiw5IEBACiAgKi8KIGNoYXIgKnNoX2NoZWNraWQoY2hh
ciAqc3RyLCBjaGFyICpsYXN0KQogewotCXJlZ2lzdGVyIHVuc2lnbmVkIGNoYXIgKmNwID0gKHVu
c2lnbmVkIGNoYXIqKXN0cjsKLQlyZWdpc3RlciB1bnNpZ25lZCBjaGFyICp2ID0gY3A7Ci0JcmVn
aXN0ZXIgaW50IGM7CisJdW5zaWduZWQgY2hhciAqY3AgPSAodW5zaWduZWQgY2hhciopc3RyOwor
CXVuc2lnbmVkIGNoYXIgKnYgPSBjcDsKKwlpbnQgYzsKIAlpZihjPW1iY2hhcihjcCksaXNhbGV0
dGVyKGMpKQogCQl3aGlsZShjPW1iY2hhcihjcCksaXNhbmFtZShjKSk7CiAJaWYoYz09J10nICYm
ICghbGFzdCB8fCAoKGNoYXIqKWNwPT1sYXN0KSkpCk9ubHkgaW4gYnVpbGRfbm9hc3R0bXAvc3Jj
L2NtZC9rc2g5My90ZXN0czogYXJyYXlzLnNoCmRpZmYgLXIgLXUgb3JpZ2luYWwvc3JjL2xpYi9s
aWJhc3QvaW5jbHVkZS9hc3QuaCBidWlsZF9ub2FzdHRtcC9zcmMvbGliL2xpYmFzdC9pbmNsdWRl
L2FzdC5oCi0tLSBvcmlnaW5hbC9zcmMvbGliL2xpYmFzdC9pbmNsdWRlL2FzdC5oCTIwMTMtMDgt
MDkgMTc6MjY6MjAuMDAwMDAwMDAwICswMjAwCisrKyBidWlsZF9ub2FzdHRtcC9zcmMvbGliL2xp
YmFzdC9pbmNsdWRlL2FzdC5oCTIwMTMtMDgtMjggMDc6MTY6MzIuOTYzNTEzMDIxICswMjAwCkBA
IC0yMDAsMTQgKzIwMCw0NiBAQAogICovCiAKICNkZWZpbmUgbWJtYXgoKQkJKGFzdC5tYl9jdXJf
bWF4KQotI2RlZmluZSBtYmVycigpCQkoYXN0LnRtcF9pbnQ8MCkKIAogI2RlZmluZSBtYmNvbGwo
KQkoYXN0Lm1iX3hmcm0hPTApCiAjZGVmaW5lIG1id2lkZSgpCShtYm1heCgpPjEpCiAKICNkZWZp
bmUgbWIyd2ModyxwLG4pCSgqYXN0Lm1iX3Rvd2MpKCYodyksKGNoYXIqKShwKSwobikpCisjaWYg
MQorI2RlZmluZSBtYmNoYXIocCkgX21iY2hhcigmKHApKQorc3RhdGljIGlubGluZSBpbnQgX21i
Y2hhcihjaGFyICoqcCkKK3sKKwlpbnQJdG1wOworCXdjaGFyX3QJd2M7CisKKwlpZiAobWJ3aWRl
KCkpCisJeworCQljaGFyICpkcCA9ICpwOworCQlpZiAoKHRtcD0oKmFzdC5tYl90b3djKSgmd2Ms
IGRwLCBtYm1heCgpKSk+MCkKKwkJeworCQkJZHArPXRtcDsKKwkJCSpwPWRwOworCQkJcmV0dXJu
IHdjOworCQl9CisJCWVsc2UKKwkJeworCQkJZHArPWFzdC5tYl9zeW5jKzE7CisJCQkqcD1kcDsK
KwkJCXJldHVybiB0bXA7CisJCX0KKwl9CisJZWxzZQorCXsKKwkJcmV0dXJuICoodW5zaWduZWQg
Y2hhciopKCgqcCkrKyk7CisJfQorfQorCisjZGVmaW5lIG1ibmNoYXIocCxuKQkobWJ3aWRlKCk/
KChhc3QudG1wX2ludD0oKmFzdC5tYl90b3djKSgmYXN0LnRtcF93Y2hhciwoY2hhciopKHApLG4p
KT4wPygocCs9YXN0LnRtcF9pbnQpLGFzdC50bXBfd2NoYXIpOihwKz1hc3QubWJfc3luYysxLGFz
dC50bXBfaW50KSk6KCoodW5zaWduZWQgY2hhciopKHArKykpKQorCisjZWxzZQogI2RlZmluZSBt
YmNoYXIocCkJKG1id2lkZSgpPygoYXN0LnRtcF9pbnQ9KCphc3QubWJfdG93YykoJmFzdC50bXBf
d2NoYXIsKGNoYXIqKShwKSxtYm1heCgpKSk+MD8oKHArPWFzdC50bXBfaW50KSxhc3QudG1wX3dj
aGFyKToocCs9YXN0Lm1iX3N5bmMrMSxhc3QudG1wX2ludCkpOigqKHVuc2lnbmVkIGNoYXIqKShw
KyspKSkKICNkZWZpbmUgbWJuY2hhcihwLG4pCShtYndpZGUoKT8oKGFzdC50bXBfaW50PSgqYXN0
Lm1iX3Rvd2MpKCZhc3QudG1wX3djaGFyLChjaGFyKikocCksbikpPjA/KChwKz1hc3QudG1wX2lu
dCksYXN0LnRtcF93Y2hhcik6KHArPWFzdC5tYl9zeW5jKzEsYXN0LnRtcF9pbnQpKTooKih1bnNp
Z25lZCBjaGFyKikocCsrKSkpCisjZW5kaWYKICNkZWZpbmUgbWJpbml0KCkJKG1id2lkZSgpPygq
YXN0Lm1iX3Rvd2MpKCh3Y2hhcl90KikwLChjaGFyKikwLG1ibWF4KCkpOjApCiAjZGVmaW5lIG1i
c2l6ZShwKQkobWJ3aWRlKCk/KCphc3QubWJfbGVuKSgoY2hhciopKHApLG1ibWF4KCkpOigocCks
MSkpCiAjZGVmaW5lIG1ibnNpemUocCxuKQkobWJ3aWRlKCk/KCphc3QubWJfbGVuKSgoY2hhciop
KHApLG4pOigocCksMSkpCmRpZmYgLXIgLXUgb3JpZ2luYWwvc3JjL2xpYi9saWJhc3QvcmVnZXgv
cmVnY29sbC5jIGJ1aWxkX25vYXN0dG1wL3NyYy9saWIvbGliYXN0L3JlZ2V4L3JlZ2NvbGwuYwot
LS0gb3JpZ2luYWwvc3JjL2xpYi9saWJhc3QvcmVnZXgvcmVnY29sbC5jCTIwMTItMDUtMTEgMTY6
NDM6MTQuMDAwMDAwMDAwICswMjAwCisrKyBidWlsZF9ub2FzdHRtcC9zcmMvbGliL2xpYmFzdC9y
ZWdleC9yZWdjb2xsLmMJMjAxMy0wOC0yOCAwNjo0NzowNy4zNTY0NTk0NDggKzAyMDAKQEAgLTM5
LDcgKzM5LDcgQEAKICAqLwogCiBpbnQKLXJlZ2NvbGxhdGUocmVnaXN0ZXIgY29uc3QgY2hhciog
cywgY2hhcioqIGUsIGNoYXIqIGJ1Ziwgc2l6ZV90IHNpemUsIHdjaGFyX3QqIHdjKQorcmVnY29s
bGF0ZShjb25zdCBjaGFyKiBzLCBjaGFyKiogZSwgY2hhciogYnVmLCBzaXplX3Qgc2l6ZSwgd2No
YXJfdCogd2MpCiB7CiAJcmVnaXN0ZXIgaW50CQkJYzsKIAlyZWdpc3RlciBjaGFyKgkJCWI7CmRp
ZmYgLXIgLXUgb3JpZ2luYWwvc3JjL2xpYi9saWJhc3QvcmVnZXgvcmVnY29tcC5jIGJ1aWxkX25v
YXN0dG1wL3NyYy9saWIvbGliYXN0L3JlZ2V4L3JlZ2NvbXAuYwotLS0gb3JpZ2luYWwvc3JjL2xp
Yi9saWJhc3QvcmVnZXgvcmVnY29tcC5jCTIwMTMtMDUtMzEgMDg6Mzg6MjkuMDAwMDAwMDAwICsw
MjAwCisrKyBidWlsZF9ub2FzdHRtcC9zcmMvbGliL2xpYmFzdC9yZWdleC9yZWdjb21wLmMJMjAx
My0wOC0yOCAwNjo0Nzo1NS44NDg5MTA2MjkgKzAyMDAKQEAgLTEwMzEsMTEgKzEwMzEsMTEgQEAK
IHN0YXRpYyBDZWx0X3QqCiBjb2woQ2VsdF90KiBjZSwgaW50IGljLCB1bnNpZ25lZCBjaGFyKiBi
cCwgaW50IGJ3LCBpbnQgYmMsIHVuc2lnbmVkIGNoYXIqIGVwLCBpbnQgZXcsIGludCBlYykKIHsK
LQlyZWdpc3RlciBjaGFyKgkJczsKLQlyZWdpc3RlciB1bnNpZ25lZCBjaGFyKglrOwotCXJlZ2lz
dGVyIHVuc2lnbmVkIGNoYXIqCWU7Ci0JcmVnaXN0ZXIgaW50CQljOwotCXJlZ2lzdGVyIGludAkJ
Y2M7CisJY2hhcioJCQlzOworCXVuc2lnbmVkIGNoYXIJCSogazsKKwl1bnNpZ25lZCBjaGFyCQkq
IGU7CisJaW50CQkJYzsKKwlpbnQJCQljYzsKIAlpbnQJCQlidDsKIAlpbnQJCQlldDsKIAlDa2V5
X3QJCQlrZXk7CmRpZmYgLXIgLXUgb3JpZ2luYWwvc3JjL2xpYi9saWJhc3Qvc3RyaW5nL2NocmVz
Yy5jIGJ1aWxkX25vYXN0dG1wL3NyYy9saWIvbGliYXN0L3N0cmluZy9jaHJlc2MuYwotLS0gb3Jp
Z2luYWwvc3JjL2xpYi9saWJhc3Qvc3RyaW5nL2NocmVzYy5jCTIwMTMtMDctMTYgMjA6MDI6MTMu
MDAwMDAwMDAwICswMjAwCisrKyBidWlsZF9ub2FzdHRtcC9zcmMvbGliL2xpYmFzdC9zdHJpbmcv
Y2hyZXNjLmMJMjAxMy0wOC0yOCAwNjo0MTo1Mi42MDM1NDMyODYgKzAyMDAKQEAgLTM5LDcgKzM5
LDcgQEAKICNlbmRpZgogCiBpbnQKLWNocmV4cChyZWdpc3RlciBjb25zdCBjaGFyKiBzLCBjaGFy
KiogcCwgaW50KiBtLCByZWdpc3RlciBpbnQgZmxhZ3MpCitjaHJleHAoY29uc3QgY2hhciogcywg
Y2hhcioqIHAsIGludCogbSwgcmVnaXN0ZXIgaW50IGZsYWdzKQogewogCXJlZ2lzdGVyIGNvbnN0
IGNoYXIqCXE7CiAJcmVnaXN0ZXIgaW50CQljOwpkaWZmIC1yIC11IG9yaWdpbmFsL3NyYy9saWIv
bGliYXN0L3N0cmluZy9mbXRlc2MuYyBidWlsZF9ub2FzdHRtcC9zcmMvbGliL2xpYmFzdC9zdHJp
bmcvZm10ZXNjLmMKLS0tIG9yaWdpbmFsL3NyYy9saWIvbGliYXN0L3N0cmluZy9mbXRlc2MuYwky
MDExLTAxLTI3IDIyOjIwOjQ1LjAwMDAwMDAwMCArMDEwMAorKysgYnVpbGRfbm9hc3R0bXAvc3Jj
L2xpYi9saWJhc3Qvc3RyaW5nL2ZtdGVzYy5jCTIwMTMtMDgtMjggMDY6NDY6MTcuMTg2OTIyNDk2
ICswMjAwCkBAIC00NywxOCArNDcsMTggQEAKIGNoYXIqCiBmbXRxdW90ZShjb25zdCBjaGFyKiBh
cywgY29uc3QgY2hhciogcWIsIGNvbnN0IGNoYXIqIHFlLCBzaXplX3QgbiwgaW50IGZsYWdzKQog
ewotCXJlZ2lzdGVyIHVuc2lnbmVkIGNoYXIqCXMgPSAodW5zaWduZWQgY2hhciopYXM7Ci0JcmVn
aXN0ZXIgdW5zaWduZWQgY2hhcioJZSA9IHMgKyBuOwotCXJlZ2lzdGVyIGNoYXIqCQliOwotCXJl
Z2lzdGVyIGludAkJYzsKLQlyZWdpc3RlciBpbnQJCW07Ci0JcmVnaXN0ZXIgaW50CQllc2NhcGVk
OwotCXJlZ2lzdGVyIGludAkJc3BhY2VkOwotCXJlZ2lzdGVyIGludAkJZG91YmxlcXVvdGU7Ci0J
cmVnaXN0ZXIgaW50CQlzaW5nbGVxdW90ZTsKLQlpbnQJCQlzaGVsbDsKLQljaGFyKgkJCWY7Ci0J
Y2hhcioJCQlidWY7CisJdW5zaWduZWQgY2hhcgkqIHMgPSAodW5zaWduZWQgY2hhciopYXM7CisJ
dW5zaWduZWQgY2hhcgkqIGUgPSBzICsgbjsKKwljaGFyKgkJYjsKKwlpbnQJCWM7CisJaW50CQlt
OworCWludAkJZXNjYXBlZDsKKwlpbnQJCXNwYWNlZDsKKwlpbnQJCWRvdWJsZXF1b3RlOworCWlu
dAkJc2luZ2xlcXVvdGU7CisJaW50CQlzaGVsbDsKKwljaGFyCQkqZjsKKwljaGFyCQkqYnVmOwog
CiAJYyA9IDQgKiAobiArIDEpOwogCWlmIChxYikKZGlmZiAtciAtdSBvcmlnaW5hbC9zcmMvbGli
L2xpYmNtZC9qb2luLmMgYnVpbGRfbm9hc3R0bXAvc3JjL2xpYi9saWJjbWQvam9pbi5jCi0tLSBv
cmlnaW5hbC9zcmMvbGliL2xpYmNtZC9qb2luLmMJMjAxMi0wMS0xMCAxOTo1NDoyMS4wMDAwMDAw
MDAgKzAxMDAKKysrIGJ1aWxkX25vYXN0dG1wL3NyYy9saWIvbGliY21kL2pvaW4uYwkyMDEzLTA4
LTI4IDA2OjU3OjU0LjE4MzEyODc5OCArMDIwMApAQCAtMjk4LDcgKzI5OCw3IEBACiAJcmVnaXN0
ZXIgRmlsZV90KglmcCA9ICZqcC0+ZmlsZVtpbmRleF07CiAJcmVnaXN0ZXIgRmllbGRfdCoJZmll
bGQgPSBmcC0+ZmllbGRzOwogCXJlZ2lzdGVyIEZpZWxkX3QqCWZpZWxkbWF4ID0gZmllbGQgKyBm
cC0+bWF4ZmllbGRzOwotCXJlZ2lzdGVyIGNoYXIqCQljcDsKKwljaGFyKgkJCWNwOwogCXJlZ2lz
dGVyIGludAkJbjsKIAljaGFyKgkJCXRwOwogCkBAIC04MTYsNyArODE2LDcgQEAKIGJfam9pbihp
bnQgYXJnYywgY2hhcioqIGFyZ3YsIFNoYmx0aW5fdCogY29udGV4dCkKIHsKIAlyZWdpc3RlciBp
bnQJCW47Ci0JcmVnaXN0ZXIgY2hhcioJCWNwOworCWNoYXIqCQkJY3A7CiAJcmVnaXN0ZXIgSm9p
bl90KglqcDsKIAljaGFyKgkJCWU7CiAKZGlmZiAtciAtdSBvcmlnaW5hbC9zcmMvbGliL2xpYmNt
ZC9wYXN0ZS5jIGJ1aWxkX25vYXN0dG1wL3NyYy9saWIvbGliY21kL3Bhc3RlLmMKLS0tIG9yaWdp
bmFsL3NyYy9saWIvbGliY21kL3Bhc3RlLmMJMjAxMi0wMS0xMCAxOTo1NTozMS4wMDAwMDAwMDAg
KzAxMDAKKysrIGJ1aWxkX25vYXN0dG1wL3NyYy9saWIvbGliY21kL3Bhc3RlLmMJMjAxMy0wOC0y
OCAwNjo1MjowNS4yNjM1MDkzMjIgKzAyMDAKQEAgLTE3Niw3ICsxNzYsNyBAQAogewogCXJlZ2lz
dGVyIGludAkJbiwgc2ZsYWc9MDsKIAlyZWdpc3RlciBTZmlvX3QJCSpmcCwgKipzdHJlYW1zOwot
CXJlZ2lzdGVyIGNoYXIgCQkqY3AsICpkZWxpbTsKKwljaGFyCQkJKmNwLCAqZGVsaW07CiAJY2hh
cgkJCSplcDsKIAlEZWxpbV90CQkJKm1wOwogCWludAkJCWRsZW4sIGRzaXo7CmRpZmYgLXIgLXUg
b3JpZ2luYWwvc3JjL2xpYi9saWJjbWQvcmV2LmMgYnVpbGRfbm9hc3R0bXAvc3JjL2xpYi9saWJj
bWQvcmV2LmMKLS0tIG9yaWdpbmFsL3NyYy9saWIvbGliY21kL3Jldi5jCTIwMTItMDEtMTAgMTk6
NTU6NDguMDAwMDAwMDAwICswMTAwCisrKyBidWlsZF9ub2FzdHRtcC9zcmMvbGliL2xpYmNtZC9y
ZXYuYwkyMDEzLTA4LTI4IDA2OjUyOjM3LjY2OTE0NzYxMyArMDIwMApAQCAtNjAsNyArNjAsNyBA
QAogc3RhdGljIGludCByZXZfY2hhcihTZmlvX3QgKmluLCBTZmlvX3QgKm91dCkKIHsKIAlyZWdp
c3RlciBpbnQgYzsKLQlyZWdpc3RlciBjaGFyICplcCwgKmJwLCAqY3A7CisJY2hhciAqZXAsICpi
cCwgKmNwOwogCXJlZ2lzdGVyIHdjaGFyX3QgKndwLCAqeHA7CiAJcmVnaXN0ZXIgc2l6ZV90IG47
CiAJcmVnaXN0ZXIgc2l6ZV90IHc7CmRpZmYgLXIgLXUgb3JpZ2luYWwvc3JjL2xpYi9saWJjbWQv
dW5pcS5jIGJ1aWxkX25vYXN0dG1wL3NyYy9saWIvbGliY21kL3VuaXEuYwotLS0gb3JpZ2luYWwv
c3JjL2xpYi9saWJjbWQvdW5pcS5jCTIwMTItMDMtMDggMDI6Mzg6MzYuMDAwMDAwMDAwICswMTAw
CisrKyBidWlsZF9ub2FzdHRtcC9zcmMvbGliL2xpYmNtZC91bmlxLmMJMjAxMy0wOC0yOCAwNjo1
MzoxMS4yMTU4NDIwMDIgKzAyMDAKQEAgLTg1LDcgKzg1LDcgQEAKIHN0YXRpYyBpbnQgdW5pcShT
ZmlvX3QgKmZkaW4sIFNmaW9fdCAqZmRvdXQsIGludCBmaWVsZHMsIGludCBjaGFycywgaW50IHdp
ZHRoLCBpbnQgbW9kZSwgaW50KiBhbGwsIENvbXBhcmVfZiBjb21wYXJlKQogewogCXJlZ2lzdGVy
IGludCBuLCBmLCBvdXRzaXplPTAsIG1iID0gbWJ3aWRlKCk7Ci0JcmVnaXN0ZXIgY2hhciAqY3As
ICplcCwgKm1wLCAqYnVmcCwgKm91dHA7CisJY2hhciAqY3AsICplcCwgKm1wLCAqYnVmcCwgKm91
dHA7CiAJY2hhciAqb3JlY3AsICpzYnVmcD0wLCAqb3V0YnVmZjsKIAlpbnQgcmVjbGVuLG9yZWNs
ZW49IC0xLGNvdW50PTAsY3dpZHRoPTAsc2VwLG5leHQ7CiAJaWYobW9kZSZDX0ZMQUcpCmRpZmYg
LXIgLXUgb3JpZ2luYWwvc3JjL2xpYi9saWJjbWQvd2NsaWIuYyBidWlsZF9ub2FzdHRtcC9zcmMv
bGliL2xpYmNtZC93Y2xpYi5jCi0tLSBvcmlnaW5hbC9zcmMvbGliL2xpYmNtZC93Y2xpYi5jCTIw
MTItMTEtMjIgMDU6MzM6NDQuMDAwMDAwMDAwICswMTAwCisrKyBidWlsZF9ub2FzdHRtcC9zcmMv
bGliL2xpYmNtZC93Y2xpYi5jCTIwMTMtMDgtMjggMDY6NTM6NTUuNDUyMDc2NzY2ICswMjAwCkBA
IC0xNjQsNyArMTY0LDcgQEAKIHdjX2NvdW50KFdjX3QgKndwLCBTZmlvX3QgKmZkLCBjb25zdCBj
aGFyKiBmaWxlKQogewogCXJlZ2lzdGVyIGNoYXIqCQl0eXBlID0gd3AtPnR5cGU7Ci0JcmVnaXN0
ZXIgdW5zaWduZWQgY2hhcioJY3A7CisJdW5zaWduZWQgY2hhcioJY3A7CiAJcmVnaXN0ZXIgU2Zv
ZmZfdAluYnl0ZXM7CiAJcmVnaXN0ZXIgU2ZvZmZfdAluY2hhcnM7CiAJcmVnaXN0ZXIgU2ZvZmZf
dAlud29yZHM7Cg==
--047d7bd6b65ad2056104e4fc0110--
Loading...