Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA384:256) (Exim 4.89) (envelope-from ) id 1emwyD-0006gb-3p for pgsql-hackers@arkaria.postgresql.org; Sat, 17 Feb 2018 07:31:42 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.84_2) (envelope-from ) id 1emwyA-0003zP-Ah for pgsql-hackers@arkaria.postgresql.org; Sat, 17 Feb 2018 07:31:38 +0000 Received: from magus.postgresql.org ([2a02:c0:301:0:ffff::29]) by malur.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA384:256) (Exim 4.84_2) (envelope-from ) id 1emwy9-0003zF-TU for pgsql-hackers@lists.postgresql.org; Sat, 17 Feb 2018 07:31:38 +0000 Received: from mail.postgrespro.ru ([93.174.131.138]) by magus.postgresql.org with esmtp (Exim 4.89) (envelope-from ) id 1emwxz-0006Fr-AJ for pgsql-hackers@postgresql.org; Sat, 17 Feb 2018 07:31:36 +0000 Received: from localhost (localhost [127.0.0.1]) by mail.postgrespro.ru (Postfix) with ESMTP id 9B5D521CA0C9; Sat, 17 Feb 2018 10:31:25 +0300 (MSK) X-Virus-Scanned: Debian amavisd-new at postgrespro.ru X-Spam-Flag: NO X-Spam-Score: 0 X-Spam-Level: X-Spam-Status: No, score=x tagged_above=-99 required=4 WHITELISTED tests=[] autolearn=unavailable Received: from [192.168.1.35] (unknown [89.250.10.62]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (Client did not present a certificate) by mail.postgrespro.ru (Postfix) with ESMTPSA id 2663721CA033; Sat, 17 Feb 2018 10:31:25 +0300 (MSK) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=postgrespro.ru; s=mail; t=1518852685; bh=+E7YnllN7MQMBpRwMxzx+QOozZChcDQKMuQnr1r1SIo=; h=Subject:To:References:From:Date:In-Reply-To; b=m3sLXSfE94TaD08/g7TAxP2zchB9ZhturVG2ljJDD3b/h53T6xlWMk8APS4kqeNYf 9bX9dIH1fl2zewS7JX7qAvXpyfTF0qqczDqiueNzkF12kyEV2VkePGhzZt9PGV2CoR v7FfrPX7o9X2GetKMiQJvJCXBYXmXLXFheiF+Gr4= Subject: Re: [HACKERS] Proposal: generic WAL compression To: Antonin Houska , Arthur Silva , Michael Paquier , Stephen Frost , Markus Nullmeier , David Steele , pgsql-hackers@postgresql.org References: <59F90ABF.2060407@postgrespro.ru> <23990.1510853483@localhost> From: Oleg Ivanov Message-ID: <5A87DA4C.6050509@postgrespro.ru> Date: Sat, 17 Feb 2018 10:31:24 +0300 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Thunderbird/38.5.1 MIME-Version: 1.0 In-Reply-To: <23990.1510853483@localhost> Content-Type: multipart/mixed; boundary="------------000004060508030804080906" List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Precedence: bulk This is a multi-part message in MIME format. --------------000004060508030804080906 Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 7bit Hello everyone! Unfortunately, I faced the use case with RUM index, in which my patch produced enormously large time overhead (queries execution time is about 2 or 3 times slower). Only now I finally managed to limit this overhead by 20% or even make it statistically insignificant on my HDD. Nevertheless, SSD evaluation is still required. So I attach new test totat_test.sh script which includes the bad RUM use case and the new version of the patch. Thanks everybody for review, it improved the patch a lot. The majority of the listed drawbacks were fixed, the others are discussed below. On 11/16/2017 08:31 PM, Antonin Houska wrote: > * writeToPtr() and readFromPtr() are applied to the existing code. I think > this is a reason for a separate diff, to be applied before the actual patch. Removed the existing code refactoring, that should be a separate patch indeed. > * What's the reason for changing FRAGMENT_HEADER_SIZE ? I see no change in > the data layout that writeFragment() produces. Diff delta has its own header which consists of one char and one int. To make this point more clear, I defined DIFF_DELTA_HEADER_SIZE and added 2 * DIFF_DELTA_HEADER_SIZE to MAX_DELTA_SIZE. > ** "An O(ND) Difference Algorithm and Its Variations" - I think the reference > should contain more information, e.g. name of the author(s). I think I even > saw URLs to scientific papers in the PG source but I'm not 100% sure right > now. The reference to the paper contains much more information now. > ** As for the algorithm itself: Although I didn't have enough patience (and > time) to follow it in every detail for this first review, I think I can > imagine what it is about. Yet I think reading would be easier if the > concepts of alignment and "diff delta" were depicted in the comments, > perhaps using some sort of "ASCII graphics". I briefly described the main idea of the dynamical programming algorithm in comments of alignRegions. It can be further refined if you think it is still unclear now, but I'm afraid the detailed description will result in just copying the referred paper into the comments. > ** DiffDeltaOperations enumeration: the individual values should be described. > > > * computeRegionDiffDelta() > > ** Does "previous delta" in one of the comments refer to "base delta", > i.e. the delta computation w/o your patch? If so, the comment should > mention it explicitly. > > ** If you use Min() to initialize the for-loop, it'd be more consistent if you > also used Max() when checking the limits: > > for (i = Min(validStart, targetStart); i < Max(validEnd, targetEnd); ++i) > > And similarly you can simplify the body of the loop. I found that this part of code is unnecessary and deleted it. On 11/17/2017 03:02 PM, Arthur Silva wrote: > I wonder if the algorithm could be changed to operate with units of 2 > or 4 bytes (instead of 1). > Since the algorithm speed is essentially doubled/quadrupled it could > yield a better runtime/compression trade-off. > > Does that make sense? This approach implies that we cannot detect data shift by one byte, for example. It is suitable for 2- or 4-bytes-aligned data, but looks not general enough. On 01/23/2018 12:37 AM, Stephen Frost wrote: >> * writeToPtr() and readFromPtr() are applied to the existing code. I think >> this is a reason for a separate diff, to be applied before the actual patch. > I'm not really a fan of using these, for my 2c. I'm not sure how others > feel, but having these macros which change one of the arguments to the > macro (by advancing the pointer) doesn't result in a net improvement to > readability for me. Sounds reasonable, but the patch uses such constructions as writeToPtr rather often. How do you feel about using writeToPtr(&ptr, data) which which more explicitly indicates the first argument changing? On 02/07/2018 09:02 PM, Markus Nullmeier wrote: > One general comment I can already make is that enabling compression > should be made optional, which appears to be a small and easy addition > to the generic WAL API. Now I'm working on this.I consider creation the function GenericXLogRegisterBufferEx in addition to GenericXLogRegisterBuffer. GenericXLogRegisterBufferEx will take a structure with parameters for diff delta such as maximal alignment length, to which parts of page it must be applied, etc. And GenericXLogRegisterBufferwill call GenericXLogRegisterBufferEx with default parameters. This allows using different compression settings for different indexes. What do you think about such solution? --------------000004060508030804080906 Content-Type: text/x-patch; name="generic_xlog_diffdelta_v2.patch" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="generic_xlog_diffdelta_v2.patch" diff --git a/src/backend/access/transam/generic_xlog.c b/src/backend/access/transam/generic_xlog.c index 3adbf7b..2ed4146 100644 --- a/src/backend/access/transam/generic_xlog.c +++ b/src/backend/access/transam/generic_xlog.c @@ -44,8 +44,16 @@ *------------------------------------------------------------------------- */ #define FRAGMENT_HEADER_SIZE (2 * sizeof(OffsetNumber)) +#define DIFF_DELTA_HEADER_SIZE (sizeof(char) + sizeof(int)) #define MATCH_THRESHOLD FRAGMENT_HEADER_SIZE -#define MAX_DELTA_SIZE (BLCKSZ + 2 * FRAGMENT_HEADER_SIZE) +#define MAX_DELTA_SIZE (BLCKSZ + 2 * FRAGMENT_HEADER_SIZE + \ + 2 * DIFF_DELTA_HEADER_SIZE) + sizeof(bool) + +#define MAX_ALIGN_MISMATCHES 24 +/* MAX_ALIGN_MISMATCHES is supposed to be not greater than PG_UINT8_MAX */ + +#define writeToPtr(ptr, x) memcpy(ptr, &(x), sizeof(x)), ptr += sizeof(x) +#define readFromPtr(ptr, x) memcpy(&(x), ptr, sizeof(x)), ptr += sizeof(x) /* Struct of generic xlog data for single page */ typedef struct @@ -71,15 +79,62 @@ struct GenericXLogState bool isLogged; }; +/* Describes for the region which type of delta is used in it */ +typedef enum +{ + DIFF_DELTA = 0, /* diff delta with insert, remove and replace + * operations */ + BASE_DELTA = 1 /* base delta with update operations only */ +} DeltaType; + +/* Diff delta operations for transforming current page to target page */ +typedef enum +{ + DIFF_INSERT = 0, + DIFF_REMOVE = 1, + DIFF_REPLACE = 2 +} DiffDeltaOperations; + static void writeFragment(PageData *pageData, OffsetNumber offset, OffsetNumber len, const char *data); static void computeRegionDelta(PageData *pageData, const char *curpage, const char *targetpage, int targetStart, int targetEnd, - int validStart, int validEnd); + int validStart, int validEnd, + bool forceBaseDelta); static void computeDelta(PageData *pageData, Page curpage, Page targetpage); static void applyPageRedo(Page page, const char *delta, Size deltaSize); +static int alignRegions(const char *curRegion, const char *targetRegion, + int curRegionLen, int targetRegionLen); + +static bool computeRegionDiffDelta(PageData *pageData, + const char *curpage, const char *targetpage, + int targetStart, int targetEnd, + int validStart, int validEnd); +static const char *applyPageDiffRedo(Page page, const char *delta, Size deltaSize); + +static void computeRegionBaseDelta(PageData *pageData, + const char *curpage, const char *targetpage, + int targetStart, int targetEnd, + int validStart, int validEnd); +static const char *applyPageBaseRedo(Page page, const char *delta, Size deltaSize); + +static bool pageDataContainsDiffDelta(PageData *pageData); +static void downgradeDeltaToBaseFormat(PageData *pageData); + +/* Arrays for the alignment building and for the resulting alignments */ +static int V[MAX_ALIGN_MISMATCHES + 1][2 * MAX_ALIGN_MISMATCHES + 1]; +static int prevDiag[MAX_ALIGN_MISMATCHES + 1][2 * MAX_ALIGN_MISMATCHES + 1]; +static int alignmentDiag[MAX_ALIGN_MISMATCHES + 1]; +static char curRegionAligned[BLCKSZ + MAX_ALIGN_MISMATCHES]; +static bool curRegionAlignedGap[BLCKSZ + MAX_ALIGN_MISMATCHES]; +static char targetRegionAligned[BLCKSZ + MAX_ALIGN_MISMATCHES]; +static bool targetRegionAlignedGap[BLCKSZ + MAX_ALIGN_MISMATCHES]; + +/* Array for diff delta application */ +static char localPage[BLCKSZ]; + /* * Write next fragment into pageData's delta. @@ -115,14 +170,76 @@ writeFragment(PageData *pageData, OffsetNumber offset, OffsetNumber length, * Bytes in curpage outside the range validStart to validEnd-1 should be * considered invalid, and always overwritten with target data. * - * This function is a hot spot, so it's worth being as tense as possible - * about the data-matching loops. + * If forceBaseDelta is true, fucntion just calls computeRegionBaseDelta. + * Otherwise this function tries to build diff delta first and, if it fails, + * uses the base delta. It also provides the header before the delta in which + * the type and the length of the delta are contained. */ static void computeRegionDelta(PageData *pageData, const char *curpage, const char *targetpage, int targetStart, int targetEnd, - int validStart, int validEnd) + int validStart, int validEnd, + bool forceBaseDelta) +{ + int length; + char header; + int prevDeltaLen; + bool diff = false; + char *ptr = pageData->delta + pageData->deltaLen; + + /* Verify we have enough space */ + Assert(pageData->deltaLen + sizeof(header) + + sizeof(length) <= MAX_DELTA_SIZE); + + pageData->deltaLen += sizeof(header) + sizeof(length); + prevDeltaLen = pageData->deltaLen; + + /* Try building diff delta only if necessary */ + if (!forceBaseDelta) + { + diff = computeRegionDiffDelta(pageData, + curpage, targetpage, + targetStart, targetEnd, + validStart, validEnd); + } + /* + * If we succeeded to make diff delta, just set the header. + * Otherwise, make base delta. + */ + if (diff) + { + header = DIFF_DELTA; + } + else + { + header = BASE_DELTA; + computeRegionBaseDelta(pageData, + curpage, targetpage, + targetStart, targetEnd, + validStart, validEnd); + } + length = pageData->deltaLen - prevDeltaLen; + + writeToPtr(ptr, header); + writeToPtr(ptr, length); +} + +/* + * Compute the XLOG fragments needed to transform a region of curpage into the + * corresponding region of targetpage, and append them to pageData's delta + * field. The region to transform runs from targetStart to targetEnd-1. + * Bytes in curpage outside the range validStart to validEnd-1 should be + * considered invalid, and always overwritten with target data. + * + * This function is a hot spot, so it's worth being as tense as possible + * about the data-matching loops. + */ +static void +computeRegionBaseDelta(PageData *pageData, + const char *curpage, const char *targetpage, + int targetStart, int targetEnd, + int validStart, int validEnd) { int i, loopEnd, @@ -222,27 +339,458 @@ computeRegionDelta(PageData *pageData, } /* + * Align curRegion and targetRegion and return the length of the alignment + * or -1 if the alignment with number of mismatching positions less than + * or equal to MAX_ALIGN_MISMATCHES does not exist. + * The algorithm guarantees to find the alignment with the least possible + * number of mismathing positions or return that such least number is greater + * than MAX_ALIGN_MISMATCHES. + * + * For a good introduction to the subject, read about the "Levenshtein + * distance" in Wikipedia. + * + * The basic algorithm is described in: + * "An O(ND) Difference Algorithm and its Variations", Eugene W. Myers, + * Algorithmica Vol. 1, 1986, pp. 251-266, + * , + * PDF: . + * See especially section 3, which describes the variation used below. + * + * This variation requires O(N + D ^ 2) memory and has time complexity O(ND). + * We choose it because it is faster than described in section 4.2 modification + * with O(N + D) memory requirement. + * + * The only modification we made to the original algorithm is the introduction + * of REPLACE operations, while in the original algorithm only INSERT and + * REMOVE are considered. This introduction doesn't affect time and memory + * complexity of the algorithm. + * + * The alignment is stored in curRegionAligned, targetRegionAligned, + * curRegionAlignedGap and targetRegionAlignedGap. The first two arrays + * contain the aligned data and the second two contain the map of align gaps + * in the first two arrays. + */ +static int +alignRegions(const char *curRegion, const char *targetRegion, + int curRegionLen, int targetRegionLen) +{ + /* Number of mismatches */ + int m; + + /* Difference between curRegion and targetRegion prefix lengths */ + int k; + + /* Curbuf and targetRegion prefix lengths */ + int i, + j; + /* Result alignment length */ + int resLen; + + /* Maximal possible result alignment length */ + int maxResLen; + + /* The length of the equal block */ + int curLen; + + /* Number of mismathes in the answer */ + int numMismatches = -1; + + /* + * If lengths differ too much, there is no alignment with a small + * number of mismatches. + */ + if (!(-MAX_ALIGN_MISMATCHES < curRegionLen - targetRegionLen && + curRegionLen - targetRegionLen < MAX_ALIGN_MISMATCHES)) + return -1; + + /* + * V is an array to store the values of dynamic programming. The first + * dimension corresponds to m, i. e. to the number of performed editing + * operations, and the second one is for k + m, where k is the number of + * a diagonal. + * A diagonal numbered k is such points (i, j) where i - j = k. + * Here i means the length of curRegion prefix and j means the length + * of targetRegion prefix. + * V[m][m + k] is the length of the longest prefix of curRegion i + * which can be aligned with the prefix of length j of targetRegion + * using m editing operations. + * In the loop below we initialize V[0][0] and then compute V[m][m + k] + * based on, if defined, V[m - 1][m + k - 1], V[m - 1][m + k], and + * V[m - 1][m + k + 1]. + * V[m][m + k] is undefined if k < -m or k > m. + */ + V[0][0] = 0; + + /* Find the longest path with the given number of mismatches */ + for (m = 0; m <= MAX_ALIGN_MISMATCHES; ++m) + { + /* + * Find the largest prefix alignment with the given number of + * mismatches and the given diagonal, i. e. difference between + * curRegion and targetRegion prefix lengths. + */ + for (k = -m; k <= m; ++k) + { + /* Dynamic programming recurrent step */ + if (m > 0) + { + i = -1; + if (k != -m && k != m && + V[m - 1][m - 1 + k] + 1 > i) + { + i = V[m - 1][m - 1 + k] + 1; + prevDiag[m][m + k] = k; + } + if (k != -m && k != -m + 1 && + V[m - 1][m - 1 + k - 1] + 1 > i) + { + i = V[m - 1][m - 1 + k - 1] + 1; + prevDiag[m][m + k] = k - 1; + } + if (k != m && k != m - 1 && + V[m - 1][m - 1 + k + 1] > i) + { + i = V[m - 1][m - 1 + k + 1]; + prevDiag[m][m + k] = k + 1; + } + } + else + i = 0; + j = i - k; + + /* Boundary checks */ + Assert(i >= 0); + Assert(j >= 0); + + /* Increase the prefixes while the bytes are equal */ + while (i < curRegionLen && j < targetRegionLen && + curRegion[i] == targetRegion[j]) + i++, j++; + + /* + * Save the largest curRegion prefix that was aligned with given + * number of mismatches and difference between curRegion and + * targetRegion prefix lengths. + */ + V[m][m + k] = i; + + /* If we find the alignment, save its length and break */ + if (i == curRegionLen && j == targetRegionLen) + { + numMismatches = m; + break; + } + } + /* Break if we find an alignment */ + if (numMismatches != -1) + break; + } + /* No alignment was found */ + if (numMismatches == -1) + return -1; + + /* + * Restore the path k-s for each iteration of the main loop + * for the found alignment. + */ + Assert(m >= 0); + while (m != 0) + { + Assert(-m <= k && k <= m); + alignmentDiag[m] = k; + k = prevDiag[m][m + k]; + m--; + } + Assert(k == 0); + alignmentDiag[0] = 0; + + /* Clear RegionAlignedGap arrays */ + maxResLen = Min(curRegionLen, targetRegionLen) + numMismatches; + memset(curRegionAlignedGap, 0, maxResLen); + memset(targetRegionAlignedGap, 0, maxResLen); + + /* Process the first equal block */ + resLen = V[0][0]; + Assert(resLen <= Min(curRegionLen, targetRegionLen)); + memcpy(curRegionAligned, curRegion, V[0][0]); + memcpy(targetRegionAligned, targetRegion, V[0][0]); + + /* Restore the rest of the alignment */ + for (m = 1; m <= numMismatches; ++m) + { + /* Initialize the variables for the block */ + int dk = alignmentDiag[m] - alignmentDiag[m - 1]; + int prevDiag = alignmentDiag[m - 1]; + k = alignmentDiag[m]; + i = V[m - 1][m - 1 + prevDiag]; + j = i - prevDiag; + /* Check state consistency */ + Assert(0 <= i && i <= curRegionLen); + Assert(0 <= j && j <= targetRegionLen); + + /* Check the block operation correctness */ + Assert(dk == -1 || i < curRegionLen); + Assert(dk == 1 || j < targetRegionLen); + Assert(-1 <= dk && dk <= 1); + Assert(resLen + 1 <= maxResLen); + + /* Do the alignment operation of the block */ + if (dk == 1 || dk == 0) + curRegionAligned[resLen] = curRegion[i++]; + else + curRegionAlignedGap[resLen] = true; + if (dk == 0 || dk == -1) + targetRegionAligned[resLen] = targetRegion[j++]; + else + targetRegionAlignedGap[resLen] = true; + resLen++; + + /* Compute the size of the equal part of the block */ + curLen = V[m][m + k] - i; + + /* Check whether the equal part of the block is computed correctly */ + Assert(curLen >= 0); + Assert(resLen + curLen <= maxResLen); + Assert(memcmp(&curRegion[i], &targetRegion[j], curLen) == 0); + + /* Copy the equal part of the block */ + memcpy(&curRegionAligned[resLen], &curRegion[i], curLen); + memcpy(&targetRegionAligned[resLen], &targetRegion[j], curLen); + resLen += curLen; + } + + return resLen; +} + +/* + * Try to build a short alignment in order to produce a short diff delta. + * If fails, return false, otherwise return true and write the delta to + * pageData->delta. + */ +static bool +computeRegionDiffDelta(PageData *pageData, + const char *curpage, const char *targetpage, + int targetStart, int targetEnd, + int validStart, int validEnd) +{ + char *ptr = pageData->delta + pageData->deltaLen; + int i, + j; + char type; + char len; + OffsetNumber start; + OffsetNumber tmp; + + int alignmentLength; + + alignmentLength = alignRegions(&curpage[validStart], + &targetpage[targetStart], + validEnd - validStart, + targetEnd - targetStart); + + /* If no proper alignment was found return false */ + if (alignmentLength < 0) + return false; + + /* + * Translate the alignment into the set of instructions for transformation + * from curRegion into targetRegion, and write these instructions into + * pageData->delta. + */ + + /* Verify we have enough space */ + Assert(pageData->deltaLen + 4 * sizeof(tmp) <= MAX_DELTA_SIZE); + + /* Write start and end indexes of the buffers */ + tmp = validStart; + writeToPtr(ptr, tmp); + tmp = validEnd; + writeToPtr(ptr, tmp); + tmp = targetStart; + writeToPtr(ptr, tmp); + tmp = targetEnd; + writeToPtr(ptr, tmp); + + /* Transform the alignment into the set of instructions */ + start = 0; + for (i = 0; i < alignmentLength; ++i) + { + /* Verify the alignment */ + Assert(!curRegionAlignedGap[i] || !targetRegionAlignedGap[i]); + + /* If the values are equal, write no instructions */ + if (curRegionAligned[i] == targetRegionAligned[i] && + !curRegionAlignedGap[i] && !targetRegionAlignedGap[i]) + { + start++; + continue; + } + + if (curRegionAlignedGap[i]) + type = DIFF_INSERT; + else if (targetRegionAlignedGap[i]) + type = DIFF_REMOVE; + else + type = DIFF_REPLACE; + + /* Find the end of the block of the same instructions */ + j = i + 1; + while (j < alignmentLength) + { + bool sameType = false; + + switch (type) + { + case DIFF_INSERT: + sameType = (curRegionAlignedGap[j]); + break; + case DIFF_REMOVE: + sameType = (targetRegionAlignedGap[j]); + break; + case DIFF_REPLACE: + sameType = (!curRegionAlignedGap[j] && + !targetRegionAlignedGap[j] && + curRegionAligned[j] != targetRegionAligned[j]); + break; + default: + elog(ERROR, "unrecognized delta operation type: %d", type); + break; + } + if (sameType) + j++; + else + break; + } + len = j - i; + + /* Verify we have enough space */ + Assert(pageData->deltaLen + sizeof(type) + + sizeof(len) + sizeof(start) <= MAX_DELTA_SIZE); + /* Write the header for instruction */ + writeToPtr(ptr, type); + writeToPtr(ptr, len); + writeToPtr(ptr, start); + + /* Write instruction data and go to the end of the block */ + if (type != DIFF_REMOVE) + { + /* Verify we have enough space */ + Assert(pageData->deltaLen + len <= MAX_DELTA_SIZE); + while (i < j) + { + char c = targetRegionAligned[i++]; + + writeToPtr(ptr, c); + } + } + else + i = j; + i--; + + /* Shift start position which shows where to apply instruction */ + if (type != DIFF_INSERT) + start += len; + } + + pageData->deltaLen = ptr - pageData->delta; + + return true; +} + +/* + * Return whether pageData->delta contains diff deltas or not. + */ +static bool +pageDataContainsDiffDelta(PageData *pageData) +{ + char *ptr = pageData->delta + sizeof(bool); + char *end = pageData->delta + pageData->deltaLen; + char header; + int length; + + while (ptr < end) + { + readFromPtr(ptr, header); + readFromPtr(ptr, length); + + if (header == DIFF_DELTA) + return true; + ptr += length; + } + return false; +} + +/* + * Downgrade pageData->delta to base delta format. + * + * Only base diffs are allowed to perform the transformation. + */ +static void +downgradeDeltaToBaseFormat(PageData *pageData) +{ + char *ptr = pageData->delta; + char *end = pageData->delta + pageData->deltaLen; + char *cur; + bool containsDiffDelta; + char header; + int length; + int newDeltaLength = 0; + + /* Check whether containsDiffDelta is false */ + readFromPtr(ptr, containsDiffDelta); + Assert(!containsDiffDelta); + + cur = ptr; + while (ptr < end) + { + readFromPtr(ptr, header); + readFromPtr(ptr, length); + + /* Check whether the region delta is base delta */ + Assert(header == BASE_DELTA); + newDeltaLength += length; + + memmove(cur, ptr, length); + cur += length; + ptr += length; + } + pageData->deltaLen = newDeltaLength; +} + +/* * Compute the XLOG delta record needed to transform curpage into targetpage, * and store it in pageData's delta field. */ static void computeDelta(PageData *pageData, Page curpage, Page targetpage) { + bool *containsDiffDelta = pageData->delta; int targetLower = ((PageHeader) targetpage)->pd_lower, targetUpper = ((PageHeader) targetpage)->pd_upper, curLower = ((PageHeader) curpage)->pd_lower, curUpper = ((PageHeader) curpage)->pd_upper; - pageData->deltaLen = 0; + pageData->deltaLen = sizeof(bool); /* Compute delta records for lower part of page ... */ computeRegionDelta(pageData, curpage, targetpage, 0, targetLower, - 0, curLower); + 0, curLower, + false); /* ... and for upper part, ignoring what's between */ computeRegionDelta(pageData, curpage, targetpage, targetUpper, BLCKSZ, - curUpper, BLCKSZ); + curUpper, BLCKSZ, + true); + + /* + * Set first byte to true if at least one of the region deltas + * is diff delta. Otherwise set first byte to false and downgrade all + * regions to base format without extra headers. + */ + *containsDiffDelta = pageDataContainsDiffDelta(pageData); + if (!(*containsDiffDelta)) + downgradeDeltaToBaseFormat(pageData); /* * If xlog debug is enabled, then check produced delta. Result of delta @@ -451,12 +999,58 @@ GenericXLogAbort(GenericXLogState *state) /* * Apply delta to given page image. + * + * Read blocks of instructions and apply them based on their type: + * BASE_DELTA or DIFF_DELTA. */ static void applyPageRedo(Page page, const char *delta, Size deltaSize) { const char *ptr = delta; const char *end = delta + deltaSize; + char header; + int length; + bool containsDiffDelta; + + /* If page delta is base delta, apply it. */ + readFromPtr(ptr, containsDiffDelta); + if (!containsDiffDelta) + { + applyPageBaseRedo(page, ptr, end - ptr); + return; + } + + /* Otherwise apply each region delta. */ + while (ptr < end) + { + readFromPtr(ptr, header); + readFromPtr(ptr, length); + + switch (header) + { + case DIFF_DELTA: + ptr = applyPageDiffRedo(page, ptr, length); + break; + case BASE_DELTA: + ptr = applyPageBaseRedo(page, ptr, length); + break; + default: + elog(ERROR, + "unrecognized delta type: %d", + header); + break; + } + } +} + +/* + * Apply base delta to given page image. + */ +static const char * +applyPageBaseRedo(Page page, const char *delta, Size deltaSize) +{ + const char *ptr = delta; + const char *end = delta + deltaSize; while (ptr < end) { @@ -472,6 +1066,80 @@ applyPageRedo(Page page, const char *delta, Size deltaSize) ptr += length; } + return ptr; +} + +/* + * Apply diff delta to given page image. + */ +static const char * +applyPageDiffRedo(Page page, const char *delta, Size deltaSize) +{ + const char *ptr = delta; + const char *end = delta + deltaSize; + OffsetNumber targetStart, + targetEnd; + OffsetNumber validStart, + validEnd; + int i, + j; + OffsetNumber start; + + /* Read start and end indexes of the buffers */ + readFromPtr(ptr, validStart); + readFromPtr(ptr, validEnd); + readFromPtr(ptr, targetStart); + readFromPtr(ptr, targetEnd); + + /* Read and apply the instructions */ + i = 0, j = 0; + while (ptr < end) + { + char type; + char len; + + /* Read the header of the current instruction */ + readFromPtr(ptr, type); + readFromPtr(ptr, len); + readFromPtr(ptr, start); + + /* Copy the data before current instruction to buffer */ + memcpy(&localPage[j], page + validStart + i, start - i); + j += start - i; + i = start; + + /* Apply the instruction */ + switch (type) + { + case DIFF_INSERT: + memcpy(&localPage[j], ptr, len); + ptr += len; + j += len; + break; + case DIFF_REMOVE: + i += len; + break; + case DIFF_REPLACE: + memcpy(&localPage[j], ptr, len); + i += len; + j += len; + ptr += len; + break; + default: + elog(ERROR, + "unrecognized delta instruction type: %d", + type); + break; + } + } + + /* Copy the data after the last instruction */ + memcpy(&localPage[j], page + validStart + i, validEnd - validStart - i); + j += validEnd - validStart - i; + i = validEnd - validStart; + + memcpy(page + targetStart, localPage, j); + return ptr; } /* --------------000004060508030804080906 Content-Type: text/plain; charset=UTF-8; name="postgresql.conf" Content-Transfer-Encoding: base64 Content-Disposition: attachment; filename="postgresql.conf" IyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQojIFBvc3RncmVTUUwgY29uZmlndXJh dGlvbiBmaWxlCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KIwojIFRoaXMgZmls ZSBjb25zaXN0cyBvZiBsaW5lcyBvZiB0aGUgZm9ybToKIwojICAgbmFtZSA9IHZhbHVlCiMK IyAoVGhlICI9IiBpcyBvcHRpb25hbC4pICBXaGl0ZXNwYWNlIG1heSBiZSB1c2VkLiAgQ29t bWVudHMgYXJlIGludHJvZHVjZWQgd2l0aAojICIjIiBhbnl3aGVyZSBvbiBhIGxpbmUuICBU aGUgY29tcGxldGUgbGlzdCBvZiBwYXJhbWV0ZXIgbmFtZXMgYW5kIGFsbG93ZWQKIyB2YWx1 ZXMgY2FuIGJlIGZvdW5kIGluIHRoZSBQb3N0Z3JlU1FMIGRvY3VtZW50YXRpb24uCiMKIyBU aGUgY29tbWVudGVkLW91dCBzZXR0aW5ncyBzaG93biBpbiB0aGlzIGZpbGUgcmVwcmVzZW50 IHRoZSBkZWZhdWx0IHZhbHVlcy4KIyBSZS1jb21tZW50aW5nIGEgc2V0dGluZyBpcyBOT1Qg c3VmZmljaWVudCB0byByZXZlcnQgaXQgdG8gdGhlIGRlZmF1bHQgdmFsdWU7CiMgeW91IG5l ZWQgdG8gcmVsb2FkIHRoZSBzZXJ2ZXIuCiMKIyBUaGlzIGZpbGUgaXMgcmVhZCBvbiBzZXJ2 ZXIgc3RhcnR1cCBhbmQgd2hlbiB0aGUgc2VydmVyIHJlY2VpdmVzIGEgU0lHSFVQCiMgc2ln bmFsLiAgSWYgeW91IGVkaXQgdGhlIGZpbGUgb24gYSBydW5uaW5nIHN5c3RlbSwgeW91IGhh dmUgdG8gU0lHSFVQIHRoZQojIHNlcnZlciBmb3IgdGhlIGNoYW5nZXMgdG8gdGFrZSBlZmZl Y3QsIHJ1biAicGdfY3RsIHJlbG9hZCIsIG9yIGV4ZWN1dGUKIyAiU0VMRUNUIHBnX3JlbG9h ZF9jb25mKCkiLiAgU29tZSBwYXJhbWV0ZXJzLCB3aGljaCBhcmUgbWFya2VkIGJlbG93LAoj IHJlcXVpcmUgYSBzZXJ2ZXIgc2h1dGRvd24gYW5kIHJlc3RhcnQgdG8gdGFrZSBlZmZlY3Qu CiMKIyBBbnkgcGFyYW1ldGVyIGNhbiBhbHNvIGJlIGdpdmVuIGFzIGEgY29tbWFuZC1saW5l IG9wdGlvbiB0byB0aGUgc2VydmVyLCBlLmcuLAojICJwb3N0Z3JlcyAtYyBsb2dfY29ubmVj dGlvbnM9b24iLiAgU29tZSBwYXJhbWV0ZXJzIGNhbiBiZSBjaGFuZ2VkIGF0IHJ1biB0aW1l CiMgd2l0aCB0aGUgIlNFVCIgU1FMIGNvbW1hbmQuCiMKIyBNZW1vcnkgdW5pdHM6ICBrQiA9 IGtpbG9ieXRlcyAgICAgICAgVGltZSB1bml0czogIG1zICA9IG1pbGxpc2Vjb25kcwojICAg ICAgICAgICAgICAgIE1CID0gbWVnYWJ5dGVzICAgICAgICAgICAgICAgICAgICAgcyAgID0g c2Vjb25kcwojICAgICAgICAgICAgICAgIEdCID0gZ2lnYWJ5dGVzICAgICAgICAgICAgICAg ICAgICAgbWluID0gbWludXRlcwojICAgICAgICAgICAgICAgIFRCID0gdGVyYWJ5dGVzICAg ICAgICAgICAgICAgICAgICAgaCAgID0gaG91cnMKIyAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgIGQgICA9IGRheXMKCgojLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tCiMgRklMRSBMT0NBVElPTlMKIy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LQoKIyBUaGUgZGVmYXVsdCB2YWx1ZXMgb2YgdGhlc2UgdmFyaWFibGVzIGFyZSBkcml2ZW4g ZnJvbSB0aGUgLUQgY29tbWFuZC1saW5lCiMgb3B0aW9uIG9yIFBHREFUQSBlbnZpcm9ubWVu dCB2YXJpYWJsZSwgcmVwcmVzZW50ZWQgaGVyZSBhcyBDb25maWdEaXIuCgojZGF0YV9kaXJl Y3RvcnkgPSAnQ29uZmlnRGlyJwkJIyB1c2UgZGF0YSBpbiBhbm90aGVyIGRpcmVjdG9yeQoJ CQkJCSMgKGNoYW5nZSByZXF1aXJlcyByZXN0YXJ0KQojaGJhX2ZpbGUgPSAnQ29uZmlnRGly L3BnX2hiYS5jb25mJwkjIGhvc3QtYmFzZWQgYXV0aGVudGljYXRpb24gZmlsZQoJCQkJCSMg KGNoYW5nZSByZXF1aXJlcyByZXN0YXJ0KQojaWRlbnRfZmlsZSA9ICdDb25maWdEaXIvcGdf aWRlbnQuY29uZicJIyBpZGVudCBjb25maWd1cmF0aW9uIGZpbGUKCQkJCQkjIChjaGFuZ2Ug cmVxdWlyZXMgcmVzdGFydCkKCiMgSWYgZXh0ZXJuYWxfcGlkX2ZpbGUgaXMgbm90IGV4cGxp Y2l0bHkgc2V0LCBubyBleHRyYSBQSUQgZmlsZSBpcyB3cml0dGVuLgojZXh0ZXJuYWxfcGlk X2ZpbGUgPSAnJwkJCSMgd3JpdGUgYW4gZXh0cmEgUElEIGZpbGUKCQkJCQkjIChjaGFuZ2Ug cmVxdWlyZXMgcmVzdGFydCkKCgojLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiMgQ09OTkVD VElPTlMgQU5EIEFVVEhFTlRJQ0FUSU9OCiMtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiMg LSBDb25uZWN0aW9uIFNldHRpbmdzIC0KCiNsaXN0ZW5fYWRkcmVzc2VzID0gJ2xvY2FsaG9z dCcJCSMgd2hhdCBJUCBhZGRyZXNzKGVzKSB0byBsaXN0ZW4gb247CgkJCQkJIyBjb21tYS1z ZXBhcmF0ZWQgbGlzdCBvZiBhZGRyZXNzZXM7CgkJCQkJIyBkZWZhdWx0cyB0byAnbG9jYWxo b3N0JzsgdXNlICcqJyBmb3IgYWxsCgkJCQkJIyAoY2hhbmdlIHJlcXVpcmVzIHJlc3RhcnQp CiNwb3J0ID0gNTg0NQkJCQkjIChjaGFuZ2UgcmVxdWlyZXMgcmVzdGFydCkKbWF4X2Nvbm5l Y3Rpb25zID0gMTAwCQkJIyAoY2hhbmdlIHJlcXVpcmVzIHJlc3RhcnQpCiNzdXBlcnVzZXJf cmVzZXJ2ZWRfY29ubmVjdGlvbnMgPSAzCSMgKGNoYW5nZSByZXF1aXJlcyByZXN0YXJ0KQoj dW5peF9zb2NrZXRfZGlyZWN0b3JpZXMgPSAnL3RtcCcJIyBjb21tYS1zZXBhcmF0ZWQgbGlz dCBvZiBkaXJlY3RvcmllcwoJCQkJCSMgKGNoYW5nZSByZXF1aXJlcyByZXN0YXJ0KQojdW5p eF9zb2NrZXRfZ3JvdXAgPSAnJwkJCSMgKGNoYW5nZSByZXF1aXJlcyByZXN0YXJ0KQojdW5p eF9zb2NrZXRfcGVybWlzc2lvbnMgPSAwNzc3CQkjIGJlZ2luIHdpdGggMCB0byB1c2Ugb2N0 YWwgbm90YXRpb24KCQkJCQkjIChjaGFuZ2UgcmVxdWlyZXMgcmVzdGFydCkKI2JvbmpvdXIg PSBvZmYJCQkJIyBhZHZlcnRpc2Ugc2VydmVyIHZpYSBCb25qb3VyCgkJCQkJIyAoY2hhbmdl IHJlcXVpcmVzIHJlc3RhcnQpCiNib25qb3VyX25hbWUgPSAnJwkJCSMgZGVmYXVsdHMgdG8g dGhlIGNvbXB1dGVyIG5hbWUKCQkJCQkjIChjaGFuZ2UgcmVxdWlyZXMgcmVzdGFydCkKCiMg LSBTZWN1cml0eSBhbmQgQXV0aGVudGljYXRpb24gLQoKI2F1dGhlbnRpY2F0aW9uX3RpbWVv dXQgPSAxbWluCQkjIDFzLTYwMHMKI3NzbCA9IG9mZgojc3NsX2NpcGhlcnMgPSAnSElHSDpN RURJVU06KzNERVM6IWFOVUxMJyAjIGFsbG93ZWQgU1NMIGNpcGhlcnMKI3NzbF9wcmVmZXJf c2VydmVyX2NpcGhlcnMgPSBvbgojc3NsX2VjZGhfY3VydmUgPSAncHJpbWUyNTZ2MScKI3Nz bF9kaF9wYXJhbXNfZmlsZSA9ICcnCiNzc2xfY2VydF9maWxlID0gJ3NlcnZlci5jcnQnCiNz c2xfa2V5X2ZpbGUgPSAnc2VydmVyLmtleScKI3NzbF9jYV9maWxlID0gJycKI3NzbF9jcmxf ZmlsZSA9ICcnCiNwYXNzd29yZF9lbmNyeXB0aW9uID0gbWQ1CQkjIG1kNSBvciBzY3JhbS1z aGEtMjU2CiNkYl91c2VyX25hbWVzcGFjZSA9IG9mZgojcm93X3NlY3VyaXR5ID0gb24KCiMg R1NTQVBJIHVzaW5nIEtlcmJlcm9zCiNrcmJfc2VydmVyX2tleWZpbGUgPSAnJwoja3JiX2Nh c2VpbnNfdXNlcnMgPSBvZmYKCiMgLSBUQ1AgS2VlcGFsaXZlcyAtCiMgc2VlICJtYW4gNyB0 Y3AiIGZvciBkZXRhaWxzCgojdGNwX2tlZXBhbGl2ZXNfaWRsZSA9IDAJCSMgVENQX0tFRVBJ RExFLCBpbiBzZWNvbmRzOwoJCQkJCSMgMCBzZWxlY3RzIHRoZSBzeXN0ZW0gZGVmYXVsdAoj dGNwX2tlZXBhbGl2ZXNfaW50ZXJ2YWwgPSAwCQkjIFRDUF9LRUVQSU5UVkwsIGluIHNlY29u ZHM7CgkJCQkJIyAwIHNlbGVjdHMgdGhlIHN5c3RlbSBkZWZhdWx0CiN0Y3Bfa2VlcGFsaXZl c19jb3VudCA9IDAJCSMgVENQX0tFRVBDTlQ7CgkJCQkJIyAwIHNlbGVjdHMgdGhlIHN5c3Rl bSBkZWZhdWx0CgoKIy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQojIFJFU09VUkNFIFVTQUdF IChleGNlcHQgV0FMKQojLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgojIC0gTWVtb3J5IC0K CnNoYXJlZF9idWZmZXJzID0gMTAyNE1CCQkJIyBtaW4gMTI4a0IKCQkJCQkjIChjaGFuZ2Ug cmVxdWlyZXMgcmVzdGFydCkKI2h1Z2VfcGFnZXMgPSB0cnkJCQkjIG9uLCBvZmYsIG9yIHRy eQoJCQkJCSMgKGNoYW5nZSByZXF1aXJlcyByZXN0YXJ0KQojdGVtcF9idWZmZXJzID0gOE1C CQkJIyBtaW4gODAwa0IKI21heF9wcmVwYXJlZF90cmFuc2FjdGlvbnMgPSAwCQkjIHplcm8g ZGlzYWJsZXMgdGhlIGZlYXR1cmUKCQkJCQkjIChjaGFuZ2UgcmVxdWlyZXMgcmVzdGFydCkK IyBDYXV0aW9uOiBpdCBpcyBub3QgYWR2aXNhYmxlIHRvIHNldCBtYXhfcHJlcGFyZWRfdHJh bnNhY3Rpb25zIG5vbnplcm8gdW5sZXNzCiMgeW91IGFjdGl2ZWx5IGludGVuZCB0byB1c2Ug cHJlcGFyZWQgdHJhbnNhY3Rpb25zLgojd29ya19tZW0gPSA0TUIJCQkJIyBtaW4gNjRrQgoj bWFpbnRlbmFuY2Vfd29ya19tZW0gPSA2NE1CCQkjIG1pbiAxTUIKI3JlcGxhY2VtZW50X3Nv cnRfdHVwbGVzID0gMTUwMDAwCSMgbGltaXRzIHVzZSBvZiByZXBsYWNlbWVudCBzZWxlY3Rp b24gc29ydAojYXV0b3ZhY3V1bV93b3JrX21lbSA9IC0xCQkjIG1pbiAxTUIsIG9yIC0xIHRv IHVzZSBtYWludGVuYW5jZV93b3JrX21lbQojbWF4X3N0YWNrX2RlcHRoID0gMk1CCQkJIyBt aW4gMTAwa0IKZHluYW1pY19zaGFyZWRfbWVtb3J5X3R5cGUgPSBwb3NpeAkjIHRoZSBkZWZh dWx0IGlzIHRoZSBmaXJzdCBvcHRpb24KCQkJCQkjIHN1cHBvcnRlZCBieSB0aGUgb3BlcmF0 aW5nIHN5c3RlbToKCQkJCQkjICAgcG9zaXgKCQkJCQkjICAgc3lzdgoJCQkJCSMgICB3aW5k b3dzCgkJCQkJIyAgIG1tYXAKCQkJCQkjIHVzZSBub25lIHRvIGRpc2FibGUgZHluYW1pYyBz aGFyZWQgbWVtb3J5CgkJCQkJIyAoY2hhbmdlIHJlcXVpcmVzIHJlc3RhcnQpCgojIC0gRGlz ayAtCgojdGVtcF9maWxlX2xpbWl0ID0gLTEJCQkjIGxpbWl0cyBwZXItcHJvY2VzcyB0ZW1w IGZpbGUgc3BhY2UKCQkJCQkjIGluIGtCLCBvciAtMSBmb3Igbm8gbGltaXQKCiMgLSBLZXJu ZWwgUmVzb3VyY2UgVXNhZ2UgLQoKI21heF9maWxlc19wZXJfcHJvY2VzcyA9IDEwMDAJCSMg bWluIDI1CgkJCQkJIyAoY2hhbmdlIHJlcXVpcmVzIHJlc3RhcnQpCiNzaGFyZWRfcHJlbG9h ZF9saWJyYXJpZXMgPSAnJwkJIyAoY2hhbmdlIHJlcXVpcmVzIHJlc3RhcnQpCgojIC0gQ29z dC1CYXNlZCBWYWN1dW0gRGVsYXkgLQoKI3ZhY3V1bV9jb3N0X2RlbGF5ID0gMAkJCSMgMC0x MDAgbWlsbGlzZWNvbmRzCiN2YWN1dW1fY29zdF9wYWdlX2hpdCA9IDEJCSMgMC0xMDAwMCBj cmVkaXRzCiN2YWN1dW1fY29zdF9wYWdlX21pc3MgPSAxMAkJIyAwLTEwMDAwIGNyZWRpdHMK I3ZhY3V1bV9jb3N0X3BhZ2VfZGlydHkgPSAyMAkJIyAwLTEwMDAwIGNyZWRpdHMKI3ZhY3V1 bV9jb3N0X2xpbWl0ID0gMjAwCQkjIDEtMTAwMDAgY3JlZGl0cwoKIyAtIEJhY2tncm91bmQg V3JpdGVyIC0KCmJnd3JpdGVyX2RlbGF5ID0gMjBtcwkJCSMgMTAtMTAwMDBtcyBiZXR3ZWVu IHJvdW5kcwpiZ3dyaXRlcl9scnVfbWF4cGFnZXMgPSA4MDAJCSMgMC0xMDAwIG1heCBidWZm ZXJzIHdyaXR0ZW4vcm91bmQKYmd3cml0ZXJfbHJ1X211bHRpcGxpZXIgPSA4LjAJCSMgMC0x MC4wIG11bHRpcGxpZXIgb24gYnVmZmVycyBzY2FubmVkL3JvdW5kCiNiZ3dyaXRlcl9mbHVz aF9hZnRlciA9IDUxMmtCCQkjIG1lYXN1cmVkIGluIHBhZ2VzLCAwIGRpc2FibGVzCgojIC0g QXN5bmNocm9ub3VzIEJlaGF2aW9yIC0KCiNlZmZlY3RpdmVfaW9fY29uY3VycmVuY3kgPSAx CQkjIDEtMTAwMDsgMCBkaXNhYmxlcyBwcmVmZXRjaGluZwojbWF4X3dvcmtlcl9wcm9jZXNz ZXMgPSA4CQkjIChjaGFuZ2UgcmVxdWlyZXMgcmVzdGFydCkKI21heF9wYXJhbGxlbF93b3Jr ZXJzX3Blcl9nYXRoZXIgPSAyCSMgdGFrZW4gZnJvbSBtYXhfcGFyYWxsZWxfd29ya2Vycwoj bWF4X3BhcmFsbGVsX3dvcmtlcnMgPSA4CQkjIG1heGltdW0gbnVtYmVyIG9mIG1heF93b3Jr ZXJfcHJvY2Vzc2VzIHRoYXQKCQkJCQkjIGNhbiBiZSB1c2VkIGluIHBhcmFsbGVsIHF1ZXJp ZXMKI29sZF9zbmFwc2hvdF90aHJlc2hvbGQgPSAtMQkJIyAxbWluLTYwZDsgLTEgZGlzYWJs ZXM7IDAgaXMgaW1tZWRpYXRlCgkJCQkJIyAoY2hhbmdlIHJlcXVpcmVzIHJlc3RhcnQpCiNi YWNrZW5kX2ZsdXNoX2FmdGVyID0gMAkJIyBtZWFzdXJlZCBpbiBwYWdlcywgMCBkaXNhYmxl cwoKCiMtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KIyBXUklURSBBSEVBRCBMT0cKIy0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLQoKIyAtIFNldHRpbmdzIC0KCndhbF9sZXZlbCA9IG1pbmlt YWwJCQkjIG1pbmltYWwsIHJlcGxpY2EsIG9yIGxvZ2ljYWwKCQkJCQkjIChjaGFuZ2UgcmVx dWlyZXMgcmVzdGFydCkKZnN5bmMgPSBvZmYJCQkJIyBmbHVzaCBkYXRhIHRvIGRpc2sgZm9y IGNyYXNoIHNhZmV0eQoJCQkJCSMgKHR1cm5pbmcgdGhpcyBvZmYgY2FuIGNhdXNlCgkJCQkJ IyB1bnJlY292ZXJhYmxlIGRhdGEgY29ycnVwdGlvbikKc3luY2hyb25vdXNfY29tbWl0ID0g b2ZmCQkjIHN5bmNocm9uaXphdGlvbiBsZXZlbDsKCQkJCQkjIG9mZiwgbG9jYWwsIHJlbW90 ZV93cml0ZSwgcmVtb3RlX2FwcGx5LCBvciBvbgojd2FsX3N5bmNfbWV0aG9kID0gZnN5bmMJ CSMgdGhlIGRlZmF1bHQgaXMgdGhlIGZpcnN0IG9wdGlvbgoJCQkJCSMgc3VwcG9ydGVkIGJ5 IHRoZSBvcGVyYXRpbmcgc3lzdGVtOgoJCQkJCSMgICBvcGVuX2RhdGFzeW5jCgkJCQkJIyAg IGZkYXRhc3luYyAoZGVmYXVsdCBvbiBMaW51eCkKCQkJCQkjICAgZnN5bmMKCQkJCQkjICAg ZnN5bmNfd3JpdGV0aHJvdWdoCgkJCQkJIyAgIG9wZW5fc3luYwpmdWxsX3BhZ2Vfd3JpdGVz ID0gb2ZmCQkJIyByZWNvdmVyIGZyb20gcGFydGlhbCBwYWdlIHdyaXRlcwojd2FsX2NvbXBy ZXNzaW9uID0gb2ZmCQkJIyBlbmFibGUgY29tcHJlc3Npb24gb2YgZnVsbC1wYWdlIHdyaXRl cwojd2FsX2xvZ19oaW50cyA9IG9mZgkJCSMgYWxzbyBkbyBmdWxsIHBhZ2Ugd3JpdGVzIG9m IG5vbi1jcml0aWNhbCB1cGRhdGVzCgkJCQkJIyAoY2hhbmdlIHJlcXVpcmVzIHJlc3RhcnQp CiN3YWxfYnVmZmVycyA9IC0xCQkJIyBtaW4gMzJrQiwgLTEgc2V0cyBiYXNlZCBvbiBzaGFy ZWRfYnVmZmVycwoJCQkJCSMgKGNoYW5nZSByZXF1aXJlcyByZXN0YXJ0KQojd2FsX3dyaXRl cl9kZWxheSA9IDIwMG1zCQkjIDEtMTAwMDAgbWlsbGlzZWNvbmRzCiN3YWxfd3JpdGVyX2Zs dXNoX2FmdGVyID0gMU1CCQkjIG1lYXN1cmVkIGluIHBhZ2VzLCAwIGRpc2FibGVzCgojY29t bWl0X2RlbGF5ID0gMAkJCSMgcmFuZ2UgMC0xMDAwMDAsIGluIG1pY3Jvc2Vjb25kcwojY29t bWl0X3NpYmxpbmdzID0gNQkJCSMgcmFuZ2UgMS0xMDAwCgojIC0gQ2hlY2twb2ludHMgLQoK Y2hlY2twb2ludF90aW1lb3V0ID0gMTIwbWluCQkjIHJhbmdlIDMwcy0xZAptYXhfd2FsX3Np emUgPSA4R0IKbWluX3dhbF9zaXplID0gMUdCCiNjaGVja3BvaW50X2NvbXBsZXRpb25fdGFy Z2V0ID0gMC41CSMgY2hlY2twb2ludCB0YXJnZXQgZHVyYXRpb24sIDAuMCAtIDEuMAojY2hl Y2twb2ludF9mbHVzaF9hZnRlciA9IDI1NmtCCQkjIG1lYXN1cmVkIGluIHBhZ2VzLCAwIGRp c2FibGVzCiNjaGVja3BvaW50X3dhcm5pbmcgPSAzMHMJCSMgMCBkaXNhYmxlcwoKIyAtIEFy Y2hpdmluZyAtCgojYXJjaGl2ZV9tb2RlID0gb2ZmCQkjIGVuYWJsZXMgYXJjaGl2aW5nOyBv ZmYsIG9uLCBvciBhbHdheXMKCQkJCSMgKGNoYW5nZSByZXF1aXJlcyByZXN0YXJ0KQojYXJj aGl2ZV9jb21tYW5kID0gJycJCSMgY29tbWFuZCB0byB1c2UgdG8gYXJjaGl2ZSBhIGxvZ2Zp bGUgc2VnbWVudAoJCQkJIyBwbGFjZWhvbGRlcnM6ICVwID0gcGF0aCBvZiBmaWxlIHRvIGFy Y2hpdmUKCQkJCSMgICAgICAgICAgICAgICAlZiA9IGZpbGUgbmFtZSBvbmx5CgkJCQkjIGUu Zy4gJ3Rlc3QgISAtZiAvbW50L3NlcnZlci9hcmNoaXZlZGlyLyVmICYmIGNwICVwIC9tbnQv c2VydmVyL2FyY2hpdmVkaXIvJWYnCiNhcmNoaXZlX3RpbWVvdXQgPSAwCQkjIGZvcmNlIGEg bG9nZmlsZSBzZWdtZW50IHN3aXRjaCBhZnRlciB0aGlzCgkJCQkjIG51bWJlciBvZiBzZWNv bmRzOyAwIGRpc2FibGVzCgoKIy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQojIFJFUExJQ0FU SU9OCiMtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiMgLSBTZW5kaW5nIFNlcnZlcihzKSAt CgojIFNldCB0aGVzZSBvbiB0aGUgbWFzdGVyIGFuZCBvbiBhbnkgc3RhbmRieSB0aGF0IHdp bGwgc2VuZCByZXBsaWNhdGlvbiBkYXRhLgoKbWF4X3dhbF9zZW5kZXJzID0gMAkJIyBtYXgg bnVtYmVyIG9mIHdhbHNlbmRlciBwcm9jZXNzZXMKCQkJCSMgKGNoYW5nZSByZXF1aXJlcyBy ZXN0YXJ0KQojd2FsX2tlZXBfc2VnbWVudHMgPSAwCQkjIGluIGxvZ2ZpbGUgc2VnbWVudHMs IDE2TUIgZWFjaDsgMCBkaXNhYmxlcwojd2FsX3NlbmRlcl90aW1lb3V0ID0gNjBzCSMgaW4g bWlsbGlzZWNvbmRzOyAwIGRpc2FibGVzCgojbWF4X3JlcGxpY2F0aW9uX3Nsb3RzID0gMTAJ IyBtYXggbnVtYmVyIG9mIHJlcGxpY2F0aW9uIHNsb3RzCgkJCQkjIChjaGFuZ2UgcmVxdWly ZXMgcmVzdGFydCkKI3RyYWNrX2NvbW1pdF90aW1lc3RhbXAgPSBvZmYJIyBjb2xsZWN0IHRp bWVzdGFtcCBvZiB0cmFuc2FjdGlvbiBjb21taXQKCQkJCSMgKGNoYW5nZSByZXF1aXJlcyBy ZXN0YXJ0KQoKIyAtIE1hc3RlciBTZXJ2ZXIgLQoKIyBUaGVzZSBzZXR0aW5ncyBhcmUgaWdu b3JlZCBvbiBhIHN0YW5kYnkgc2VydmVyLgoKI3N5bmNocm9ub3VzX3N0YW5kYnlfbmFtZXMg PSAnJwkjIHN0YW5kYnkgc2VydmVycyB0aGF0IHByb3ZpZGUgc3luYyByZXAKCQkJCSMgbWV0 aG9kIHRvIGNob29zZSBzeW5jIHN0YW5kYnlzLCBudW1iZXIgb2Ygc3luYyBzdGFuZGJ5cywK CQkJCSMgYW5kIGNvbW1hLXNlcGFyYXRlZCBsaXN0IG9mIGFwcGxpY2F0aW9uX25hbWUKCQkJ CSMgZnJvbSBzdGFuZGJ5KHMpOyAnKicgPSBhbGwKI3ZhY3V1bV9kZWZlcl9jbGVhbnVwX2Fn ZSA9IDAJIyBudW1iZXIgb2YgeGFjdHMgYnkgd2hpY2ggY2xlYW51cCBpcyBkZWxheWVkCgoj IC0gU3RhbmRieSBTZXJ2ZXJzIC0KCiMgVGhlc2Ugc2V0dGluZ3MgYXJlIGlnbm9yZWQgb24g YSBtYXN0ZXIgc2VydmVyLgoKI2hvdF9zdGFuZGJ5ID0gb24JCQkjICJvZmYiIGRpc2FsbG93 cyBxdWVyaWVzIGR1cmluZyByZWNvdmVyeQoJCQkJCSMgKGNoYW5nZSByZXF1aXJlcyByZXN0 YXJ0KQojbWF4X3N0YW5kYnlfYXJjaGl2ZV9kZWxheSA9IDMwcwkjIG1heCBkZWxheSBiZWZv cmUgY2FuY2VsaW5nIHF1ZXJpZXMKCQkJCQkjIHdoZW4gcmVhZGluZyBXQUwgZnJvbSBhcmNo aXZlOwoJCQkJCSMgLTEgYWxsb3dzIGluZGVmaW5pdGUgZGVsYXkKI21heF9zdGFuZGJ5X3N0 cmVhbWluZ19kZWxheSA9IDMwcwkjIG1heCBkZWxheSBiZWZvcmUgY2FuY2VsaW5nIHF1ZXJp ZXMKCQkJCQkjIHdoZW4gcmVhZGluZyBzdHJlYW1pbmcgV0FMOwoJCQkJCSMgLTEgYWxsb3dz IGluZGVmaW5pdGUgZGVsYXkKI3dhbF9yZWNlaXZlcl9zdGF0dXNfaW50ZXJ2YWwgPSAxMHMJ IyBzZW5kIHJlcGxpZXMgYXQgbGVhc3QgdGhpcyBvZnRlbgoJCQkJCSMgMCBkaXNhYmxlcwoj aG90X3N0YW5kYnlfZmVlZGJhY2sgPSBvZmYJCSMgc2VuZCBpbmZvIGZyb20gc3RhbmRieSB0 byBwcmV2ZW50CgkJCQkJIyBxdWVyeSBjb25mbGljdHMKI3dhbF9yZWNlaXZlcl90aW1lb3V0 ID0gNjBzCQkjIHRpbWUgdGhhdCByZWNlaXZlciB3YWl0cyBmb3IKCQkJCQkjIGNvbW11bmlj YXRpb24gZnJvbSBtYXN0ZXIKCQkJCQkjIGluIG1pbGxpc2Vjb25kczsgMCBkaXNhYmxlcwoj d2FsX3JldHJpZXZlX3JldHJ5X2ludGVydmFsID0gNXMJIyB0aW1lIHRvIHdhaXQgYmVmb3Jl IHJldHJ5aW5nIHRvCgkJCQkJIyByZXRyaWV2ZSBXQUwgYWZ0ZXIgYSBmYWlsZWQgYXR0ZW1w dAoKIyAtIFN1YnNjcmliZXJzIC0KCiMgVGhlc2Ugc2V0dGluZ3MgYXJlIGlnbm9yZWQgb24g YSBwdWJsaXNoZXIuCgojbWF4X2xvZ2ljYWxfcmVwbGljYXRpb25fd29ya2VycyA9IDQJIyB0 YWtlbiBmcm9tIG1heF93b3JrZXJfcHJvY2Vzc2VzCgkJCQkJIyAoY2hhbmdlIHJlcXVpcmVz IHJlc3RhcnQpCiNtYXhfc3luY193b3JrZXJzX3Blcl9zdWJzY3JpcHRpb24gPSAyCSMgdGFr ZW4gZnJvbSBtYXhfbG9naWNhbF9yZXBsaWNhdGlvbl93b3JrZXJzCgoKIy0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLQojIFFVRVJZIFRVTklORwojLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t CgojIC0gUGxhbm5lciBNZXRob2QgQ29uZmlndXJhdGlvbiAtCgojZW5hYmxlX2JpdG1hcHNj YW4gPSBvbgojZW5hYmxlX2hhc2hhZ2cgPSBvbgojZW5hYmxlX2hhc2hqb2luID0gb24KI2Vu YWJsZV9pbmRleHNjYW4gPSBvbgojZW5hYmxlX2luZGV4b25seXNjYW4gPSBvbgojZW5hYmxl X21hdGVyaWFsID0gb24KI2VuYWJsZV9tZXJnZWpvaW4gPSBvbgojZW5hYmxlX25lc3Rsb29w ID0gb24KI2VuYWJsZV9zZXFzY2FuID0gb24KI2VuYWJsZV9zb3J0ID0gb24KI2VuYWJsZV90 aWRzY2FuID0gb24KCiMgLSBQbGFubmVyIENvc3QgQ29uc3RhbnRzIC0KCiNzZXFfcGFnZV9j b3N0ID0gMS4wCQkJIyBtZWFzdXJlZCBvbiBhbiBhcmJpdHJhcnkgc2NhbGUKI3JhbmRvbV9w YWdlX2Nvc3QgPSA0LjAJCQkjIHNhbWUgc2NhbGUgYXMgYWJvdmUKI2NwdV90dXBsZV9jb3N0 ID0gMC4wMQkJCSMgc2FtZSBzY2FsZSBhcyBhYm92ZQojY3B1X2luZGV4X3R1cGxlX2Nvc3Qg PSAwLjAwNQkJIyBzYW1lIHNjYWxlIGFzIGFib3ZlCiNjcHVfb3BlcmF0b3JfY29zdCA9IDAu MDAyNQkJIyBzYW1lIHNjYWxlIGFzIGFib3ZlCiNwYXJhbGxlbF90dXBsZV9jb3N0ID0gMC4x CQkjIHNhbWUgc2NhbGUgYXMgYWJvdmUKI3BhcmFsbGVsX3NldHVwX2Nvc3QgPSAxMDAwLjAJ IyBzYW1lIHNjYWxlIGFzIGFib3ZlCiNtaW5fcGFyYWxsZWxfdGFibGVfc2Nhbl9zaXplID0g OE1CCiNtaW5fcGFyYWxsZWxfaW5kZXhfc2Nhbl9zaXplID0gNTEya0IKI2VmZmVjdGl2ZV9j YWNoZV9zaXplID0gNEdCCgojIC0gR2VuZXRpYyBRdWVyeSBPcHRpbWl6ZXIgLQoKI2dlcW8g PSBvbgojZ2Vxb190aHJlc2hvbGQgPSAxMgojZ2Vxb19lZmZvcnQgPSA1CQkJIyByYW5nZSAx LTEwCiNnZXFvX3Bvb2xfc2l6ZSA9IDAJCQkjIHNlbGVjdHMgZGVmYXVsdCBiYXNlZCBvbiBl ZmZvcnQKI2dlcW9fZ2VuZXJhdGlvbnMgPSAwCQkJIyBzZWxlY3RzIGRlZmF1bHQgYmFzZWQg b24gZWZmb3J0CiNnZXFvX3NlbGVjdGlvbl9iaWFzID0gMi4wCQkjIHJhbmdlIDEuNS0yLjAK I2dlcW9fc2VlZCA9IDAuMAkJCSMgcmFuZ2UgMC4wLTEuMAoKIyAtIE90aGVyIFBsYW5uZXIg T3B0aW9ucyAtCgojZGVmYXVsdF9zdGF0aXN0aWNzX3RhcmdldCA9IDEwMAkjIHJhbmdlIDEt MTAwMDAKI2NvbnN0cmFpbnRfZXhjbHVzaW9uID0gcGFydGl0aW9uCSMgb24sIG9mZiwgb3Ig cGFydGl0aW9uCiNjdXJzb3JfdHVwbGVfZnJhY3Rpb24gPSAwLjEJCSMgcmFuZ2UgMC4wLTEu MAojZnJvbV9jb2xsYXBzZV9saW1pdCA9IDgKI2pvaW5fY29sbGFwc2VfbGltaXQgPSA4CQkj IDEgZGlzYWJsZXMgY29sbGFwc2luZyBvZiBleHBsaWNpdAoJCQkJCSMgSk9JTiBjbGF1c2Vz CiNmb3JjZV9wYXJhbGxlbF9tb2RlID0gb2ZmCgoKIy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LQojIEVSUk9SIFJFUE9SVElORyBBTkQgTE9HR0lORwojLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tCgojIC0gV2hlcmUgdG8gTG9nIC0KCiNsb2dfZGVzdGluYXRpb24gPSAnc3RkZXJyJwkJ IyBWYWxpZCB2YWx1ZXMgYXJlIGNvbWJpbmF0aW9ucyBvZgoJCQkJCSMgc3RkZXJyLCBjc3Zs b2csIHN5c2xvZywgYW5kIGV2ZW50bG9nLAoJCQkJCSMgZGVwZW5kaW5nIG9uIHBsYXRmb3Jt LiAgY3N2bG9nCgkJCQkJIyByZXF1aXJlcyBsb2dnaW5nX2NvbGxlY3RvciB0byBiZSBvbi4K CiMgVGhpcyBpcyB1c2VkIHdoZW4gbG9nZ2luZyB0byBzdGRlcnI6CiNsb2dnaW5nX2NvbGxl Y3RvciA9IG9mZgkJIyBFbmFibGUgY2FwdHVyaW5nIG9mIHN0ZGVyciBhbmQgY3N2bG9nCgkJ CQkJIyBpbnRvIGxvZyBmaWxlcy4gUmVxdWlyZWQgdG8gYmUgb24gZm9yCgkJCQkJIyBjc3Zs b2dzLgoJCQkJCSMgKGNoYW5nZSByZXF1aXJlcyByZXN0YXJ0KQoKIyBUaGVzZSBhcmUgb25s eSB1c2VkIGlmIGxvZ2dpbmdfY29sbGVjdG9yIGlzIG9uOgojbG9nX2RpcmVjdG9yeSA9ICds b2cnCQkJIyBkaXJlY3Rvcnkgd2hlcmUgbG9nIGZpbGVzIGFyZSB3cml0dGVuLAoJCQkJCSMg Y2FuIGJlIGFic29sdXRlIG9yIHJlbGF0aXZlIHRvIFBHREFUQQojbG9nX2ZpbGVuYW1lID0g J3Bvc3RncmVzcWwtJVktJW0tJWRfJUglTSVTLmxvZycJIyBsb2cgZmlsZSBuYW1lIHBhdHRl cm4sCgkJCQkJIyBjYW4gaW5jbHVkZSBzdHJmdGltZSgpIGVzY2FwZXMKI2xvZ19maWxlX21v ZGUgPSAwNjAwCQkJIyBjcmVhdGlvbiBtb2RlIGZvciBsb2cgZmlsZXMsCgkJCQkJIyBiZWdp biB3aXRoIDAgdG8gdXNlIG9jdGFsIG5vdGF0aW9uCiNsb2dfdHJ1bmNhdGVfb25fcm90YXRp b24gPSBvZmYJCSMgSWYgb24sIGFuIGV4aXN0aW5nIGxvZyBmaWxlIHdpdGggdGhlCgkJCQkJ IyBzYW1lIG5hbWUgYXMgdGhlIG5ldyBsb2cgZmlsZSB3aWxsIGJlCgkJCQkJIyB0cnVuY2F0 ZWQgcmF0aGVyIHRoYW4gYXBwZW5kZWQgdG8uCgkJCQkJIyBCdXQgc3VjaCB0cnVuY2F0aW9u IG9ubHkgb2NjdXJzIG9uCgkJCQkJIyB0aW1lLWRyaXZlbiByb3RhdGlvbiwgbm90IG9uIHJl c3RhcnRzCgkJCQkJIyBvciBzaXplLWRyaXZlbiByb3RhdGlvbi4gIERlZmF1bHQgaXMKCQkJ CQkjIG9mZiwgbWVhbmluZyBhcHBlbmQgdG8gZXhpc3RpbmcgZmlsZXMKCQkJCQkjIGluIGFs bCBjYXNlcy4KI2xvZ19yb3RhdGlvbl9hZ2UgPSAxZAkJCSMgQXV0b21hdGljIHJvdGF0aW9u IG9mIGxvZ2ZpbGVzIHdpbGwKCQkJCQkjIGhhcHBlbiBhZnRlciB0aGF0IHRpbWUuICAwIGRp c2FibGVzLgojbG9nX3JvdGF0aW9uX3NpemUgPSAxME1CCQkjIEF1dG9tYXRpYyByb3RhdGlv biBvZiBsb2dmaWxlcyB3aWxsCgkJCQkJIyBoYXBwZW4gYWZ0ZXIgdGhhdCBtdWNoIGxvZyBv dXRwdXQuCgkJCQkJIyAwIGRpc2FibGVzLgoKIyBUaGVzZSBhcmUgcmVsZXZhbnQgd2hlbiBs b2dnaW5nIHRvIHN5c2xvZzoKI3N5c2xvZ19mYWNpbGl0eSA9ICdMT0NBTDAnCiNzeXNsb2df aWRlbnQgPSAncG9zdGdyZXMnCiNzeXNsb2dfc2VxdWVuY2VfbnVtYmVycyA9IG9uCiNzeXNs b2dfc3BsaXRfbWVzc2FnZXMgPSBvbgoKIyBUaGlzIGlzIG9ubHkgcmVsZXZhbnQgd2hlbiBs b2dnaW5nIHRvIGV2ZW50bG9nICh3aW4zMik6CiMgKGNoYW5nZSByZXF1aXJlcyByZXN0YXJ0 KQojZXZlbnRfc291cmNlID0gJ1Bvc3RncmVTUUwnCgojIC0gV2hlbiB0byBMb2cgLQoKI2Ns aWVudF9taW5fbWVzc2FnZXMgPSBub3RpY2UJCSMgdmFsdWVzIGluIG9yZGVyIG9mIGRlY3Jl YXNpbmcgZGV0YWlsOgoJCQkJCSMgICBkZWJ1ZzUKCQkJCQkjICAgZGVidWc0CgkJCQkJIyAg IGRlYnVnMwoJCQkJCSMgICBkZWJ1ZzIKCQkJCQkjICAgZGVidWcxCgkJCQkJIyAgIGxvZwoJ CQkJCSMgICBub3RpY2UKCQkJCQkjICAgd2FybmluZwoJCQkJCSMgICBlcnJvcgoKI2xvZ19t aW5fbWVzc2FnZXMgPSB3YXJuaW5nCQkjIHZhbHVlcyBpbiBvcmRlciBvZiBkZWNyZWFzaW5n IGRldGFpbDoKCQkJCQkjICAgZGVidWc1CgkJCQkJIyAgIGRlYnVnNAoJCQkJCSMgICBkZWJ1 ZzMKCQkJCQkjICAgZGVidWcyCgkJCQkJIyAgIGRlYnVnMQoJCQkJCSMgICBpbmZvCgkJCQkJ IyAgIG5vdGljZQoJCQkJCSMgICB3YXJuaW5nCgkJCQkJIyAgIGVycm9yCgkJCQkJIyAgIGxv ZwoJCQkJCSMgICBmYXRhbAoJCQkJCSMgICBwYW5pYwoKI2xvZ19taW5fZXJyb3Jfc3RhdGVt ZW50ID0gZXJyb3IJIyB2YWx1ZXMgaW4gb3JkZXIgb2YgZGVjcmVhc2luZyBkZXRhaWw6CgkJ CQkJIyAgIGRlYnVnNQoJCQkJCSMgICBkZWJ1ZzQKCQkJCQkjICAgZGVidWczCgkJCQkJIyAg IGRlYnVnMgoJCQkJCSMgICBkZWJ1ZzEKCQkJCQkjICAgaW5mbwoJCQkJCSMgICBub3RpY2UK CQkJCQkjICAgd2FybmluZwoJCQkJCSMgICBlcnJvcgoJCQkJCSMgICBsb2cKCQkJCQkjICAg ZmF0YWwKCQkJCQkjICAgcGFuaWMgKGVmZmVjdGl2ZWx5IG9mZikKCiNsb2dfbWluX2R1cmF0 aW9uX3N0YXRlbWVudCA9IC0xCSMgLTEgaXMgZGlzYWJsZWQsIDAgbG9ncyBhbGwgc3RhdGVt ZW50cwoJCQkJCSMgYW5kIHRoZWlyIGR1cmF0aW9ucywgPiAwIGxvZ3Mgb25seQoJCQkJCSMg c3RhdGVtZW50cyBydW5uaW5nIGF0IGxlYXN0IHRoaXMgbnVtYmVyCgkJCQkJIyBvZiBtaWxs aXNlY29uZHMKCgojIC0gV2hhdCB0byBMb2cgLQoKI2RlYnVnX3ByaW50X3BhcnNlID0gb2Zm CiNkZWJ1Z19wcmludF9yZXdyaXR0ZW4gPSBvZmYKI2RlYnVnX3ByaW50X3BsYW4gPSBvZmYK I2RlYnVnX3ByZXR0eV9wcmludCA9IG9uCiNsb2dfY2hlY2twb2ludHMgPSBvZmYKI2xvZ19j b25uZWN0aW9ucyA9IG9mZgojbG9nX2Rpc2Nvbm5lY3Rpb25zID0gb2ZmCiNsb2dfZHVyYXRp b24gPSBvZmYKI2xvZ19lcnJvcl92ZXJib3NpdHkgPSBkZWZhdWx0CQkjIHRlcnNlLCBkZWZh dWx0LCBvciB2ZXJib3NlIG1lc3NhZ2VzCiNsb2dfaG9zdG5hbWUgPSBvZmYKI2xvZ19saW5l X3ByZWZpeCA9ICclbSBbJXBdICcJCSMgc3BlY2lhbCB2YWx1ZXM6CgkJCQkJIyAgICVhID0g YXBwbGljYXRpb24gbmFtZQoJCQkJCSMgICAldSA9IHVzZXIgbmFtZQoJCQkJCSMgICAlZCA9 IGRhdGFiYXNlIG5hbWUKCQkJCQkjICAgJXIgPSByZW1vdGUgaG9zdCBhbmQgcG9ydAoJCQkJ CSMgICAlaCA9IHJlbW90ZSBob3N0CgkJCQkJIyAgICVwID0gcHJvY2VzcyBJRAoJCQkJCSMg ICAldCA9IHRpbWVzdGFtcCB3aXRob3V0IG1pbGxpc2Vjb25kcwoJCQkJCSMgICAlbSA9IHRp bWVzdGFtcCB3aXRoIG1pbGxpc2Vjb25kcwoJCQkJCSMgICAlbiA9IHRpbWVzdGFtcCB3aXRo IG1pbGxpc2Vjb25kcyAoYXMgYSBVbml4IGVwb2NoKQoJCQkJCSMgICAlaSA9IGNvbW1hbmQg dGFnCgkJCQkJIyAgICVlID0gU1FMIHN0YXRlCgkJCQkJIyAgICVjID0gc2Vzc2lvbiBJRAoJ CQkJCSMgICAlbCA9IHNlc3Npb24gbGluZSBudW1iZXIKCQkJCQkjICAgJXMgPSBzZXNzaW9u IHN0YXJ0IHRpbWVzdGFtcAoJCQkJCSMgICAldiA9IHZpcnR1YWwgdHJhbnNhY3Rpb24gSUQK CQkJCQkjICAgJXggPSB0cmFuc2FjdGlvbiBJRCAoMCBpZiBub25lKQoJCQkJCSMgICAlcSA9 IHN0b3AgaGVyZSBpbiBub24tc2Vzc2lvbgoJCQkJCSMgICAgICAgIHByb2Nlc3NlcwoJCQkJ CSMgICAlJSA9ICclJwoJCQkJCSMgZS5nLiAnPCV1JSUlZD4gJwojbG9nX2xvY2tfd2FpdHMg PSBvZmYJCQkjIGxvZyBsb2NrIHdhaXRzID49IGRlYWRsb2NrX3RpbWVvdXQKI2xvZ19zdGF0 ZW1lbnQgPSAnbm9uZScJCQkjIG5vbmUsIGRkbCwgbW9kLCBhbGwKI2xvZ19yZXBsaWNhdGlv bl9jb21tYW5kcyA9IG9mZgojbG9nX3RlbXBfZmlsZXMgPSAtMQkJCSMgbG9nIHRlbXBvcmFy eSBmaWxlcyBlcXVhbCBvciBsYXJnZXIKCQkJCQkjIHRoYW4gdGhlIHNwZWNpZmllZCBzaXpl IGluIGtpbG9ieXRlczsKCQkJCQkjIC0xIGRpc2FibGVzLCAwIGxvZ3MgYWxsIHRlbXAgZmls ZXMKbG9nX3RpbWV6b25lID0gJ1ctU1UnCgoKIyAtIFByb2Nlc3MgVGl0bGUgLQoKI2NsdXN0 ZXJfbmFtZSA9ICcnCQkJIyBhZGRlZCB0byBwcm9jZXNzIHRpdGxlcyBpZiBub25lbXB0eQoJ CQkJCSMgKGNoYW5nZSByZXF1aXJlcyByZXN0YXJ0KQojdXBkYXRlX3Byb2Nlc3NfdGl0bGUg PSBvbgoKCiMtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KIyBSVU5USU1FIFNUQVRJU1RJQ1MK Iy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKIyAtIFF1ZXJ5L0luZGV4IFN0YXRpc3RpY3Mg Q29sbGVjdG9yIC0KCiN0cmFja19hY3Rpdml0aWVzID0gb24KI3RyYWNrX2NvdW50cyA9IG9u CiN0cmFja19pb190aW1pbmcgPSBvZmYKI3RyYWNrX2Z1bmN0aW9ucyA9IG5vbmUJCQkjIG5v bmUsIHBsLCBhbGwKI3RyYWNrX2FjdGl2aXR5X3F1ZXJ5X3NpemUgPSAxMDI0CSMgKGNoYW5n ZSByZXF1aXJlcyByZXN0YXJ0KQojc3RhdHNfdGVtcF9kaXJlY3RvcnkgPSAncGdfc3RhdF90 bXAnCgoKIyAtIFN0YXRpc3RpY3MgTW9uaXRvcmluZyAtCgojbG9nX3BhcnNlcl9zdGF0cyA9 IG9mZgojbG9nX3BsYW5uZXJfc3RhdHMgPSBvZmYKI2xvZ19leGVjdXRvcl9zdGF0cyA9IG9m ZgojbG9nX3N0YXRlbWVudF9zdGF0cyA9IG9mZgoKCiMtLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0KIyBBVVRPVkFDVVVNIFBBUkFNRVRFUlMKIy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoK I2F1dG92YWN1dW0gPSBvbgkJCSMgRW5hYmxlIGF1dG92YWN1dW0gc3VicHJvY2Vzcz8gICdv bicKCQkJCQkjIHJlcXVpcmVzIHRyYWNrX2NvdW50cyB0byBhbHNvIGJlIG9uLgojbG9nX2F1 dG92YWN1dW1fbWluX2R1cmF0aW9uID0gLTEJIyAtMSBkaXNhYmxlcywgMCBsb2dzIGFsbCBh Y3Rpb25zIGFuZAoJCQkJCSMgdGhlaXIgZHVyYXRpb25zLCA+IDAgbG9ncyBvbmx5CgkJCQkJ IyBhY3Rpb25zIHJ1bm5pbmcgYXQgbGVhc3QgdGhpcyBudW1iZXIKCQkJCQkjIG9mIG1pbGxp c2Vjb25kcy4KI2F1dG92YWN1dW1fbWF4X3dvcmtlcnMgPSAzCQkjIG1heCBudW1iZXIgb2Yg YXV0b3ZhY3V1bSBzdWJwcm9jZXNzZXMKCQkJCQkjIChjaGFuZ2UgcmVxdWlyZXMgcmVzdGFy dCkKI2F1dG92YWN1dW1fbmFwdGltZSA9IDFtaW4JCSMgdGltZSBiZXR3ZWVuIGF1dG92YWN1 dW0gcnVucwojYXV0b3ZhY3V1bV92YWN1dW1fdGhyZXNob2xkID0gNTAJIyBtaW4gbnVtYmVy IG9mIHJvdyB1cGRhdGVzIGJlZm9yZQoJCQkJCSMgdmFjdXVtCiNhdXRvdmFjdXVtX2FuYWx5 emVfdGhyZXNob2xkID0gNTAJIyBtaW4gbnVtYmVyIG9mIHJvdyB1cGRhdGVzIGJlZm9yZQoJ CQkJCSMgYW5hbHl6ZQojYXV0b3ZhY3V1bV92YWN1dW1fc2NhbGVfZmFjdG9yID0gMC4yCSMg ZnJhY3Rpb24gb2YgdGFibGUgc2l6ZSBiZWZvcmUgdmFjdXVtCiNhdXRvdmFjdXVtX2FuYWx5 emVfc2NhbGVfZmFjdG9yID0gMC4xCSMgZnJhY3Rpb24gb2YgdGFibGUgc2l6ZSBiZWZvcmUg YW5hbHl6ZQojYXV0b3ZhY3V1bV9mcmVlemVfbWF4X2FnZSA9IDIwMDAwMDAwMAkjIG1heGlt dW0gWElEIGFnZSBiZWZvcmUgZm9yY2VkIHZhY3V1bQoJCQkJCSMgKGNoYW5nZSByZXF1aXJl cyByZXN0YXJ0KQojYXV0b3ZhY3V1bV9tdWx0aXhhY3RfZnJlZXplX21heF9hZ2UgPSA0MDAw MDAwMDAJIyBtYXhpbXVtIG11bHRpeGFjdCBhZ2UKCQkJCQkjIGJlZm9yZSBmb3JjZWQgdmFj dXVtCgkJCQkJIyAoY2hhbmdlIHJlcXVpcmVzIHJlc3RhcnQpCiNhdXRvdmFjdXVtX3ZhY3V1 bV9jb3N0X2RlbGF5ID0gMjBtcwkjIGRlZmF1bHQgdmFjdXVtIGNvc3QgZGVsYXkgZm9yCgkJ CQkJIyBhdXRvdmFjdXVtLCBpbiBtaWxsaXNlY29uZHM7CgkJCQkJIyAtMSBtZWFucyB1c2Ug dmFjdXVtX2Nvc3RfZGVsYXkKI2F1dG92YWN1dW1fdmFjdXVtX2Nvc3RfbGltaXQgPSAtMQkj IGRlZmF1bHQgdmFjdXVtIGNvc3QgbGltaXQgZm9yCgkJCQkJIyBhdXRvdmFjdXVtLCAtMSBt ZWFucyB1c2UKCQkJCQkjIHZhY3V1bV9jb3N0X2xpbWl0CgoKIy0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLQojIENMSUVOVCBDT05ORUNUSU9OIERFRkFVTFRTCiMtLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0KCiMgLSBTdGF0ZW1lbnQgQmVoYXZpb3IgLQoKI3NlYXJjaF9wYXRoID0gJyIk dXNlciIsIHB1YmxpYycJIyBzY2hlbWEgbmFtZXMKI2RlZmF1bHRfdGFibGVzcGFjZSA9ICcn CQkjIGEgdGFibGVzcGFjZSBuYW1lLCAnJyB1c2VzIHRoZSBkZWZhdWx0CiN0ZW1wX3RhYmxl c3BhY2VzID0gJycJCQkjIGEgbGlzdCBvZiB0YWJsZXNwYWNlIG5hbWVzLCAnJyB1c2VzCgkJ CQkJIyBvbmx5IGRlZmF1bHQgdGFibGVzcGFjZQojY2hlY2tfZnVuY3Rpb25fYm9kaWVzID0g b24KI2RlZmF1bHRfdHJhbnNhY3Rpb25faXNvbGF0aW9uID0gJ3JlYWQgY29tbWl0dGVkJwoj ZGVmYXVsdF90cmFuc2FjdGlvbl9yZWFkX29ubHkgPSBvZmYKI2RlZmF1bHRfdHJhbnNhY3Rp b25fZGVmZXJyYWJsZSA9IG9mZgojc2Vzc2lvbl9yZXBsaWNhdGlvbl9yb2xlID0gJ29yaWdp bicKI3N0YXRlbWVudF90aW1lb3V0ID0gMAkJCSMgaW4gbWlsbGlzZWNvbmRzLCAwIGlzIGRp c2FibGVkCiNsb2NrX3RpbWVvdXQgPSAwCQkJIyBpbiBtaWxsaXNlY29uZHMsIDAgaXMgZGlz YWJsZWQKI2lkbGVfaW5fdHJhbnNhY3Rpb25fc2Vzc2lvbl90aW1lb3V0ID0gMAkjIGluIG1p bGxpc2Vjb25kcywgMCBpcyBkaXNhYmxlZAojdmFjdXVtX2ZyZWV6ZV9taW5fYWdlID0gNTAw MDAwMDAKI3ZhY3V1bV9mcmVlemVfdGFibGVfYWdlID0gMTUwMDAwMDAwCiN2YWN1dW1fbXVs dGl4YWN0X2ZyZWV6ZV9taW5fYWdlID0gNTAwMDAwMAojdmFjdXVtX211bHRpeGFjdF9mcmVl emVfdGFibGVfYWdlID0gMTUwMDAwMDAwCiNieXRlYV9vdXRwdXQgPSAnaGV4JwkJCSMgaGV4 LCBlc2NhcGUKI3htbGJpbmFyeSA9ICdiYXNlNjQnCiN4bWxvcHRpb24gPSAnY29udGVudCcK I2dpbl9mdXp6eV9zZWFyY2hfbGltaXQgPSAwCiNnaW5fcGVuZGluZ19saXN0X2xpbWl0ID0g NE1CCgojIC0gTG9jYWxlIGFuZCBGb3JtYXR0aW5nIC0KCmRhdGVzdHlsZSA9ICdpc28sIGRt eScKI2ludGVydmFsc3R5bGUgPSAncG9zdGdyZXMnCnRpbWV6b25lID0gJ1ctU1UnCiN0aW1l em9uZV9hYmJyZXZpYXRpb25zID0gJ0RlZmF1bHQnICAgICAjIFNlbGVjdCB0aGUgc2V0IG9m IGF2YWlsYWJsZSB0aW1lIHpvbmUKCQkJCQkjIGFiYnJldmlhdGlvbnMuICBDdXJyZW50bHks IHRoZXJlIGFyZQoJCQkJCSMgICBEZWZhdWx0CgkJCQkJIyAgIEF1c3RyYWxpYSAoaGlzdG9y aWNhbCB1c2FnZSkKCQkJCQkjICAgSW5kaWEKCQkJCQkjIFlvdSBjYW4gY3JlYXRlIHlvdXIg b3duIGZpbGUgaW4KCQkJCQkjIHNoYXJlL3RpbWV6b25lc2V0cy8uCiNleHRyYV9mbG9hdF9k aWdpdHMgPSAwCQkJIyBtaW4gLTE1LCBtYXggMwojY2xpZW50X2VuY29kaW5nID0gc3FsX2Fz Y2lpCQkjIGFjdHVhbGx5LCBkZWZhdWx0cyB0byBkYXRhYmFzZQoJCQkJCSMgZW5jb2RpbmcK CiMgVGhlc2Ugc2V0dGluZ3MgYXJlIGluaXRpYWxpemVkIGJ5IGluaXRkYiwgYnV0IHRoZXkg Y2FuIGJlIGNoYW5nZWQuCmxjX21lc3NhZ2VzID0gJ2VuX1VTLlVURi04JwkJCSMgbG9jYWxl IGZvciBzeXN0ZW0gZXJyb3IgbWVzc2FnZQoJCQkJCSMgc3RyaW5ncwpsY19tb25ldGFyeSA9 ICdydV9SVS5VVEYtOCcJCQkjIGxvY2FsZSBmb3IgbW9uZXRhcnkgZm9ybWF0dGluZwpsY19u dW1lcmljID0gJ3J1X1JVLlVURi04JwkJCSMgbG9jYWxlIGZvciBudW1iZXIgZm9ybWF0dGlu ZwpsY190aW1lID0gJ3J1X1JVLlVURi04JwkJCQkjIGxvY2FsZSBmb3IgdGltZSBmb3JtYXR0 aW5nCgojIGRlZmF1bHQgY29uZmlndXJhdGlvbiBmb3IgdGV4dCBzZWFyY2gKZGVmYXVsdF90 ZXh0X3NlYXJjaF9jb25maWcgPSAncGdfY2F0YWxvZy5lbmdsaXNoJwoKIyAtIE90aGVyIERl ZmF1bHRzIC0KCiNkeW5hbWljX2xpYnJhcnlfcGF0aCA9ICckbGliZGlyJwojbG9jYWxfcHJl bG9hZF9saWJyYXJpZXMgPSAnJwojc2Vzc2lvbl9wcmVsb2FkX2xpYnJhcmllcyA9ICcnCgoK Iy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQojIExPQ0sgTUFOQUdFTUVOVAojLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tCgojZGVhZGxvY2tfdGltZW91dCA9IDFzCiNtYXhfbG9ja3NfcGVy X3RyYW5zYWN0aW9uID0gNjQJCSMgbWluIDEwCgkJCQkJIyAoY2hhbmdlIHJlcXVpcmVzIHJl c3RhcnQpCiNtYXhfcHJlZF9sb2Nrc19wZXJfdHJhbnNhY3Rpb24gPSA2NAkjIG1pbiAxMAoJ CQkJCSMgKGNoYW5nZSByZXF1aXJlcyByZXN0YXJ0KQojbWF4X3ByZWRfbG9ja3NfcGVyX3Jl bGF0aW9uID0gLTIJIyBuZWdhdGl2ZSB2YWx1ZXMgbWVhbgoJCQkJCSMgKG1heF9wcmVkX2xv Y2tzX3Blcl90cmFuc2FjdGlvbgoJCQkJCSMgIC8gLW1heF9wcmVkX2xvY2tzX3Blcl9yZWxh dGlvbikgLSAxCiNtYXhfcHJlZF9sb2Nrc19wZXJfcGFnZSA9IDIgICAgICAgICAgICAjIG1p biAwCgoKIy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQojIFZFUlNJT04vUExBVEZPUk0gQ09N UEFUSUJJTElUWQojLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgojIC0gUHJldmlvdXMgUG9z dGdyZVNRTCBWZXJzaW9ucyAtCgojYXJyYXlfbnVsbHMgPSBvbgojYmFja3NsYXNoX3F1b3Rl ID0gc2FmZV9lbmNvZGluZwkjIG9uLCBvZmYsIG9yIHNhZmVfZW5jb2RpbmcKI2RlZmF1bHRf d2l0aF9vaWRzID0gb2ZmCiNlc2NhcGVfc3RyaW5nX3dhcm5pbmcgPSBvbgojbG9fY29tcGF0 X3ByaXZpbGVnZXMgPSBvZmYKI29wZXJhdG9yX3ByZWNlZGVuY2Vfd2FybmluZyA9IG9mZgoj cXVvdGVfYWxsX2lkZW50aWZpZXJzID0gb2ZmCiNzdGFuZGFyZF9jb25mb3JtaW5nX3N0cmlu Z3MgPSBvbgojc3luY2hyb25pemVfc2Vxc2NhbnMgPSBvbgoKIyAtIE90aGVyIFBsYXRmb3Jt cyBhbmQgQ2xpZW50cyAtCgojdHJhbnNmb3JtX251bGxfZXF1YWxzID0gb2ZmCgoKIy0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLQojIEVSUk9SIEhBTkRMSU5HCiMtLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0KCiNleGl0X29uX2Vycm9yID0gb2ZmCQkJIyB0ZXJtaW5hdGUgc2Vzc2lvbiBv biBhbnkgZXJyb3I/CiNyZXN0YXJ0X2FmdGVyX2NyYXNoID0gb24JCSMgcmVpbml0aWFsaXpl IGFmdGVyIGJhY2tlbmQgY3Jhc2g/CgoKIy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQojIENP TkZJRyBGSUxFIElOQ0xVREVTCiMtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiMgVGhlc2Ug b3B0aW9ucyBhbGxvdyBzZXR0aW5ncyB0byBiZSBsb2FkZWQgZnJvbSBmaWxlcyBvdGhlciB0 aGFuIHRoZQojIGRlZmF1bHQgcG9zdGdyZXNxbC5jb25mLgoKI2luY2x1ZGVfZGlyID0gJ2Nv bmYuZCcJCQkjIGluY2x1ZGUgZmlsZXMgZW5kaW5nIGluICcuY29uZicgZnJvbQoJCQkJCSMg ZGlyZWN0b3J5ICdjb25mLmQnCiNpbmNsdWRlX2lmX2V4aXN0cyA9ICdleGlzdHMuY29uZicJ IyBpbmNsdWRlIGZpbGUgb25seSBpZiBpdCBleGlzdHMKI2luY2x1ZGUgPSAnc3BlY2lhbC5j b25mJwkJIyBpbmNsdWRlIGZpbGUKCgojLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiMgQ1VT VE9NSVpFRCBPUFRJT05TCiMtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiMgQWRkIHNldHRp bmdzIGZvciBleHRlbnNpb25zIGhlcmUK --------------000004060508030804080906 Content-Type: application/sql; name="test00.sql" Content-Transfer-Encoding: base64 Content-Disposition: attachment; filename="test00.sql" Q1JFQVRFIEVYVEVOU0lPTiBydW07CgpDUkVBVEUgVEFCTEUgdHN0IChpIGludDQsIHQgdHN2 ZWN0b3IpOwpJTlNFUlQgSU5UTyB0c3QgU0VMRUNUIGklMTAsIHRvX3RzdmVjdG9yKCdzaW1w bGUnLCBzdWJzdHIobWQ1KGk6OnRleHQpLCAxLCAxKSkgRlJPTSBnZW5lcmF0ZV9zZXJpZXMo MSwxMDAwMDApIGk7CkNSRUFURSBJTkRFWCB0c3RpZHggT04gdHN0IFVTSU5HIHJ1bSAodCBy dW1fdHN2ZWN0b3Jfb3BzKTsKCkRFTEVURSBGUk9NIHRzdCBXSEVSRSBpID0gMTsKVkFDVVVN IHRzdDsKSU5TRVJUIElOVE8gdHN0IFNFTEVDVCBpJTEwLCB0b190c3ZlY3Rvcignc2ltcGxl Jywgc3Vic3RyKG1kNShpOjp0ZXh0KSwgMSwgMSkpIEZST00gZ2VuZXJhdGVfc2VyaWVzKDEw MDAxLDExMDAwKSBpOwoKREVMRVRFIEZST00gdHN0IFdIRVJFIGkgPSAyOwpWQUNVVU0gdHN0 OwpJTlNFUlQgSU5UTyB0c3QgU0VMRUNUIGklMTAsIHRvX3RzdmVjdG9yKCdzaW1wbGUnLCBz dWJzdHIobWQ1KGk6OnRleHQpLCAxLCAxKSkgRlJPTSBnZW5lcmF0ZV9zZXJpZXMoMTEwMDEs MTIwMDApIGk7CgpERUxFVEUgRlJPTSB0c3QgV0hFUkUgaSA9IDM7ClZBQ1VVTSB0c3Q7CklO U0VSVCBJTlRPIHRzdCBTRUxFQ1QgaSUxMCwgdG9fdHN2ZWN0b3IoJ3NpbXBsZScsIHN1YnN0 cihtZDUoaTo6dGV4dCksIDEsIDEpKSBGUk9NIGdlbmVyYXRlX3NlcmllcygxMjAwMSwxMzAw MCkgaTsKCkRFTEVURSBGUk9NIHRzdCBXSEVSRSBpID0gNDsKVkFDVVVNIHRzdDsKSU5TRVJU IElOVE8gdHN0IFNFTEVDVCBpJTEwLCB0b190c3ZlY3Rvcignc2ltcGxlJywgc3Vic3RyKG1k NShpOjp0ZXh0KSwgMSwgMSkpIEZST00gZ2VuZXJhdGVfc2VyaWVzKDEzMDAxLDE0MDAwKSBp OwoKREVMRVRFIEZST00gdHN0IFdIRVJFIGkgPSA1OwpWQUNVVU0gdHN0OwpJTlNFUlQgSU5U TyB0c3QgU0VMRUNUIGklMTAsIHRvX3RzdmVjdG9yKCdzaW1wbGUnLCBzdWJzdHIobWQ1KGk6 OnRleHQpLCAxLCAxKSkgRlJPTSBnZW5lcmF0ZV9zZXJpZXMoMTQwMDEsMTUwMDApIGk7CgpE RUxFVEUgRlJPTSB0c3QgV0hFUkUgaSA9IDY7ClZBQ1VVTSB0c3Q7CklOU0VSVCBJTlRPIHRz dCBTRUxFQ1QgaSUxMCwgdG9fdHN2ZWN0b3IoJ3NpbXBsZScsIHN1YnN0cihtZDUoaTo6dGV4 dCksIDEsIDEpKSBGUk9NIGdlbmVyYXRlX3NlcmllcygxNTAwMSwxNjAwMCkgaTsKCkRFTEVU RSBGUk9NIHRzdCBXSEVSRSBpID0gNzsKVkFDVVVNIHRzdDsKSU5TRVJUIElOVE8gdHN0IFNF TEVDVCBpJTEwLCB0b190c3ZlY3Rvcignc2ltcGxlJywgc3Vic3RyKG1kNShpOjp0ZXh0KSwg MSwgMSkpIEZST00gZ2VuZXJhdGVfc2VyaWVzKDE2MDAxLDE3MDAwKSBpOwoKREVMRVRFIEZS T00gdHN0IFdIRVJFIGkgPSA4OwpWQUNVVU0gdHN0OwpJTlNFUlQgSU5UTyB0c3QgU0VMRUNU IGklMTAsIHRvX3RzdmVjdG9yKCdzaW1wbGUnLCBzdWJzdHIobWQ1KGk6OnRleHQpLCAxLCAx KSkgRlJPTSBnZW5lcmF0ZV9zZXJpZXMoMTcwMDEsMTgwMDApIGk7CgpERUxFVEUgRlJPTSB0 c3QgV0hFUkUgaSA9IDk7ClZBQ1VVTSB0c3Q7CklOU0VSVCBJTlRPIHRzdCBTRUxFQ1QgaSUx MCwgdG9fdHN2ZWN0b3IoJ3NpbXBsZScsIHN1YnN0cihtZDUoaTo6dGV4dCksIDEsIDEpKSBG Uk9NIGdlbmVyYXRlX3NlcmllcygxODAwMSwxOTAwMCkgaTsKCkRST1AgVEFCTEUgdHN0OwpE Uk9QIEVYVEVOU0lPTiBydW07Cg== --------------000004060508030804080906 Content-Type: application/sql; name="test01.sql" Content-Transfer-Encoding: base64 Content-Disposition: attachment; filename="test01.sql" Q1JFQVRFIEVYVEVOU0lPTiBydW07CgpDUkVBVEUgVEFCTEUgdHN0IChpIGludDQsIHQgdHN2 ZWN0b3IpOwpJTlNFUlQgSU5UTyB0c3QgU0VMRUNUIGklMTAsIHRvX3RzdmVjdG9yKCdzaW1w bGUnLCBzdWJzdHIobWQ1KGk6OnRleHQpLCAxLCAxKSkgRlJPTSBnZW5lcmF0ZV9zZXJpZXMo MSwxMDAwMDApIGk7CkNSRUFURSBJTkRFWCB0c3RpZHggT04gdHN0IFVTSU5HIHJ1bSAodCBy dW1fdHN2ZWN0b3Jfb3BzKTsKCkRFTEVURSBGUk9NIHRzdCBXSEVSRSBpID0gMTsKVkFDVVVN IHRzdDsKSU5TRVJUIElOVE8gdHN0IFNFTEVDVCBpJTEwLCB0b190c3ZlY3Rvcignc2ltcGxl Jywgc3Vic3RyKG1kNShpOjp0ZXh0KSwgMSwgMSkpIEZST00gZ2VuZXJhdGVfc2VyaWVzKDEw MDAxLDExMDAwKSBpOwoKREVMRVRFIEZST00gdHN0IFdIRVJFIGkgPSAyOwpWQUNVVU0gdHN0 OwpJTlNFUlQgSU5UTyB0c3QgU0VMRUNUIGklMTAsIHRvX3RzdmVjdG9yKCdzaW1wbGUnLCBz dWJzdHIobWQ1KGk6OnRleHQpLCAxLCAxKSkgRlJPTSBnZW5lcmF0ZV9zZXJpZXMoMTEwMDEs MTIwMDApIGk7CgpERUxFVEUgRlJPTSB0c3QgV0hFUkUgaSA9IDM7ClZBQ1VVTSB0c3Q7CklO U0VSVCBJTlRPIHRzdCBTRUxFQ1QgaSUxMCwgdG9fdHN2ZWN0b3IoJ3NpbXBsZScsIHN1YnN0 cihtZDUoaTo6dGV4dCksIDEsIDEpKSBGUk9NIGdlbmVyYXRlX3NlcmllcygxMjAwMSwxMzAw MCkgaTsKCkRFTEVURSBGUk9NIHRzdCBXSEVSRSBpID0gNDsKVkFDVVVNIHRzdDsKSU5TRVJU IElOVE8gdHN0IFNFTEVDVCBpJTEwLCB0b190c3ZlY3Rvcignc2ltcGxlJywgc3Vic3RyKG1k NShpOjp0ZXh0KSwgMSwgMSkpIEZST00gZ2VuZXJhdGVfc2VyaWVzKDEzMDAxLDE0MDAwKSBp OwoKREVMRVRFIEZST00gdHN0IFdIRVJFIGkgPSA1OwpWQUNVVU0gdHN0OwpJTlNFUlQgSU5U TyB0c3QgU0VMRUNUIGklMTAsIHRvX3RzdmVjdG9yKCdzaW1wbGUnLCBzdWJzdHIobWQ1KGk6 OnRleHQpLCAxLCAxKSkgRlJPTSBnZW5lcmF0ZV9zZXJpZXMoMTQwMDEsMTUwMDApIGk7CgpE RUxFVEUgRlJPTSB0c3QgV0hFUkUgaSA9IDY7ClZBQ1VVTSB0c3Q7CklOU0VSVCBJTlRPIHRz dCBTRUxFQ1QgaSUxMCwgdG9fdHN2ZWN0b3IoJ3NpbXBsZScsIHN1YnN0cihtZDUoaTo6dGV4 dCksIDEsIDEpKSBGUk9NIGdlbmVyYXRlX3NlcmllcygxNTAwMSwxNjAwMCkgaTsKCkRFTEVU RSBGUk9NIHRzdCBXSEVSRSBpID0gNzsKVkFDVVVNIHRzdDsKSU5TRVJUIElOVE8gdHN0IFNF TEVDVCBpJTEwLCB0b190c3ZlY3Rvcignc2ltcGxlJywgc3Vic3RyKG1kNShpOjp0ZXh0KSwg MSwgMSkpIEZST00gZ2VuZXJhdGVfc2VyaWVzKDE2MDAxLDE3MDAwKSBpOwoKREVMRVRFIEZS T00gdHN0IFdIRVJFIGkgPSA4OwpWQUNVVU0gdHN0OwpJTlNFUlQgSU5UTyB0c3QgU0VMRUNU IGklMTAsIHRvX3RzdmVjdG9yKCdzaW1wbGUnLCBzdWJzdHIobWQ1KGk6OnRleHQpLCAxLCAx KSkgRlJPTSBnZW5lcmF0ZV9zZXJpZXMoMTcwMDEsMTgwMDApIGk7CgpERUxFVEUgRlJPTSB0 c3QgV0hFUkUgaSA9IDk7ClZBQ1VVTSB0c3Q7CklOU0VSVCBJTlRPIHRzdCBTRUxFQ1QgaSUx MCwgdG9fdHN2ZWN0b3IoJ3NpbXBsZScsIHN1YnN0cihtZDUoaTo6dGV4dCksIDEsIDEpKSBG Uk9NIGdlbmVyYXRlX3NlcmllcygxODAwMSwxOTAwMCkgaTsKCkRST1AgVEFCTEUgdHN0OwpE Uk9QIEVYVEVOU0lPTiBydW07Cg== --------------000004060508030804080906 Content-Type: application/x-shellscript; name="test_correctness.sh" Content-Transfer-Encoding: base64 Content-Disposition: attachment; filename="test_correctness.sh" IyEvYmluL2Jhc2gKCmVjaG8gUHJlcGFyaW5nLi4uCgppZiAhIFsgLWEgcG9zdGdyZXNxbCBd OyB0aGVuCiAgZ2l0IGNsb25lIGdpdDovL2dpdC5wb3N0Z3Jlc3FsLm9yZy9naXQvcG9zdGdy ZXNxbC5naXQ7CmZpCmNkIHBvc3RncmVzcWwKZ2l0IGNoZWNrb3V0IFJFTF8xMF8wCmNkIC4u CgppZiAhIFsgLWEgcnVtIF07IHRoZW4KICBnaXQgY2xvbmUgaHR0cHM6Ly9naXRodWIuY29t L3Bvc3RncmVzcHJvL3J1bQpmaQoKcm0gLXJmIHBvc3RncmVzcWxfY29ycmVjdG5lc3MKY3Ag LXIgcG9zdGdyZXNxbCBwb3N0Z3Jlc3FsX2NvcnJlY3RuZXNzCmNwIC1yIHJ1bSBwb3N0Z3Jl c3FsX2NvcnJlY3RuZXNzL2NvbnRyaWIKCmNkIHBvc3RncmVzcWxfY29ycmVjdG5lc3MKcGF0 Y2ggLXAxIDwgLi4vZ2VuZXJpY194bG9nX2RpZmZkZWx0YV92Mi5wYXRjaApjZCAuLgoKdGVz dF9wb3N0Z3Jlc3FsX3ZlcnNpb25zPSJwb3N0Z3Jlc3FsX2NvcnJlY3RuZXNzIgp0ZXN0X2Nv bnRyaWJzPSJydW0gYmxvb20iCgpwcmVmaXg9YHB3ZGAKCnBvcnQ9NTg0NQoKZm9yIHBvc3Rn cmVzcWwgaW4gJHRlc3RfcG9zdGdyZXNxbF92ZXJzaW9uczsgZG8KICBlY2hvIFRlc3Rpbmcg JHBvc3RncmVzcWwuLi4KICBybSAtcmYgZGJfJHBvc3RncmVzcWwKICBybSAtcmYgYmluXyRw b3N0Z3Jlc3FsCiAgcm0gLWYgbG9nXyR7cG9zdGdyZXNxbH0ubG9nCgogIGNkICRwb3N0Z3Jl c3FsCiAgLi9jb25maWd1cmUgLS1wcmVmaXg9JHByZWZpeC9iaW5fJHBvc3RncmVzcWwgLS1l bmFibGUtY2Fzc2VydCAtLWVuYWJsZS1kZWJ1ZyAtLWVuYWJsZS1ubHMgLS13aXRoLXBncG9y dD0kcG9ydCBDRkxBR1M9Ii1EV0FMX0RFQlVHIiA+IC9kZXYvbnVsbAogIG1ha2UgLWo0ID4g L2Rldi9udWxsCiAgbWFrZSBpbnN0YWxsID4gL2Rldi9udWxsCiAgZm9yIGNvbnRyaWIgaW4g JHRlc3RfY29udHJpYnM7IGRvCiAgICBjZCBjb250cmliLyRjb250cmliCiAgICBtYWtlIC1q NCA+IC9kZXYvbnVsbAogICAgbWFrZSBpbnN0YWxsID4gL2Rldi9udWxsCiAgICBjZCAuLi8u LjsKICBkb25lCiAgY2QgLi4KCiAgYmluXyRwb3N0Z3Jlc3FsL2Jpbi9pbml0ZGIgLUQgZGJf JHBvc3RncmVzcWwgPiAvZGV2L251bGwgMj4gL2Rldi9udWxsCiAgZWNobyAid2FsX2RlYnVn ID0gb24iID4+IGRiXyRwb3N0Z3Jlc3FsL3Bvc3RncmVzcWwuY29uZgoKICBiaW5fJHBvc3Rn cmVzcWwvYmluL3BnX2N0bCAtRCBkYl8kcG9zdGdyZXNxbCAtbCBsb2dfJHtwb3N0Z3Jlc3Fs fS5sb2cgc3RhcnQKICB3aGlsZSAhKGJpbl8kcG9zdGdyZXNxbC9iaW4vcHNxbCAtLXBvcnQg JHBvcnQgLWQgcG9zdGdyZXMgLWMgIlNFTEVDVCAxOyIgPiAvZGV2L251bGwgMj4gL2Rldi9u dWxsKTsgZG8KICAgIHNsZWVwIDE7CiAgZG9uZQoKICAjY2QgJHBvc3RncmVzcWwKICAjUEdQ T1JUPSRwb3J0IHRpbWUgbWFrZSBpbnN0YWxsY2hlY2sKICAjY2QgLi4KCiAgZm9yIGNvbnRy aWIgaW4gJHRlc3RfY29udHJpYnM7IGRvCiAgICBjZCAkcG9zdGdyZXNxbC9jb250cmliLyRj b250cmliCiAgICBQR1BPUlQ9JHBvcnQgdGltZSBtYWtlIGluc3RhbGxjaGVjawogICAgY2Qg Li4vLi4vLi47CiAgZG9uZQoKICBiaW5fJHBvc3RncmVzcWwvYmluL3BnX2N0bCAtRCBkYl8k cG9zdGdyZXNxbCAtbCBsb2dfJHtwb3N0Z3Jlc3FsfS5sb2cgc3RvcApkb25lCg== --------------000004060508030804080906 Content-Type: application/x-shellscript; name="total_test.sh" Content-Transfer-Encoding: base64 Content-Disposition: attachment; filename="total_test.sh" IyEvYmluL2Jhc2gKCmVjaG8gUHJlcGFyaW5nLi4uCgppZiAhIFsgLWEgcG9zdGdyZXNxbCBd OyB0aGVuCiAgZ2l0IGNsb25lIGdpdDovL2dpdC5wb3N0Z3Jlc3FsLm9yZy9naXQvcG9zdGdy ZXNxbC5naXQ7CmZpCmNkIHBvc3RncmVzcWwKZ2l0IGNoZWNrb3V0IFJFTF8xMF8wCmNkIC4u CgppZiAhIFsgLWEgdF9wZ2xpc3QtaW5zZXJ0cy5zcWwgXTsgdGhlbgogIHdnZXQgaHR0cDov L3d3dy5zYWkubXN1LnN1L35tZWdlcmEvcG9zdGdyZXMvZmlsZXMvdF9wZ2xpc3QtaW5zZXJ0 cy5zcWwKICBoZWFkIC1uIC03IHRfcGdsaXN0LWluc2VydHMuc3FsID4gdG1wCiAgZWNobyAi IiJDUkVBVEUgRVhURU5TSU9OIHJ1bTsKCkNSRUFURSBJTkRFWCBwZ2xpc3RfZnRzX3RzX29y ZGVyX3J1bV9pZHggT04gdF9wZ2xpc3QgVVNJTkcgcnVtKGZ0cyBydW1fdHN2ZWN0b3JfdGlt ZXN0YW1wX29wcywgc2VudCkKV0lUSCAoYXR0YWNoID0gJ3NlbnQnLCB0byA9ICdmdHMnLCBv cmRlcl9ieV9hdHRhY2g9J3QnKTsKCi0tCi0tIFBvc3RncmVTUUwgZGF0YWJhc2UgZHVtcCBj b21wbGV0ZQotLSIiIiA+PiB0bXAKICBtdiB0bXAgdF9wZ2xpc3QtaW5zZXJ0cy5zcWw7CmZp CgppZiAhIFsgLWEgdF9wZ2xpc3QtaW5zZXJ0cy5kdW1wIF07IHRoZW4KICB3Z2V0IGh0dHA6 Ly93d3cuc2FpLm1zdS5zdS9+bWVnZXJhL3Bvc3RncmVzL2ZpbGVzL3RfcGdsaXN0LWluc2Vy dHMuZHVtcC5negogIGd6aXAgLWQgdF9wZ2xpc3QtaW5zZXJ0cy5kdW1wLmd6OwpmaQoKaWYg ISBbIC1hIHJ1bSBdOyB0aGVuCiAgZ2l0IGNsb25lIGh0dHBzOi8vZ2l0aHViLmNvbS9wb3N0 Z3Jlc3Byby9ydW0KZmkKCnJtIC1yZiBwb3N0Z3Jlc3FsX29yaWdpbmFsCnJtIC1yZiBwb3N0 Z3Jlc3FsX29wdGltaXplZApjcCAtciBwb3N0Z3Jlc3FsIHBvc3RncmVzcWxfb3JpZ2luYWwK Y3AgLXIgcnVtIHBvc3RncmVzcWxfb3JpZ2luYWwvY29udHJpYgoKY3AgLXIgcG9zdGdyZXNx bF9vcmlnaW5hbCBwb3N0Z3Jlc3FsX29wdGltaXplZApjZCBwb3N0Z3Jlc3FsX29wdGltaXpl ZApwYXRjaCAtcDEgPCAuLi9nZW5lcmljX3hsb2dfZGlmZmRlbHRhX3YyLnBhdGNoCmNkIC4u Cgp0ZXN0X3Bvc3RncmVzcWxfdmVyc2lvbnM9InBvc3RncmVzcWxfb3JpZ2luYWwgcG9zdGdy ZXNxbF9vcHRpbWl6ZWQiCnRlc3RfY29udHJpYnM9InJ1bSBibG9vbSIKCnByZWZpeD1gcHdk YAoKcG9ydD01ODQ1Cgpmb3IgcG9zdGdyZXNxbCBpbiAkdGVzdF9wb3N0Z3Jlc3FsX3ZlcnNp b25zOyBkbwogIGVjaG8gVGVzdGluZyAkcG9zdGdyZXNxbC4uLgogIHJtIC1yZiBkYl8kcG9z dGdyZXNxbAogIHJtIC1yZiBiaW5fJHBvc3RncmVzcWwKICBybSAtZiBsb2dfJHtwb3N0Z3Jl c3FsfS5sb2cKCiAgY2QgJHBvc3RncmVzcWwKICAuL2NvbmZpZ3VyZSAtLXByZWZpeD0kcHJl Zml4L2Jpbl8kcG9zdGdyZXNxbCAtLWVuYWJsZS1ubHMgLS13aXRoLXBncG9ydD0kcG9ydCA+ IC9kZXYvbnVsbAogIG1ha2UgLWo0ID4gL2Rldi9udWxsCiAgbWFrZSBpbnN0YWxsID4gL2Rl di9udWxsCiAgZm9yIGNvbnRyaWIgaW4gJHRlc3RfY29udHJpYnM7IGRvCiAgICBjZCBjb250 cmliLyRjb250cmliCiAgICBtYWtlIC1qNCA+IC9kZXYvbnVsbAogICAgbWFrZSBpbnN0YWxs ID4gL2Rldi9udWxsCiAgICBjZCAuLi8uLjsKICBkb25lCiAgY2QgLi4KCiAgYmluXyRwb3N0 Z3Jlc3FsL2Jpbi9pbml0ZGIgLUQgZGJfJHBvc3RncmVzcWwgPiAvZGV2L251bGwgMj4gL2Rl di9udWxsCiAgY3AgcG9zdGdyZXNxbC5jb25mIGRiXyRwb3N0Z3Jlc3FsLwogIGJpbl8kcG9z dGdyZXNxbC9iaW4vcGdfY3RsIC1EIGRiXyRwb3N0Z3Jlc3FsIC1sIGxvZ18ke3Bvc3RncmVz cWx9LmxvZyBzdGFydAogIHdoaWxlICEoYmluXyRwb3N0Z3Jlc3FsL2Jpbi9wc3FsIC0tcG9y dCAkcG9ydCAtZCBwb3N0Z3JlcyAtYyAiU0VMRUNUIDE7IiA+IC9kZXYvbnVsbCAyPiAvZGV2 L251bGwpOyBkbwogICAgc2xlZXAgMTsKICBkb25lCgogIGVjaG8gIiIiQ1JFQVRFIEZVTkNU SU9OIHBnX2NhdGFsb2cucGdfY3VycmVudF94bG9nX2xvY2F0aW9uKCkgUkVUVVJOUyBwZ19s c24gQVMgXCRcJApCRUdJTgogICAgUkVUVVJOIHBnX2N1cnJlbnRfd2FsX2xzbigpOwpFTkQ7 ClwkXCQgTEFOR1VBR0UgcGxwZ3NxbDsiIiIgfCBiaW5fJHBvc3RncmVzcWwvYmluL3BzcWwg LS1wb3J0ICRwb3J0IC1kIHBvc3RncmVzCgogIGZvciBjb250cmliIGluICR0ZXN0X2NvbnRy aWJzOyBkbwogICAgc3RhcnQ9YGJpbl8kcG9zdGdyZXNxbC9iaW4vcHNxbCAtLXBvcnQgJHBv cnQgLWQgcG9zdGdyZXMgLWMgIkNPUFkgKFNFTEVDVCBwZ19jdXJyZW50X3hsb2dfbG9jYXRp b24oKSkgVE8gc3Rkb3V0OyIgfCB0ciAvIHhgCiAgICBjZCAkcG9zdGdyZXNxbC9jb250cmli LyRjb250cmliCiAgICBQR1BPUlQ9JHBvcnQgdGltZSBtYWtlIGluc3RhbGxjaGVjayA+IC9k ZXYvbnVsbAogICAgY2QgLi4vLi4vLi4KICAgIGZpbmlzaD1gYmluXyRwb3N0Z3Jlc3FsL2Jp bi9wc3FsIC0tcG9ydCAkcG9ydCAtZCBwb3N0Z3JlcyAtYyAiQ09QWSAoU0VMRUNUIHBnX2N1 cnJlbnRfeGxvZ19sb2NhdGlvbigpKSBUTyBzdGRvdXQ7IiB8IHRyIC8geGAKICAgIGVjaG8g SW5zdGFsbENoZWNrIG9mICRjb250cmliIFdBTCBzaXplIGlzICQoKCRmaW5pc2ggLSAkc3Rh cnQpKSBieXRlczsKICBkb25lCgogIGJpbl8kcG9zdGdyZXNxbC9iaW4vY3JlYXRlZGIgLS1w b3J0ICRwb3J0IHRlc3QwMAogIHN0YXJ0PWBiaW5fJHBvc3RncmVzcWwvYmluL3BzcWwgLS1w b3J0ICRwb3J0IC1kIHBvc3RncmVzIC1jICJDT1BZIChTRUxFQ1QgcGdfY3VycmVudF94bG9n X2xvY2F0aW9uKCkpIFRPIHN0ZG91dDsiIHwgdHIgLyB4YAogIHN0YXJ0X2dsb2JhbD0kc3Rh cnQKICBjYXQgdGVzdDAwLnNxbCB8IHdoaWxlIHJlYWQgbGluZTsgZG8KICAgIGlmIHRlc3Qg LXogIiRsaW5lIjsgdGhlbgogICAgICBjb250aW51ZTsKICAgIGZpCiAgICBiaW5fJHBvc3Rn cmVzcWwvYmluL3BzcWwgLS1wb3J0ICRwb3J0IC1kIHRlc3QwMCAtYyAiJGxpbmUiID4gL2Rl di9udWxsCiAgICBmaW5pc2g9YGJpbl8kcG9zdGdyZXNxbC9iaW4vcHNxbCAtLXBvcnQgJHBv cnQgLWQgcG9zdGdyZXMgLWMgIkNPUFkgKFNFTEVDVCBwZ19jdXJyZW50X3hsb2dfbG9jYXRp b24oKSkgVE8gc3Rkb3V0OyIgfCB0ciAvIHhgCiAgICBlY2hvIFJ1bSBcIiRsaW5lXCIgV0FM IHNpemUgaXMgJCgoJGZpbmlzaCAtICRzdGFydCkpIGJ5dGVzCiAgICBzdGFydD0kZmluaXNo CiAgZG9uZSAKICBmaW5pc2hfZ2xvYmFsPWBiaW5fJHBvc3RncmVzcWwvYmluL3BzcWwgLS1w b3J0ICRwb3J0IC1kIHBvc3RncmVzIC1jICJDT1BZIChTRUxFQ1QgcGdfY3VycmVudF94bG9n X2xvY2F0aW9uKCkpIFRPIHN0ZG91dDsiIHwgdHIgLyB4YAogIHRpbWUgYmluXyRwb3N0Z3Jl c3FsL2Jpbi9wc3FsIC0tcG9ydCAkcG9ydCAtZCB0ZXN0MDAgPCB0ZXN0MDAuc3FsID4gL2Rl di9udWxsCiAgZWNobyBSdW0gdGVzdDAwLnNxbCBXQUwgc2l6ZSBpcyAkKCgkZmluaXNoX2ds b2JhbCAtICRzdGFydF9nbG9iYWwpKSBieXRlcwoKICBiaW5fJHBvc3RncmVzcWwvYmluL2Ny ZWF0ZWRiIC0tcG9ydCAkcG9ydCB0ZXN0MDEKICBzdGFydD1gYmluXyRwb3N0Z3Jlc3FsL2Jp bi9wc3FsIC0tcG9ydCAkcG9ydCAtZCBwb3N0Z3JlcyAtYyAiQ09QWSAoU0VMRUNUIHBnX2N1 cnJlbnRfeGxvZ19sb2NhdGlvbigpKSBUTyBzdGRvdXQ7IiB8IHRyIC8geGAKICBzdGFydF9n bG9iYWw9JHN0YXJ0CiAgY2F0IHRlc3QwMS5zcWwgfCB3aGlsZSByZWFkIGxpbmU7IGRvCiAg ICBpZiB0ZXN0IC16ICIkbGluZSI7IHRoZW4KICAgICAgY29udGludWU7CiAgICBmaQogICAg YmluXyRwb3N0Z3Jlc3FsL2Jpbi9wc3FsIC0tcG9ydCAkcG9ydCAtZCB0ZXN0MDEgLWMgIiRs aW5lIiA+IC9kZXYvbnVsbAogICAgZmluaXNoPWBiaW5fJHBvc3RncmVzcWwvYmluL3BzcWwg LS1wb3J0ICRwb3J0IC1kIHBvc3RncmVzIC1jICJDT1BZIChTRUxFQ1QgcGdfY3VycmVudF94 bG9nX2xvY2F0aW9uKCkpIFRPIHN0ZG91dDsiIHwgdHIgLyB4YAogICAgZWNobyBCbG9vbSBc IiRsaW5lXCIgV0FMIHNpemUgaXMgJCgoJGZpbmlzaCAtICRzdGFydCkpIGJ5dGVzCiAgICBz dGFydD0kZmluaXNoCiAgZG9uZSAKICBmaW5pc2hfZ2xvYmFsPWBiaW5fJHBvc3RncmVzcWwv YmluL3BzcWwgLS1wb3J0ICRwb3J0IC1kIHBvc3RncmVzIC1jICJDT1BZIChTRUxFQ1QgcGdf Y3VycmVudF94bG9nX2xvY2F0aW9uKCkpIFRPIHN0ZG91dDsiIHwgdHIgLyB4YAogIHRpbWUg YmluXyRwb3N0Z3Jlc3FsL2Jpbi9wc3FsIC0tcG9ydCAkcG9ydCAtZCB0ZXN0MDEgPCB0ZXN0 MDEuc3FsID4gL2Rldi9udWxsCiAgZWNobyBCbG9vbSB0ZXN0MDEuc3FsIFdBTCBzaXplIGlz ICQoKCRmaW5pc2hfZ2xvYmFsIC0gJHN0YXJ0X2dsb2JhbCkpIGJ5dGVzCgogIGJpbl8kcG9z dGdyZXNxbC9iaW4vY3JlYXRlZGIgLS1wb3J0ICRwb3J0IHRlc3RfcGdsaXN0cwogIHN0YXJ0 PWBiaW5fJHBvc3RncmVzcWwvYmluL3BzcWwgLS1wb3J0ICRwb3J0IC1kIHBvc3RncmVzIC1j ICJDT1BZIChTRUxFQ1QgcGdfY3VycmVudF94bG9nX2xvY2F0aW9uKCkpIFRPIHN0ZG91dDsi YAogIGJpbl8kcG9zdGdyZXNxbC9iaW4vcHNxbCAtLXBvcnQgJHBvcnQgLWQgdGVzdF9wZ2xp c3RzIDwgdF9wZ2xpc3QtaW5zZXJ0cy5zcWwgPiAvZGV2L251bGwKICB0aW1lIGJpbl8kcG9z dGdyZXNxbC9iaW4vcHNxbCAtLXBvcnQgJHBvcnQgLWQgdGVzdF9wZ2xpc3RzIDwgdF9wZ2xp c3QtaW5zZXJ0cy5kdW1wID4gL2Rldi9udWxsCiAgZmluaXNoX2dsb2JhbD1gYmluXyRwb3N0 Z3Jlc3FsL2Jpbi9wc3FsIC0tcG9ydCAkcG9ydCAtZCBwb3N0Z3JlcyAtYyAiQ09QWSAoU0VM RUNUIHBnX2N1cnJlbnRfeGxvZ19sb2NhdGlvbigpKSBUTyBzdGRvdXQ7ImAKICBlY2hvIFBn TGlzdHMgV0FMIHN0YXJ0IGlzICRzdGFydCBhbmQgZmluaXNoIGlzICRmaW5pc2hfZ2xvYmFs CgogIGJpbl8kcG9zdGdyZXNxbC9iaW4vcGdfY3RsIC1EIGRiXyRwb3N0Z3Jlc3FsIC1sIGxv Z18ke3Bvc3RncmVzcWx9LmxvZyBzdG9wCmRvbmUK --------------000004060508030804080906--