From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-pl1-f177.google.com (mail-pl1-f177.google.com [209.85.214.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 3746B225409 for ; Fri, 11 Jul 2025 13:19:59 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.214.177 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1752240003; cv=none; b=Te5zqXlSQX9pP4mwfnNinxnhHTd1tgXbxs5p20hhMhypC4lbY0DWiQBjNANOJ2CivMuBCNeaL/Xm/SUQEemDt3EijtdiDJrhg88i412wD2Vn6f9ZiVG6XO+vCdtotxsNA+PK60zO3MFUhHYG0Vvxp6O4XI/PR0S/xtcCByJhAIg= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1752240003; c=relaxed/simple; bh=HQrEf5cxYsPuilWdbZhEN6kTQHr6QXxvfSFQxNr1Prw=; h=From:To:Cc:Subject:Date:Message-ID:MIME-Version:Content-Type; b=PaDGhX26I5Bhahn0N9RtaSt6SPi4J4kh8cGlsbnebt8EnVV46PeLS1+3SkiXaUla8JM0TKJI3QWO/8R3gKEzxmH37zH8WrFXLCZxmkI4eCJnUQIJYWv/16exhAEEg5WDChiET1onvrhOFJuE+zSBup23QSPnzznGr0M0FkgdNL8= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=rivosinc.com; spf=pass smtp.mailfrom=rivosinc.com; dkim=pass (2048-bit key) header.d=rivosinc-com.20230601.gappssmtp.com header.i=@rivosinc-com.20230601.gappssmtp.com header.b=x2YCXnem; arc=none smtp.client-ip=209.85.214.177 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=rivosinc.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=rivosinc.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=rivosinc-com.20230601.gappssmtp.com header.i=@rivosinc-com.20230601.gappssmtp.com header.b="x2YCXnem" Received: by mail-pl1-f177.google.com with SMTP id d9443c01a7336-235f9e87f78so20701585ad.2 for ; Fri, 11 Jul 2025 06:19:59 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=rivosinc-com.20230601.gappssmtp.com; s=20230601; t=1752239999; x=1752844799; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:from:to:cc:subject:date:message-id:reply-to; bh=6//hd5/2Hzqt0npYzE6gaxMoRCrJFz+kATaycN9jSlk=; b=x2YCXnemXgxgnJhZBtXUsoABa0L4EwlND3wP0S0B43ZQYQ1KZ5N7ymQ9pkyPLjlW4U Cpy0/A7VXAH7sZN5aW21sFidCRC5vbYNYL4MXpq04Bii7L7e764jexg3ddX8yxPc0pXC a1esYYxECCOVeZLbOiNj2OkYBTLdocGS4C1YcRIZ0TWKo16xrT3hKh2TypRKw3dJ02xa nBbjyMWOvKjqjvFDZ6ghzFZ/yHEJv/hUJmfZFnU1FQLk248LmTiS2ig0zjeiBaLpMAbe B9dqjF0IbmjYH7dsNnlGDuQjxUF7v8N9fDVZzH0j5geL2X1DeFMKK2vyqS8CgRGYuFlG /KuQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1752239999; x=1752844799; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=6//hd5/2Hzqt0npYzE6gaxMoRCrJFz+kATaycN9jSlk=; b=Z3VNRtjfUSYXQgN4udSDMV4NAs7ssGpsbqRBrHd0Gw7wsCzbw6yO7LbVQzkS9310AK zxWityY8XfluIlPwAUSkcQ/ByfEYnULzm1gqR6D6zwL6+BpMjXfoBaDium3QJtEioK0d OqvTTMNtT0ppB/9v2Uc2h8y4BcKW/r/YNlFmen0iL5rdNNCzDFthP5orf7ytef7lhAu7 DbZ4wUCYsm/DosHWJZ6+EnR2Qpx8+1q3y/aj6UjyLYsPsUL4d8BjjgTcGlEitAW4YGtt R77Gj/IFVZ8HBk3iI/DAfhw9jPjS6ZRoWT8tknXH2EJkNh6OQxiqg2l8sMeHv5GRSZE4 gI9A== X-Forwarded-Encrypted: i=1; AJvYcCWtxuqOBk+2+hUaFMDwR6g0yRu9uUp+vFbjcgwGbOJjMw2mhZ8dCfT17ifaw8j/VmeCUiA1e2ceM77X5cp9mG8=@vger.kernel.org X-Gm-Message-State: AOJu0YxS+yn7ZeybflZcMgTp5oDeof/onTm+FK1C/rBk8t8cXC8TRUQa C3PPlwWoy2UH6c0MpEphnSogfD5KSbiAyVu6vGu+r9Ls9Q+FNyNM7SiF6I4jSFmfE4A= X-Gm-Gg: ASbGnct2Lud2JpGZ8PPeuoL+VY8QIbIGmY/Tv6Bfls0nlTAXG5tUnW6ESxVpcfw+Gss NvbxAYES/WjlyF0BlEe4zIpGCZ/oy7qanuQt5xhdvVxwcT2YaCUx05v/3DwSQLQlQmGxC0DO9rp 4dToVsve0Gh4hZWto4gq/Gj0KcMI09aaoDIK37zAzMt+R9Ij0/9lSHZ4+77goYnL/Jk1dzh26Ob sf4gd4bXFS5Zm98BdbjDrXF1wUZeHWaQ/tAFBvboOvFvcNyO2OLEJ1fw0d+KLg8nPx6bjlWQXb/ 7QbMWLpCoQ/AjpJJyZ8dG79L6yZtoFOGUeUn7e6OMlTuwbmWYL5aQ9tDRYtB1v5imWniEM4CXyx anv9uRl//c70PyA== X-Google-Smtp-Source: AGHT+IHxrRQsPtuvfbXx6QfQiO/WeYYzyL8cHrvNDnYrHbvIxocomxFbz25k5rB1zAsStkf+RMEFpw== X-Received: by 2002:a17:903:a4f:b0:235:f70:fd39 with SMTP id d9443c01a7336-23dede2e17cmr37632915ad.10.1752239998668; Fri, 11 Jul 2025 06:19:58 -0700 (PDT) Received: from cleger.eu.int ([2001:41d0:420:f300::]) by smtp.gmail.com with ESMTPSA id 41be03b00d2f7-b3bbe52e261sm5158486a12.2.2025.07.11.06.19.52 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 11 Jul 2025 06:19:57 -0700 (PDT) From: =?UTF-8?q?Cl=C3=A9ment=20L=C3=A9ger?= To: linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org, linux-riscv@lists.infradead.org Cc: =?UTF-8?q?Cl=C3=A9ment=20L=C3=A9ger?= , Palmer Dabbelt , Paul Walmsley , Shuah Khan , Alexandre Ghiti , Andreas Schwab Subject: [PATCH v5] selftests: riscv: add misaligned access testing Date: Fri, 11 Jul 2025 13:19:24 +0000 Message-ID: <20250711131925.112485-1-cleger@rivosinc.com> X-Mailer: git-send-email 2.43.0 Precedence: bulk X-Mailing-List: linux-kselftest@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This selftest tests all the currently emulated instructions (except for the RV32 compressed ones which are left as a future exercise for a RV32 user). For the FPU instructions, all the FPU registers are tested. Signed-off-by: Clément Léger --- This commits needs [1] for the test to be passed or it will fail due to missing sign extension. Note: This test can be executed using an SBI that support FWFT or that delegates misaligned traps by default. If using QEMU, you will need the patches mentioned at [2] so that misaligned accesses will generate a trap. Note: This commit was part of a series [3] that was partially merged. Note: the remaining checkpatch errors are not applicable to this tests which is a userspace one and does not use the kernel headers. Macros with complex values can not be enclosed in do while loop since they are generating functions. Link: https://lore.kernel.org/linux-riscv/mvmikk0goil.fsf@suse.de/ [1] Link: https://lore.kernel.org/all/20241211211933.198792-1-fkonrad@amd.com/ [2] Link: https://lore.kernel.org/linux-riscv/20250422162324.956065-1-cleger@rivosinc.com/ [3] V5: - Sign extend LWU return value - Added sign extensions tests - Tests multiples values for GP load/store V4: - Fixed a typo in test name s/load/store V3: - Fixed a segfault and a sign extension error found when compiling with -O, x != 0 (Alex) - Use inline assembly to generate the sigbus and avoid GCC optimizations V2: - Fix commit description - Fix a few errors reported by checkpatch.pl --- tools/testing/selftests/riscv/Makefile | 2 +- .../selftests/riscv/misaligned/.gitignore | 1 + .../selftests/riscv/misaligned/Makefile | 12 + .../selftests/riscv/misaligned/common.S | 33 ++ .../testing/selftests/riscv/misaligned/fpu.S | 180 +++++++++++ tools/testing/selftests/riscv/misaligned/gp.S | 113 +++++++ .../selftests/riscv/misaligned/misaligned.c | 288 ++++++++++++++++++ 7 files changed, 628 insertions(+), 1 deletion(-) create mode 100644 tools/testing/selftests/riscv/misaligned/.gitignore create mode 100644 tools/testing/selftests/riscv/misaligned/Makefile create mode 100644 tools/testing/selftests/riscv/misaligned/common.S create mode 100644 tools/testing/selftests/riscv/misaligned/fpu.S create mode 100644 tools/testing/selftests/riscv/misaligned/gp.S create mode 100644 tools/testing/selftests/riscv/misaligned/misaligned.c diff --git a/tools/testing/selftests/riscv/Makefile b/tools/testing/selftests/riscv/Makefile index 099b8c1f46f8..95a98ceeb3b3 100644 --- a/tools/testing/selftests/riscv/Makefile +++ b/tools/testing/selftests/riscv/Makefile @@ -5,7 +5,7 @@ ARCH ?= $(shell uname -m 2>/dev/null || echo not) ifneq (,$(filter $(ARCH),riscv)) -RISCV_SUBTARGETS ?= abi hwprobe mm sigreturn vector +RISCV_SUBTARGETS ?= abi hwprobe mm sigreturn vector misaligned else RISCV_SUBTARGETS := endif diff --git a/tools/testing/selftests/riscv/misaligned/.gitignore b/tools/testing/selftests/riscv/misaligned/.gitignore new file mode 100644 index 000000000000..5eff15a1f981 --- /dev/null +++ b/tools/testing/selftests/riscv/misaligned/.gitignore @@ -0,0 +1 @@ +misaligned diff --git a/tools/testing/selftests/riscv/misaligned/Makefile b/tools/testing/selftests/riscv/misaligned/Makefile new file mode 100644 index 000000000000..1aa40110c50d --- /dev/null +++ b/tools/testing/selftests/riscv/misaligned/Makefile @@ -0,0 +1,12 @@ +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2021 ARM Limited +# Originally tools/testing/arm64/abi/Makefile + +CFLAGS += -I$(top_srcdir)/tools/include + +TEST_GEN_PROGS := misaligned + +include ../../lib.mk + +$(OUTPUT)/misaligned: misaligned.c fpu.S gp.S + $(CC) -g3 -static -o$@ -march=rv64imafdc $(CFLAGS) $(LDFLAGS) $^ diff --git a/tools/testing/selftests/riscv/misaligned/common.S b/tools/testing/selftests/riscv/misaligned/common.S new file mode 100644 index 000000000000..8fa00035bd5d --- /dev/null +++ b/tools/testing/selftests/riscv/misaligned/common.S @@ -0,0 +1,33 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2025 Rivos Inc. + * + * Authors: + * Clément Léger + */ + +.macro lb_sb temp, offset, src, dst + lb \temp, \offset(\src) + sb \temp, \offset(\dst) +.endm + +.macro copy_long_to temp, src, dst + lb_sb \temp, 0, \src, \dst, + lb_sb \temp, 1, \src, \dst, + lb_sb \temp, 2, \src, \dst, + lb_sb \temp, 3, \src, \dst, + lb_sb \temp, 4, \src, \dst, + lb_sb \temp, 5, \src, \dst, + lb_sb \temp, 6, \src, \dst, + lb_sb \temp, 7, \src, \dst, +.endm + +.macro sp_stack_prologue offset + addi sp, sp, -8 + sub sp, sp, \offset +.endm + +.macro sp_stack_epilogue offset + add sp, sp, \offset + addi sp, sp, 8 +.endm diff --git a/tools/testing/selftests/riscv/misaligned/fpu.S b/tools/testing/selftests/riscv/misaligned/fpu.S new file mode 100644 index 000000000000..a7ad4430a424 --- /dev/null +++ b/tools/testing/selftests/riscv/misaligned/fpu.S @@ -0,0 +1,180 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2025 Rivos Inc. + * + * Authors: + * Clément Léger + */ + +#include "common.S" + +#define CASE_ALIGN 4 + +.macro fpu_load_inst fpreg, inst, precision, load_reg +.align CASE_ALIGN + \inst \fpreg, 0(\load_reg) + fmv.\precision fa0, \fpreg + j 2f +.endm + +#define flw(__fpreg) fpu_load_inst __fpreg, flw, s, a4 +#define fld(__fpreg) fpu_load_inst __fpreg, fld, d, a4 +#define c_flw(__fpreg) fpu_load_inst __fpreg, c.flw, s, a4 +#define c_fld(__fpreg) fpu_load_inst __fpreg, c.fld, d, a4 +#define c_fldsp(__fpreg) fpu_load_inst __fpreg, c.fldsp, d, sp + +.macro fpu_store_inst fpreg, inst, precision, store_reg +.align CASE_ALIGN + fmv.\precision \fpreg, fa0 + \inst \fpreg, 0(\store_reg) + j 2f +.endm + +#define fsw(__fpreg) fpu_store_inst __fpreg, fsw, s, a4 +#define fsd(__fpreg) fpu_store_inst __fpreg, fsd, d, a4 +#define c_fsw(__fpreg) fpu_store_inst __fpreg, c.fsw, s, a4 +#define c_fsd(__fpreg) fpu_store_inst __fpreg, c.fsd, d, a4 +#define c_fsdsp(__fpreg) fpu_store_inst __fpreg, c.fsdsp, d, sp + +.macro fp_test_prologue + move a4, a1 + /* + * Compute jump offset to store the correct FP register since we don't + * have indirect FP register access (or at least we don't use this + * extension so that works on all archs) + */ + sll t0, a0, CASE_ALIGN + la t2, 1f + add t0, t0, t2 + jr t0 +.align CASE_ALIGN +1: +.endm + +.macro fp_test_prologue_compressed + /* FP registers for compressed instructions starts from 8 to 16 */ + addi a0, a0, -8 + fp_test_prologue +.endm + +#define fp_test_body_compressed(__inst_func) \ + __inst_func(f8); \ + __inst_func(f9); \ + __inst_func(f10); \ + __inst_func(f11); \ + __inst_func(f12); \ + __inst_func(f13); \ + __inst_func(f14); \ + __inst_func(f15); \ +2: + +#define fp_test_body(__inst_func) \ + __inst_func(f0); \ + __inst_func(f1); \ + __inst_func(f2); \ + __inst_func(f3); \ + __inst_func(f4); \ + __inst_func(f5); \ + __inst_func(f6); \ + __inst_func(f7); \ + __inst_func(f8); \ + __inst_func(f9); \ + __inst_func(f10); \ + __inst_func(f11); \ + __inst_func(f12); \ + __inst_func(f13); \ + __inst_func(f14); \ + __inst_func(f15); \ + __inst_func(f16); \ + __inst_func(f17); \ + __inst_func(f18); \ + __inst_func(f19); \ + __inst_func(f20); \ + __inst_func(f21); \ + __inst_func(f22); \ + __inst_func(f23); \ + __inst_func(f24); \ + __inst_func(f25); \ + __inst_func(f26); \ + __inst_func(f27); \ + __inst_func(f28); \ + __inst_func(f29); \ + __inst_func(f30); \ + __inst_func(f31); \ +2: +.text + +#define __gen_test_inst(__inst, __suffix) \ +.global test_ ## __inst; \ +test_ ## __inst:; \ + fp_test_prologue ## __suffix; \ + fp_test_body ## __suffix(__inst); \ + ret + +#define gen_test_inst_compressed(__inst) \ + .option arch,+c; \ + __gen_test_inst(c_ ## __inst, _compressed) + +#define gen_test_inst(__inst) \ + .balign 16; \ + .option push; \ + .option arch,-c; \ + __gen_test_inst(__inst, ); \ + .option pop + +.macro fp_test_prologue_load_compressed_sp + copy_long_to t0, a1, sp +.endm + +.macro fp_test_epilogue_load_compressed_sp +.endm + +.macro fp_test_prologue_store_compressed_sp +.endm + +.macro fp_test_epilogue_store_compressed_sp + copy_long_to t0, sp, a1 +.endm + +#define gen_inst_compressed_sp(__inst, __type) \ + .global test_c_ ## __inst ## sp; \ + test_c_ ## __inst ## sp:; \ + sp_stack_prologue a2; \ + fp_test_prologue_## __type ## _compressed_sp; \ + fp_test_prologue_compressed; \ + fp_test_body_compressed(c_ ## __inst ## sp); \ + fp_test_epilogue_## __type ## _compressed_sp; \ + sp_stack_epilogue a2; \ + ret + +#define gen_test_load_compressed_sp(__inst) gen_inst_compressed_sp(__inst, load) +#define gen_test_store_compressed_sp(__inst) gen_inst_compressed_sp(__inst, store) + +/* + * float_fsw_reg - Set a FP register from a register containing the value + * a0 = FP register index to be set + * a1 = addr where to store register value + * a2 = address offset + * a3 = value to be store + */ +gen_test_inst(fsw) + +/* + * float_flw_reg - Get a FP register value and return it + * a0 = FP register index to be retrieved + * a1 = addr to load register from + * a2 = address offset + */ +gen_test_inst(flw) + +gen_test_inst(fsd) +#ifdef __riscv_compressed +gen_test_inst_compressed(fsd) +gen_test_store_compressed_sp(fsd) +#endif + +gen_test_inst(fld) +#ifdef __riscv_compressed +gen_test_inst_compressed(fld) +gen_test_load_compressed_sp(fld) +#endif diff --git a/tools/testing/selftests/riscv/misaligned/gp.S b/tools/testing/selftests/riscv/misaligned/gp.S new file mode 100644 index 000000000000..5abec5ccc828 --- /dev/null +++ b/tools/testing/selftests/riscv/misaligned/gp.S @@ -0,0 +1,113 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2025 Rivos Inc. + * + * Authors: + * Clément Léger + */ + +#include "common.S" + +.text + +.macro __gen_test_inst inst, src_reg + \inst a2, 0(\src_reg) + move a0, a2 +.endm + +.macro gen_func_header func_name, rvc + .option arch,\rvc + .global test_\func_name + test_\func_name: +.endm + +.macro gen_test_inst inst + .option push + gen_func_header \inst, -c + __gen_test_inst \inst, a0 + .option pop + ret +.endm + +.macro gen_test_lwu + .option push + gen_func_header lwu, -c + __gen_test_inst lwu, a0 + .option pop + # RISC-V ABI states that C expect a sign extended 32 bits integer + sext.w a0, a0 + ret +.endm + +.macro __gen_test_inst_c name, src_reg + .option push + gen_func_header c_\name, +c + __gen_test_inst c.\name, \src_reg + .option pop + ret +.endm + +.macro gen_test_inst_c name + __gen_test_inst_c \name, a0 +.endm + + +.macro gen_test_inst_c_ldsp + .option push + gen_func_header c_ldsp, +c + sp_stack_prologue a1 + copy_long_to t0, a0, sp + c.ldsp a0, 0(sp) + sp_stack_epilogue a1 + .option pop + ret +.endm + +.macro lb_sp_sb_a0 reg, offset + lb_sb \reg, \offset, sp, a0 +.endm + +.macro gen_test_inst_c_sdsp + .option push + gen_func_header c_sdsp, +c + /* Misalign stack pointer */ + sp_stack_prologue a1 + /* Misalign access */ + c.sdsp a2, 0(sp) + copy_long_to t0, sp, a0 + sp_stack_epilogue a1 + .option pop + ret +.endm + + + /* + * a0 = addr to load from + * a1 = address offset + * a2 = value to be loaded + */ +gen_test_inst lh +gen_test_inst lhu +gen_test_inst lw +gen_test_lwu +gen_test_inst ld +#ifdef __riscv_compressed +gen_test_inst_c lw +gen_test_inst_c ld +gen_test_inst_c_ldsp +#endif + +/* + * a0 = addr where to store value + * a1 = address offset + * a2 = value to be stored + */ +gen_test_inst sh +gen_test_inst sw +gen_test_inst sd +#ifdef __riscv_compressed +gen_test_inst_c sw +gen_test_inst_c sd +gen_test_inst_c_sdsp +#endif + diff --git a/tools/testing/selftests/riscv/misaligned/misaligned.c b/tools/testing/selftests/riscv/misaligned/misaligned.c new file mode 100644 index 000000000000..57ddcbdc947c --- /dev/null +++ b/tools/testing/selftests/riscv/misaligned/misaligned.c @@ -0,0 +1,288 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2025 Rivos Inc. + * + * Authors: + * Clément Léger + */ +#include +#include +#include +#include +#include "../../kselftest_harness.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#define stringify(s) __stringify(s) +#define __stringify(s) #s + +#define U8_MAX ((u8)~0U) +#define S8_MAX ((s8)(U8_MAX >> 1)) +#define S8_MIN ((s8)(-S8_MAX - 1)) +#define U16_MAX ((u16)~0U) +#define S16_MAX ((s16)(U16_MAX >> 1)) +#define S16_MIN ((s16)(-S16_MAX - 1)) +#define U32_MAX ((u32)~0U) +#define U32_MIN ((u32)0) +#define S32_MAX ((s32)(U32_MAX >> 1)) +#define S32_MIN ((s32)(-S32_MAX - 1)) +#define U64_MAX ((u64)~0ULL) +#define S64_MAX ((s64)(U64_MAX >> 1)) +#define S64_MIN ((s64)(-S64_MAX - 1)) + +#define int16_TEST_VALUES {S16_MIN, S16_MIN/2, -1, 1, S16_MAX/2, S16_MAX} +#define int32_TEST_VALUES {S32_MIN, S32_MIN/2, -1, 1, S32_MAX/2, S32_MAX} +#define int64_TEST_VALUES {S64_MIN, S64_MIN/2, -1, 1, S64_MAX/2, S64_MAX} +#define uint16_TEST_VALUES {0, U16_MAX/2, U16_MAX} +#define uint32_TEST_VALUES {0, U32_MAX/2, U32_MAX} + +#define float_TEST_VALUES {FLT_MIN, FLT_MIN/2, FLT_MAX/2, FLT_MAX} +#define double_TEST_VALUES {DBL_MIN, DBL_MIN/2, DBL_MAX/2, DBL_MAX} + +static bool float_equal(float a, float b) +{ + float scaled_epsilon; + float difference = fabsf(a - b); + + // Scale to the largest value. + a = fabsf(a); + b = fabsf(b); + if (a > b) + scaled_epsilon = FLT_EPSILON * a; + else + scaled_epsilon = FLT_EPSILON * b; + + return difference <= scaled_epsilon; +} + +static bool double_equal(double a, double b) +{ + double scaled_epsilon; + double difference = fabsl(a - b); + + // Scale to the largest value. + a = fabs(a); + b = fabs(b); + if (a > b) + scaled_epsilon = DBL_EPSILON * a; + else + scaled_epsilon = DBL_EPSILON * b; + + return difference <= scaled_epsilon; +} + +#define fpu_load_proto(__inst, __type) \ +extern __type test_ ## __inst(unsigned long fp_reg, void *addr, unsigned long offset, __type value) + +fpu_load_proto(flw, float); +fpu_load_proto(fld, double); +fpu_load_proto(c_flw, float); +fpu_load_proto(c_fld, double); +fpu_load_proto(c_fldsp, double); + +#define fpu_store_proto(__inst, __type) \ +extern void test_ ## __inst(unsigned long fp_reg, void *addr, unsigned long offset, __type value) + +fpu_store_proto(fsw, float); +fpu_store_proto(fsd, double); +fpu_store_proto(c_fsw, float); +fpu_store_proto(c_fsd, double); +fpu_store_proto(c_fsdsp, double); + +#define gp_load_proto(__inst, __type) \ +extern __type test_ ## __inst(void *addr, unsigned long offset, __type value) + +gp_load_proto(lh, int16_t); +gp_load_proto(lhu, uint16_t); +gp_load_proto(lw, int32_t); +gp_load_proto(lwu, uint32_t); +gp_load_proto(ld, int64_t); +gp_load_proto(c_lw, int32_t); +gp_load_proto(c_ld, int64_t); +gp_load_proto(c_ldsp, int64_t); + +#define gp_store_proto(__inst, __type) \ +extern void test_ ## __inst(void *addr, unsigned long offset, __type value) + +gp_store_proto(sh, int16_t); +gp_store_proto(sw, int32_t); +gp_store_proto(sd, int64_t); +gp_store_proto(c_sw, int32_t); +gp_store_proto(c_sd, int64_t); +gp_store_proto(c_sdsp, int64_t); + +#define TEST_GP_LOAD(__inst, __type_size, __type) \ +TEST(gp_load_ ## __inst) \ +{ \ + int offset, ret, val_i; \ + uint8_t buf[16] __attribute__((aligned(16))); \ + __type ## __type_size ## _t test_val[] = __type ## __type_size ## _TEST_VALUES; \ + \ + ret = prctl(PR_SET_UNALIGN, PR_UNALIGN_NOPRINT); \ + ASSERT_EQ(ret, 0); \ + \ + for (offset = 1; offset < (__type_size) / 8; offset++) { \ + for (val_i = 0; val_i < ARRAY_SIZE(test_val); val_i++) { \ + __type ## __type_size ## _t ref_val = test_val[val_i]; \ + __type ## __type_size ## _t *ptr = \ + (__type ## __type_size ## _t *)(buf + offset); \ + memcpy(ptr, &ref_val, sizeof(ref_val)); \ + __type ## __type_size ## _t val = \ + test_ ## __inst(ptr, offset, ref_val); \ + EXPECT_EQ(ref_val, val); \ + } \ + } \ +} + +TEST_GP_LOAD(lh, 16, int) +TEST_GP_LOAD(lhu, 16, uint) +TEST_GP_LOAD(lw, 32, int) +TEST_GP_LOAD(lwu, 32, uint) +TEST_GP_LOAD(ld, 64, int) +#ifdef __riscv_compressed +TEST_GP_LOAD(c_lw, 32, int) +TEST_GP_LOAD(c_ld, 64, int) +TEST_GP_LOAD(c_ldsp, 64, int) +#endif + +#define TEST_GP_STORE(__inst, __type_size, __type) \ +TEST(gp_store_ ## __inst) \ +{ \ + int offset, ret, val_i; \ + uint8_t buf[16] __attribute__((aligned(16))); \ + __type ## __type_size ## _t test_val[] = \ + __type ## __type_size ## _TEST_VALUES; \ + \ + ret = prctl(PR_SET_UNALIGN, PR_UNALIGN_NOPRINT); \ + ASSERT_EQ(ret, 0); \ + \ + for (val_i = 0; val_i < ARRAY_SIZE(test_val); val_i++) { \ + __type ## __type_size ## _t ref_val = test_val[val_i]; \ + for (offset = 1; offset < (__type_size) / 8; offset++) { \ + __type ## __type_size ## _t val = ref_val; \ + __type ## __type_size ## _t *ptr = \ + (__type ## __type_size ## _t *)(buf + offset); \ + memset(ptr, 0, sizeof(val)); \ + test_ ## __inst(ptr, offset, val); \ + memcpy(&val, ptr, sizeof(val)); \ + EXPECT_EQ(ref_val, val); \ + } \ + } \ +} + +TEST_GP_STORE(sh, 16, int) +TEST_GP_STORE(sw, 32, int) +TEST_GP_STORE(sd, 64, int) +#ifdef __riscv_compressed +TEST_GP_STORE(c_sw, 32, int) +TEST_GP_STORE(c_sd, 64, int) +TEST_GP_STORE(c_sdsp, 64, int) +#endif + +#define __TEST_FPU_LOAD(__type, __inst, __reg_start, __reg_end) \ +TEST(fpu_load_ ## __inst) \ +{ \ + int ret, offset, fp_reg, val_i; \ + uint8_t buf[16] __attribute__((aligned(16))); \ + __type test_val[] = __type ## _TEST_VALUES; \ + \ + ret = prctl(PR_SET_UNALIGN, PR_UNALIGN_NOPRINT); \ + ASSERT_EQ(ret, 0); \ + \ + for (fp_reg = __reg_start; fp_reg < __reg_end; fp_reg++) { \ + for (offset = 1; offset < 4; offset++) { \ + for (val_i = 0; val_i < ARRAY_SIZE(test_val); val_i++) { \ + __type val, ref_val = test_val[val_i]; \ + void *load_addr = (buf + offset); \ + \ + memcpy(load_addr, &ref_val, sizeof(ref_val)); \ + val = test_ ## __inst(fp_reg, load_addr, offset, ref_val); \ + EXPECT_TRUE(__type ##_equal(val, ref_val)); \ + } \ + } \ + } \ +} + +#define TEST_FPU_LOAD(__type, __inst) \ + __TEST_FPU_LOAD(__type, __inst, 0, 32) +#define TEST_FPU_LOAD_COMPRESSED(__type, __inst) \ + __TEST_FPU_LOAD(__type, __inst, 8, 16) + +TEST_FPU_LOAD(float, flw) +TEST_FPU_LOAD(double, fld) +#ifdef __riscv_compressed +TEST_FPU_LOAD_COMPRESSED(double, c_fld) +TEST_FPU_LOAD_COMPRESSED(double, c_fldsp) +#endif + +#define __TEST_FPU_STORE(__type, __inst, __reg_start, __reg_end) \ +TEST(fpu_store_ ## __inst) \ +{ \ + int ret, offset, fp_reg, val_i; \ + uint8_t buf[16] __attribute__((aligned(16))); \ + __type test_val[] = __type ## _TEST_VALUES; \ + \ + ret = prctl(PR_SET_UNALIGN, PR_UNALIGN_NOPRINT); \ + ASSERT_EQ(ret, 0); \ + \ + for (fp_reg = __reg_start; fp_reg < __reg_end; fp_reg++) { \ + for (offset = 1; offset < 4; offset++) { \ + for (val_i = 0; val_i < ARRAY_SIZE(test_val); val_i++) { \ + __type val, ref_val = test_val[val_i]; \ + \ + void *store_addr = (buf + offset); \ + \ + test_ ## __inst(fp_reg, store_addr, offset, ref_val); \ + memcpy(&val, store_addr, sizeof(val)); \ + EXPECT_TRUE(__type ## _equal(val, ref_val)); \ + } \ + } \ + } \ +} +#define TEST_FPU_STORE(__type, __inst) \ + __TEST_FPU_STORE(__type, __inst, 0, 32) +#define TEST_FPU_STORE_COMPRESSED(__type, __inst) \ + __TEST_FPU_STORE(__type, __inst, 8, 16) + +TEST_FPU_STORE(float, fsw) +TEST_FPU_STORE(double, fsd) +#ifdef __riscv_compressed +TEST_FPU_STORE_COMPRESSED(double, c_fsd) +TEST_FPU_STORE_COMPRESSED(double, c_fsdsp) +#endif + +TEST_SIGNAL(gen_sigbus, SIGBUS) +{ + uint32_t val = 0xDEADBEEF; + uint8_t buf[16] __attribute__((aligned(16))); + int ret; + + ret = prctl(PR_SET_UNALIGN, PR_UNALIGN_SIGBUS); + ASSERT_EQ(ret, 0); + + asm volatile("sw %0, 1(%1)" : : "r"(val), "r"(buf) : "memory"); +} + +int main(int argc, char **argv) +{ + int ret, val; + + ret = prctl(PR_GET_UNALIGN, &val); + if (ret == -1 && errno == EINVAL) + ksft_exit_skip("SKIP GET_UNALIGN_CTL not supported\n"); + + exit(test_harness_run(argc, argv)); +} -- 2.43.0 From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 68D91C83F1B for ; Fri, 11 Jul 2025 13:36:42 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:Message-ID:Date:Subject:Cc :To:From:Reply-To:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:In-Reply-To:References: List-Owner; bh=zUpVBicIXqXWx6DwzM5aty+CVgZ10fnNT0laPki5KVk=; b=S7LNlGgHZbxbPi B5umK3675ykaCL08dedfDpO8YcOkIJxPtork5tsh0nkXzxC8sD6hNHJsy2bmnHYbK2Ln3x4sEI9b8 IxnCsY7blg71o/iyK1yCbd/oI/ZN7UWI9VKQ+eU82kNN0dCzfxiXTeJdKIrNOsP1br+OtXW67hNtZ McVW7Y1ARbMW5IHL21ENqZHVz/DANvrL3Tlp3/SaOucLvkHbKSDoM1d3YUAXKDRDLSDVV26TNxIGP m5mVP9KjWUsK3l+bWDrJF7jXkxoYYeSO9pbH9BQvMT1eHsmoISTINhVkFbQ1jWp8JxRqWDfHHvJ8V B67ZE70MceqYtRYf9y1A==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.98.2 #2 (Red Hat Linux)) id 1uaDvS-0000000EuHD-1HXC; Fri, 11 Jul 2025 13:36:30 +0000 Received: from mail-pl1-x631.google.com ([2607:f8b0:4864:20::631]) by bombadil.infradead.org with esmtps (Exim 4.98.2 #2 (Red Hat Linux)) id 1uaDfT-0000000ErVG-3W4H for linux-riscv@lists.infradead.org; Fri, 11 Jul 2025 13:20:01 +0000 Received: by mail-pl1-x631.google.com with SMTP id d9443c01a7336-23508d30142so22268975ad.0 for ; Fri, 11 Jul 2025 06:19:59 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=rivosinc-com.20230601.gappssmtp.com; s=20230601; t=1752239999; x=1752844799; darn=lists.infradead.org; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:from:to:cc:subject:date:message-id:reply-to; bh=6//hd5/2Hzqt0npYzE6gaxMoRCrJFz+kATaycN9jSlk=; b=OBw+hI3RicYNOLXXmKzaVJqMq9apvYQ5D02AiML+/WOEhrCpuQRYz2bjelFAvUC1rR jypV52pJDaQl/9qCe+dtSOiw4+DP6429u7bSx6Z8CWnbcdAMzgng2pXMyFSBEIBV1Sdz CGqwlkOZYSpm6f24h/5+3PjIzgs4UA9Ih5TABY/VC3sXpm//00sdknkS8aO0atGeglaU X7iRlhlerwNfL5G/OYReSCUkYfd2OZrFg1gR1H+uVNz/fTm+dImDLeQjwY+a7prCGezM keBrAGPxP8l0BC1UsxVes5SOT0GXK5zYF41uJiRMQgdjuaPZSOs8a/+aGwg1aMgCddVw Hh0Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1752239999; x=1752844799; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=6//hd5/2Hzqt0npYzE6gaxMoRCrJFz+kATaycN9jSlk=; b=YoUIDfguyh+MmKLwkZVS/yBQ4HZZsQ/Q6R4r6mP1BzPT0cFHIlZ2QEwYhOGiMvfUbr GmX1V9Qz2c+6hRlHHi//Kqaa+KqCmsYE3DZ4xBaXQJB7SRji8m2erep8SnsXq6KEESNf Yz2UnSSv86n/KXTI7y7oc+31LWD9DMapT7zL620Q263PkjL2TGiv6OAi5vMJeSg5q7pr GTbuCcLv5OYtzQzAGNYq5F4FOm51kBwKPUpB8gvPDdlhFwC319Qux5r+RM+BYoym4rvi R3AUGZKSoPcdidjrBoGs1ParObemeWl6mgUJbIPswcqHtH3XrUiBo9j3p5nu/NWWU1Is TWUw== X-Forwarded-Encrypted: i=1; AJvYcCVCnZyJzBDeH5Yxfk6W+63oXAQlZ78HA4M7UbvSftYkAPaA9ZYmYw8/sZGS9/yzm69WNg8fTY7uoHsC9w==@lists.infradead.org X-Gm-Message-State: AOJu0YyAAZ2SKzCJKUNMrMfNnjYbX5/jjD9O2A1oORexgwN+fbYZhdqF 8P10EGsAkYISnbV9AS2ZsjGYiMmNmx08IhBN4RNWZNlwMMk7uErLjrjoIa6Cd5nRPjo= X-Gm-Gg: ASbGncvGKOCRJAolNkKbFwpV2TrjE8ny6u3bfezX/spG6KJjFM/HEJmHiDIYh8Ydgcw yiwKOehHvqMPAuta8ZERNCqmLXq5eBJqb7nQ/kncAkts1oBxByg/YHuwZmdwUUp5CKLrnePppgS IjeBJ02cAvdx9vgoMFNrQbbWCQkm1f2syLDFBZ0vnhwfh0BmJg1QFod9aeIP6pnqBGNbed5CCra uQWAv0YfFKs0gLJj8x4Fkf72Sy0znZuGkkyD4UEB5kFQZWWvrSwg6lATWC4Vy7fhHl8Et9kleWN CjFnQHrOiLKn9FpRtkeHluSaxqNCGIMWLNeXvUoP4QfYRLVB4bOggWbF/X39yXmAt/00tyFtJDD KZHjzFF7HnHSVRw== X-Google-Smtp-Source: AGHT+IHxrRQsPtuvfbXx6QfQiO/WeYYzyL8cHrvNDnYrHbvIxocomxFbz25k5rB1zAsStkf+RMEFpw== X-Received: by 2002:a17:903:a4f:b0:235:f70:fd39 with SMTP id d9443c01a7336-23dede2e17cmr37632915ad.10.1752239998668; Fri, 11 Jul 2025 06:19:58 -0700 (PDT) Received: from cleger.eu.int ([2001:41d0:420:f300::]) by smtp.gmail.com with ESMTPSA id 41be03b00d2f7-b3bbe52e261sm5158486a12.2.2025.07.11.06.19.52 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 11 Jul 2025 06:19:57 -0700 (PDT) From: =?UTF-8?q?Cl=C3=A9ment=20L=C3=A9ger?= To: linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org, linux-riscv@lists.infradead.org Cc: =?UTF-8?q?Cl=C3=A9ment=20L=C3=A9ger?= , Palmer Dabbelt , Paul Walmsley , Shuah Khan , Alexandre Ghiti , Andreas Schwab Subject: [PATCH v5] selftests: riscv: add misaligned access testing Date: Fri, 11 Jul 2025 13:19:24 +0000 Message-ID: <20250711131925.112485-1-cleger@rivosinc.com> X-Mailer: git-send-email 2.43.0 MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20250711_061959_977868_E8006DEB X-CRM114-Status: GOOD ( 20.71 ) X-BeenThere: linux-riscv@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 Sender: "linux-riscv" Errors-To: linux-riscv-bounces+linux-riscv=archiver.kernel.org@lists.infradead.org VGhpcyBzZWxmdGVzdCB0ZXN0cyBhbGwgdGhlIGN1cnJlbnRseSBlbXVsYXRlZCBpbnN0cnVjdGlv bnMgKGV4Y2VwdCBmb3IKdGhlIFJWMzIgY29tcHJlc3NlZCBvbmVzIHdoaWNoIGFyZSBsZWZ0IGFz IGEgZnV0dXJlIGV4ZXJjaXNlIGZvciBhIFJWMzIKdXNlcikuIEZvciB0aGUgRlBVIGluc3RydWN0 aW9ucywgYWxsIHRoZSBGUFUgcmVnaXN0ZXJzIGFyZSB0ZXN0ZWQuCgpTaWduZWQtb2ZmLWJ5OiBD bMOpbWVudCBMw6lnZXIgPGNsZWdlckByaXZvc2luYy5jb20+CgotLS0KClRoaXMgY29tbWl0cyBu ZWVkcyBbMV0gZm9yIHRoZSB0ZXN0IHRvIGJlIHBhc3NlZCBvciBpdCB3aWxsIGZhaWwgZHVlIHRv Cm1pc3Npbmcgc2lnbiBleHRlbnNpb24uCgpOb3RlOiBUaGlzIHRlc3QgY2FuIGJlIGV4ZWN1dGVk IHVzaW5nIGFuIFNCSSB0aGF0IHN1cHBvcnQgRldGVCBvciB0aGF0CmRlbGVnYXRlcyBtaXNhbGln bmVkIHRyYXBzIGJ5IGRlZmF1bHQuIElmIHVzaW5nIFFFTVUsIHlvdSB3aWxsIG5lZWQKdGhlIHBh dGNoZXMgbWVudGlvbmVkIGF0IFsyXSBzbyB0aGF0IG1pc2FsaWduZWQgYWNjZXNzZXMgd2lsbCBn ZW5lcmF0ZQphIHRyYXAuCgpOb3RlOiBUaGlzIGNvbW1pdCB3YXMgcGFydCBvZiBhIHNlcmllcyBb M10gdGhhdCB3YXMgcGFydGlhbGx5IG1lcmdlZC4KCk5vdGU6IHRoZSByZW1haW5pbmcgY2hlY2tw YXRjaCBlcnJvcnMgYXJlIG5vdCBhcHBsaWNhYmxlIHRvIHRoaXMgdGVzdHMKd2hpY2ggaXMgYSB1 c2Vyc3BhY2Ugb25lIGFuZCBkb2VzIG5vdCB1c2UgdGhlIGtlcm5lbCBoZWFkZXJzLiBNYWNyb3MK d2l0aCBjb21wbGV4IHZhbHVlcyBjYW4gbm90IGJlIGVuY2xvc2VkIGluIGRvIHdoaWxlIGxvb3Ag c2luY2UgdGhleSBhcmUKZ2VuZXJhdGluZyBmdW5jdGlvbnMuCgpMaW5rOiBodHRwczovL2xvcmUu a2VybmVsLm9yZy9saW51eC1yaXNjdi9tdm1pa2swZ29pbC5mc2ZAc3VzZS5kZS8gWzFdCkxpbms6 IGh0dHBzOi8vbG9yZS5rZXJuZWwub3JnL2FsbC8yMDI0MTIxMTIxMTkzMy4xOTg3OTItMS1ma29u cmFkQGFtZC5jb20vIFsyXQpMaW5rOiBodHRwczovL2xvcmUua2VybmVsLm9yZy9saW51eC1yaXNj di8yMDI1MDQyMjE2MjMyNC45NTYwNjUtMS1jbGVnZXJAcml2b3NpbmMuY29tLyBbM10KClY1Ogog LSBTaWduIGV4dGVuZCBMV1UgcmV0dXJuIHZhbHVlCiAtIEFkZGVkIHNpZ24gZXh0ZW5zaW9ucyB0 ZXN0cwogLSBUZXN0cyBtdWx0aXBsZXMgdmFsdWVzIGZvciBHUCBsb2FkL3N0b3JlCgpWNDoKIC0g Rml4ZWQgYSB0eXBvIGluIHRlc3QgbmFtZSBzL2xvYWQvc3RvcmUKClYzOgogLSBGaXhlZCBhIHNl Z2ZhdWx0IGFuZCBhIHNpZ24gZXh0ZW5zaW9uIGVycm9yIGZvdW5kIHdoZW4gY29tcGlsaW5nIHdp dGgKICAtTzx4PiwgeCAhPSAwIChBbGV4KQogLSBVc2UgaW5saW5lIGFzc2VtYmx5IHRvIGdlbmVy YXRlIHRoZSBzaWdidXMgYW5kIGF2b2lkIEdDQwogICBvcHRpbWl6YXRpb25zCgpWMjoKIC0gRml4 IGNvbW1pdCBkZXNjcmlwdGlvbgogLSBGaXggYSBmZXcgZXJyb3JzIHJlcG9ydGVkIGJ5IGNoZWNr cGF0Y2gucGwKLS0tCiB0b29scy90ZXN0aW5nL3NlbGZ0ZXN0cy9yaXNjdi9NYWtlZmlsZSAgICAg ICAgfCAgIDIgKy0KIC4uLi9zZWxmdGVzdHMvcmlzY3YvbWlzYWxpZ25lZC8uZ2l0aWdub3JlICAg ICB8ICAgMSArCiAuLi4vc2VsZnRlc3RzL3Jpc2N2L21pc2FsaWduZWQvTWFrZWZpbGUgICAgICAg fCAgMTIgKwogLi4uL3NlbGZ0ZXN0cy9yaXNjdi9taXNhbGlnbmVkL2NvbW1vbi5TICAgICAgIHwg IDMzICsrCiAuLi4vdGVzdGluZy9zZWxmdGVzdHMvcmlzY3YvbWlzYWxpZ25lZC9mcHUuUyAgfCAx ODAgKysrKysrKysrKysKIHRvb2xzL3Rlc3Rpbmcvc2VsZnRlc3RzL3Jpc2N2L21pc2FsaWduZWQv Z3AuUyB8IDExMyArKysrKysrCiAuLi4vc2VsZnRlc3RzL3Jpc2N2L21pc2FsaWduZWQvbWlzYWxp Z25lZC5jICAgfCAyODggKysrKysrKysrKysrKysrKysrCiA3IGZpbGVzIGNoYW5nZWQsIDYyOCBp bnNlcnRpb25zKCspLCAxIGRlbGV0aW9uKC0pCiBjcmVhdGUgbW9kZSAxMDA2NDQgdG9vbHMvdGVz dGluZy9zZWxmdGVzdHMvcmlzY3YvbWlzYWxpZ25lZC8uZ2l0aWdub3JlCiBjcmVhdGUgbW9kZSAx MDA2NDQgdG9vbHMvdGVzdGluZy9zZWxmdGVzdHMvcmlzY3YvbWlzYWxpZ25lZC9NYWtlZmlsZQog Y3JlYXRlIG1vZGUgMTAwNjQ0IHRvb2xzL3Rlc3Rpbmcvc2VsZnRlc3RzL3Jpc2N2L21pc2FsaWdu ZWQvY29tbW9uLlMKIGNyZWF0ZSBtb2RlIDEwMDY0NCB0b29scy90ZXN0aW5nL3NlbGZ0ZXN0cy9y aXNjdi9taXNhbGlnbmVkL2ZwdS5TCiBjcmVhdGUgbW9kZSAxMDA2NDQgdG9vbHMvdGVzdGluZy9z ZWxmdGVzdHMvcmlzY3YvbWlzYWxpZ25lZC9ncC5TCiBjcmVhdGUgbW9kZSAxMDA2NDQgdG9vbHMv dGVzdGluZy9zZWxmdGVzdHMvcmlzY3YvbWlzYWxpZ25lZC9taXNhbGlnbmVkLmMKCmRpZmYgLS1n aXQgYS90b29scy90ZXN0aW5nL3NlbGZ0ZXN0cy9yaXNjdi9NYWtlZmlsZSBiL3Rvb2xzL3Rlc3Rp bmcvc2VsZnRlc3RzL3Jpc2N2L01ha2VmaWxlCmluZGV4IDA5OWI4YzFmNDZmOC4uOTVhOThjZWVi M2IzIDEwMDY0NAotLS0gYS90b29scy90ZXN0aW5nL3NlbGZ0ZXN0cy9yaXNjdi9NYWtlZmlsZQor KysgYi90b29scy90ZXN0aW5nL3NlbGZ0ZXN0cy9yaXNjdi9NYWtlZmlsZQpAQCAtNSw3ICs1LDcg QEAKIEFSQ0ggPz0gJChzaGVsbCB1bmFtZSAtbSAyPi9kZXYvbnVsbCB8fCBlY2hvIG5vdCkKIAog aWZuZXEgKCwkKGZpbHRlciAkKEFSQ0gpLHJpc2N2KSkKLVJJU0NWX1NVQlRBUkdFVFMgPz0gYWJp IGh3cHJvYmUgbW0gc2lncmV0dXJuIHZlY3RvcgorUklTQ1ZfU1VCVEFSR0VUUyA/PSBhYmkgaHdw cm9iZSBtbSBzaWdyZXR1cm4gdmVjdG9yIG1pc2FsaWduZWQKIGVsc2UKIFJJU0NWX1NVQlRBUkdF VFMgOj0KIGVuZGlmCmRpZmYgLS1naXQgYS90b29scy90ZXN0aW5nL3NlbGZ0ZXN0cy9yaXNjdi9t aXNhbGlnbmVkLy5naXRpZ25vcmUgYi90b29scy90ZXN0aW5nL3NlbGZ0ZXN0cy9yaXNjdi9taXNh bGlnbmVkLy5naXRpZ25vcmUKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMDAwMDAw Li41ZWZmMTVhMWY5ODEKLS0tIC9kZXYvbnVsbAorKysgYi90b29scy90ZXN0aW5nL3NlbGZ0ZXN0 cy9yaXNjdi9taXNhbGlnbmVkLy5naXRpZ25vcmUKQEAgLTAsMCArMSBAQAorbWlzYWxpZ25lZApk aWZmIC0tZ2l0IGEvdG9vbHMvdGVzdGluZy9zZWxmdGVzdHMvcmlzY3YvbWlzYWxpZ25lZC9NYWtl ZmlsZSBiL3Rvb2xzL3Rlc3Rpbmcvc2VsZnRlc3RzL3Jpc2N2L21pc2FsaWduZWQvTWFrZWZpbGUK bmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMDAwMDAwLi4xYWE0MDExMGM1MGQKLS0t IC9kZXYvbnVsbAorKysgYi90b29scy90ZXN0aW5nL3NlbGZ0ZXN0cy9yaXNjdi9taXNhbGlnbmVk L01ha2VmaWxlCkBAIC0wLDAgKzEsMTIgQEAKKyMgU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEdQ TC0yLjAKKyMgQ29weXJpZ2h0IChDKSAyMDIxIEFSTSBMaW1pdGVkCisjIE9yaWdpbmFsbHkgdG9v bHMvdGVzdGluZy9hcm02NC9hYmkvTWFrZWZpbGUKKworQ0ZMQUdTICs9IC1JJCh0b3Bfc3JjZGly KS90b29scy9pbmNsdWRlCisKK1RFU1RfR0VOX1BST0dTIDo9IG1pc2FsaWduZWQKKworaW5jbHVk ZSAuLi8uLi9saWIubWsKKworJChPVVRQVVQpL21pc2FsaWduZWQ6IG1pc2FsaWduZWQuYyBmcHUu UyBncC5TCisJJChDQykgLWczIC1zdGF0aWMgLW8kQCAtbWFyY2g9cnY2NGltYWZkYyAkKENGTEFH UykgJChMREZMQUdTKSAkXgpkaWZmIC0tZ2l0IGEvdG9vbHMvdGVzdGluZy9zZWxmdGVzdHMvcmlz Y3YvbWlzYWxpZ25lZC9jb21tb24uUyBiL3Rvb2xzL3Rlc3Rpbmcvc2VsZnRlc3RzL3Jpc2N2L21p c2FsaWduZWQvY29tbW9uLlMKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMDAwMDAw Li44ZmEwMDAzNWJkNWQKLS0tIC9kZXYvbnVsbAorKysgYi90b29scy90ZXN0aW5nL3NlbGZ0ZXN0 cy9yaXNjdi9taXNhbGlnbmVkL2NvbW1vbi5TCkBAIC0wLDAgKzEsMzMgQEAKKy8qIFNQRFgtTGlj ZW5zZS1JZGVudGlmaWVyOiBHUEwtMi4wLW9ubHkgKi8KKy8qCisgKiBDb3B5cmlnaHQgKGMpIDIw MjUgUml2b3MgSW5jLgorICoKKyAqIEF1dGhvcnM6CisgKiAgICAgQ2zDqW1lbnQgTMOpZ2VyIDxj bGVnZXJAcml2b3NpbmMuY29tPgorICovCisKKy5tYWNybyBsYl9zYiB0ZW1wLCBvZmZzZXQsIHNy YywgZHN0CisJbGIgXHRlbXAsIFxvZmZzZXQoXHNyYykKKwlzYiBcdGVtcCwgXG9mZnNldChcZHN0 KQorLmVuZG0KKworLm1hY3JvIGNvcHlfbG9uZ190byB0ZW1wLCBzcmMsIGRzdAorCWxiX3NiIFx0 ZW1wLCAwLCBcc3JjLCBcZHN0LAorCWxiX3NiIFx0ZW1wLCAxLCBcc3JjLCBcZHN0LAorCWxiX3Ni IFx0ZW1wLCAyLCBcc3JjLCBcZHN0LAorCWxiX3NiIFx0ZW1wLCAzLCBcc3JjLCBcZHN0LAorCWxi X3NiIFx0ZW1wLCA0LCBcc3JjLCBcZHN0LAorCWxiX3NiIFx0ZW1wLCA1LCBcc3JjLCBcZHN0LAor CWxiX3NiIFx0ZW1wLCA2LCBcc3JjLCBcZHN0LAorCWxiX3NiIFx0ZW1wLCA3LCBcc3JjLCBcZHN0 LAorLmVuZG0KKworLm1hY3JvIHNwX3N0YWNrX3Byb2xvZ3VlIG9mZnNldAorCWFkZGkgc3AsIHNw LCAtOAorCXN1YiBzcCwgc3AsIFxvZmZzZXQKKy5lbmRtCisKKy5tYWNybyBzcF9zdGFja19lcGls b2d1ZSBvZmZzZXQKKwlhZGQgc3AsIHNwLCBcb2Zmc2V0CisJYWRkaSBzcCwgc3AsIDgKKy5lbmRt CmRpZmYgLS1naXQgYS90b29scy90ZXN0aW5nL3NlbGZ0ZXN0cy9yaXNjdi9taXNhbGlnbmVkL2Zw dS5TIGIvdG9vbHMvdGVzdGluZy9zZWxmdGVzdHMvcmlzY3YvbWlzYWxpZ25lZC9mcHUuUwpuZXcg ZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwMDAwMDAuLmE3YWQ0NDMwYTQyNAotLS0gL2Rl di9udWxsCisrKyBiL3Rvb2xzL3Rlc3Rpbmcvc2VsZnRlc3RzL3Jpc2N2L21pc2FsaWduZWQvZnB1 LlMKQEAgLTAsMCArMSwxODAgQEAKKy8qIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBHUEwtMi4w LW9ubHkgKi8KKy8qCisgKiBDb3B5cmlnaHQgKGMpIDIwMjUgUml2b3MgSW5jLgorICoKKyAqIEF1 dGhvcnM6CisgKiAgICAgQ2zDqW1lbnQgTMOpZ2VyIDxjbGVnZXJAcml2b3NpbmMuY29tPgorICov CisKKyNpbmNsdWRlICJjb21tb24uUyIKKworI2RlZmluZSBDQVNFX0FMSUdOCQk0CisKKy5tYWNy byBmcHVfbG9hZF9pbnN0IGZwcmVnLCBpbnN0LCBwcmVjaXNpb24sIGxvYWRfcmVnCisuYWxpZ24g Q0FTRV9BTElHTgorCVxpbnN0IFxmcHJlZywgMChcbG9hZF9yZWcpCisJZm12LlxwcmVjaXNpb24g ZmEwLCBcZnByZWcKKwlqIDJmCisuZW5kbQorCisjZGVmaW5lIGZsdyhfX2ZwcmVnKSBmcHVfbG9h ZF9pbnN0IF9fZnByZWcsIGZsdywgcywgYTQKKyNkZWZpbmUgZmxkKF9fZnByZWcpIGZwdV9sb2Fk X2luc3QgX19mcHJlZywgZmxkLCBkLCBhNAorI2RlZmluZSBjX2ZsdyhfX2ZwcmVnKSBmcHVfbG9h ZF9pbnN0IF9fZnByZWcsIGMuZmx3LCBzLCBhNAorI2RlZmluZSBjX2ZsZChfX2ZwcmVnKSBmcHVf bG9hZF9pbnN0IF9fZnByZWcsIGMuZmxkLCBkLCBhNAorI2RlZmluZSBjX2ZsZHNwKF9fZnByZWcp IGZwdV9sb2FkX2luc3QgX19mcHJlZywgYy5mbGRzcCwgZCwgc3AKKworLm1hY3JvIGZwdV9zdG9y ZV9pbnN0IGZwcmVnLCBpbnN0LCBwcmVjaXNpb24sIHN0b3JlX3JlZworLmFsaWduIENBU0VfQUxJ R04KKwlmbXYuXHByZWNpc2lvbiBcZnByZWcsIGZhMAorCVxpbnN0IFxmcHJlZywgMChcc3RvcmVf cmVnKQorCWogMmYKKy5lbmRtCisKKyNkZWZpbmUgZnN3KF9fZnByZWcpIGZwdV9zdG9yZV9pbnN0 IF9fZnByZWcsIGZzdywgcywgYTQKKyNkZWZpbmUgZnNkKF9fZnByZWcpIGZwdV9zdG9yZV9pbnN0 IF9fZnByZWcsIGZzZCwgZCwgYTQKKyNkZWZpbmUgY19mc3coX19mcHJlZykgZnB1X3N0b3JlX2lu c3QgX19mcHJlZywgYy5mc3csIHMsIGE0CisjZGVmaW5lIGNfZnNkKF9fZnByZWcpIGZwdV9zdG9y ZV9pbnN0IF9fZnByZWcsIGMuZnNkLCBkLCBhNAorI2RlZmluZSBjX2ZzZHNwKF9fZnByZWcpIGZw dV9zdG9yZV9pbnN0IF9fZnByZWcsIGMuZnNkc3AsIGQsIHNwCisKKy5tYWNybyBmcF90ZXN0X3By b2xvZ3VlCisJbW92ZSBhNCwgYTEKKwkvKgorCSAqIENvbXB1dGUganVtcCBvZmZzZXQgdG8gc3Rv cmUgdGhlIGNvcnJlY3QgRlAgcmVnaXN0ZXIgc2luY2Ugd2UgZG9uJ3QKKwkgKiBoYXZlIGluZGly ZWN0IEZQIHJlZ2lzdGVyIGFjY2VzcyAob3IgYXQgbGVhc3Qgd2UgZG9uJ3QgdXNlIHRoaXMKKwkg KiBleHRlbnNpb24gc28gdGhhdCB3b3JrcyBvbiBhbGwgYXJjaHMpCisJICovCisJc2xsIHQwLCBh MCwgQ0FTRV9BTElHTgorCWxhIHQyLCAxZgorCWFkZCB0MCwgdDAsIHQyCisJanIgdDAKKy5hbGln bglDQVNFX0FMSUdOCisxOgorLmVuZG0KKworLm1hY3JvIGZwX3Rlc3RfcHJvbG9ndWVfY29tcHJl c3NlZAorCS8qIEZQIHJlZ2lzdGVycyBmb3IgY29tcHJlc3NlZCBpbnN0cnVjdGlvbnMgc3RhcnRz IGZyb20gOCB0byAxNiAqLworCWFkZGkgYTAsIGEwLCAtOAorCWZwX3Rlc3RfcHJvbG9ndWUKKy5l bmRtCisKKyNkZWZpbmUgZnBfdGVzdF9ib2R5X2NvbXByZXNzZWQoX19pbnN0X2Z1bmMpIFwKKwlf X2luc3RfZnVuYyhmOCk7IFwKKwlfX2luc3RfZnVuYyhmOSk7IFwKKwlfX2luc3RfZnVuYyhmMTAp OyBcCisJX19pbnN0X2Z1bmMoZjExKTsgXAorCV9faW5zdF9mdW5jKGYxMik7IFwKKwlfX2luc3Rf ZnVuYyhmMTMpOyBcCisJX19pbnN0X2Z1bmMoZjE0KTsgXAorCV9faW5zdF9mdW5jKGYxNSk7IFwK KzI6CisKKyNkZWZpbmUgZnBfdGVzdF9ib2R5KF9faW5zdF9mdW5jKSBcCisJX19pbnN0X2Z1bmMo ZjApOyBcCisJX19pbnN0X2Z1bmMoZjEpOyBcCisJX19pbnN0X2Z1bmMoZjIpOyBcCisJX19pbnN0 X2Z1bmMoZjMpOyBcCisJX19pbnN0X2Z1bmMoZjQpOyBcCisJX19pbnN0X2Z1bmMoZjUpOyBcCisJ X19pbnN0X2Z1bmMoZjYpOyBcCisJX19pbnN0X2Z1bmMoZjcpOyBcCisJX19pbnN0X2Z1bmMoZjgp OyBcCisJX19pbnN0X2Z1bmMoZjkpOyBcCisJX19pbnN0X2Z1bmMoZjEwKTsgXAorCV9faW5zdF9m dW5jKGYxMSk7IFwKKwlfX2luc3RfZnVuYyhmMTIpOyBcCisJX19pbnN0X2Z1bmMoZjEzKTsgXAor CV9faW5zdF9mdW5jKGYxNCk7IFwKKwlfX2luc3RfZnVuYyhmMTUpOyBcCisJX19pbnN0X2Z1bmMo ZjE2KTsgXAorCV9faW5zdF9mdW5jKGYxNyk7IFwKKwlfX2luc3RfZnVuYyhmMTgpOyBcCisJX19p bnN0X2Z1bmMoZjE5KTsgXAorCV9faW5zdF9mdW5jKGYyMCk7IFwKKwlfX2luc3RfZnVuYyhmMjEp OyBcCisJX19pbnN0X2Z1bmMoZjIyKTsgXAorCV9faW5zdF9mdW5jKGYyMyk7IFwKKwlfX2luc3Rf ZnVuYyhmMjQpOyBcCisJX19pbnN0X2Z1bmMoZjI1KTsgXAorCV9faW5zdF9mdW5jKGYyNik7IFwK KwlfX2luc3RfZnVuYyhmMjcpOyBcCisJX19pbnN0X2Z1bmMoZjI4KTsgXAorCV9faW5zdF9mdW5j KGYyOSk7IFwKKwlfX2luc3RfZnVuYyhmMzApOyBcCisJX19pbnN0X2Z1bmMoZjMxKTsgXAorMjoK Ky50ZXh0CisKKyNkZWZpbmUgX19nZW5fdGVzdF9pbnN0KF9faW5zdCwgX19zdWZmaXgpIFwKKy5n bG9iYWwgdGVzdF8gIyMgX19pbnN0OyBcCit0ZXN0XyAjIyBfX2luc3Q6OyBcCisJZnBfdGVzdF9w cm9sb2d1ZSAjIyBfX3N1ZmZpeDsgXAorCWZwX3Rlc3RfYm9keSAjIyBfX3N1ZmZpeChfX2luc3Qp OyBcCisJcmV0CisKKyNkZWZpbmUgZ2VuX3Rlc3RfaW5zdF9jb21wcmVzc2VkKF9faW5zdCkgXAor CS5vcHRpb24gYXJjaCwrYzsgXAorCV9fZ2VuX3Rlc3RfaW5zdChjXyAjIyBfX2luc3QsIF9jb21w cmVzc2VkKQorCisjZGVmaW5lIGdlbl90ZXN0X2luc3QoX19pbnN0KSBcCisJLmJhbGlnbiAxNjsg XAorCS5vcHRpb24gcHVzaDsgXAorCS5vcHRpb24gYXJjaCwtYzsgXAorCV9fZ2VuX3Rlc3RfaW5z dChfX2luc3QsICk7IFwKKwkub3B0aW9uIHBvcAorCisubWFjcm8gZnBfdGVzdF9wcm9sb2d1ZV9s b2FkX2NvbXByZXNzZWRfc3AKKwljb3B5X2xvbmdfdG8gdDAsIGExLCBzcAorLmVuZG0KKworLm1h Y3JvIGZwX3Rlc3RfZXBpbG9ndWVfbG9hZF9jb21wcmVzc2VkX3NwCisuZW5kbQorCisubWFjcm8g ZnBfdGVzdF9wcm9sb2d1ZV9zdG9yZV9jb21wcmVzc2VkX3NwCisuZW5kbQorCisubWFjcm8gZnBf dGVzdF9lcGlsb2d1ZV9zdG9yZV9jb21wcmVzc2VkX3NwCisJY29weV9sb25nX3RvIHQwLCBzcCwg YTEKKy5lbmRtCisKKyNkZWZpbmUgZ2VuX2luc3RfY29tcHJlc3NlZF9zcChfX2luc3QsIF9fdHlw ZSkgXAorCS5nbG9iYWwgdGVzdF9jXyAjIyBfX2luc3QgIyMgc3A7IFwKKwl0ZXN0X2NfICMjIF9f aW5zdCAjIyBzcDo7IFwKKwkJc3Bfc3RhY2tfcHJvbG9ndWUgYTI7IFwKKwkJZnBfdGVzdF9wcm9s b2d1ZV8jIyBfX3R5cGUgIyMgX2NvbXByZXNzZWRfc3A7IFwKKwkJZnBfdGVzdF9wcm9sb2d1ZV9j b21wcmVzc2VkOyBcCisJCWZwX3Rlc3RfYm9keV9jb21wcmVzc2VkKGNfICMjIF9faW5zdCAjIyBz cCk7IFwKKwkJZnBfdGVzdF9lcGlsb2d1ZV8jIyBfX3R5cGUgIyMgX2NvbXByZXNzZWRfc3A7IFwK KwkJc3Bfc3RhY2tfZXBpbG9ndWUgYTI7IFwKKwkJcmV0CisKKyNkZWZpbmUgZ2VuX3Rlc3RfbG9h ZF9jb21wcmVzc2VkX3NwKF9faW5zdCkgZ2VuX2luc3RfY29tcHJlc3NlZF9zcChfX2luc3QsIGxv YWQpCisjZGVmaW5lIGdlbl90ZXN0X3N0b3JlX2NvbXByZXNzZWRfc3AoX19pbnN0KSBnZW5faW5z dF9jb21wcmVzc2VkX3NwKF9faW5zdCwgc3RvcmUpCisKKy8qCisgKiBmbG9hdF9mc3dfcmVnIC0g U2V0IGEgRlAgcmVnaXN0ZXIgZnJvbSBhIHJlZ2lzdGVyIGNvbnRhaW5pbmcgdGhlIHZhbHVlCisg KiBhMCA9IEZQIHJlZ2lzdGVyIGluZGV4IHRvIGJlIHNldAorICogYTEgPSBhZGRyIHdoZXJlIHRv IHN0b3JlIHJlZ2lzdGVyIHZhbHVlCisgKiBhMiA9IGFkZHJlc3Mgb2Zmc2V0CisgKiBhMyA9IHZh bHVlIHRvIGJlIHN0b3JlCisgKi8KK2dlbl90ZXN0X2luc3QoZnN3KQorCisvKgorICogZmxvYXRf Zmx3X3JlZyAtIEdldCBhIEZQIHJlZ2lzdGVyIHZhbHVlIGFuZCByZXR1cm4gaXQKKyAqIGEwID0g RlAgcmVnaXN0ZXIgaW5kZXggdG8gYmUgcmV0cmlldmVkCisgKiBhMSA9IGFkZHIgdG8gbG9hZCBy ZWdpc3RlciBmcm9tCisgKiBhMiA9IGFkZHJlc3Mgb2Zmc2V0CisgKi8KK2dlbl90ZXN0X2luc3Qo Zmx3KQorCitnZW5fdGVzdF9pbnN0KGZzZCkKKyNpZmRlZiBfX3Jpc2N2X2NvbXByZXNzZWQKK2dl bl90ZXN0X2luc3RfY29tcHJlc3NlZChmc2QpCitnZW5fdGVzdF9zdG9yZV9jb21wcmVzc2VkX3Nw KGZzZCkKKyNlbmRpZgorCitnZW5fdGVzdF9pbnN0KGZsZCkKKyNpZmRlZiBfX3Jpc2N2X2NvbXBy ZXNzZWQKK2dlbl90ZXN0X2luc3RfY29tcHJlc3NlZChmbGQpCitnZW5fdGVzdF9sb2FkX2NvbXBy ZXNzZWRfc3AoZmxkKQorI2VuZGlmCmRpZmYgLS1naXQgYS90b29scy90ZXN0aW5nL3NlbGZ0ZXN0 cy9yaXNjdi9taXNhbGlnbmVkL2dwLlMgYi90b29scy90ZXN0aW5nL3NlbGZ0ZXN0cy9yaXNjdi9t aXNhbGlnbmVkL2dwLlMKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMDAwMDAwLi41 YWJlYzVjY2M4MjgKLS0tIC9kZXYvbnVsbAorKysgYi90b29scy90ZXN0aW5nL3NlbGZ0ZXN0cy9y aXNjdi9taXNhbGlnbmVkL2dwLlMKQEAgLTAsMCArMSwxMTMgQEAKKy8qIFNQRFgtTGljZW5zZS1J ZGVudGlmaWVyOiBHUEwtMi4wLW9ubHkgKi8KKy8qCisgKiBDb3B5cmlnaHQgKGMpIDIwMjUgUml2 b3MgSW5jLgorICoKKyAqIEF1dGhvcnM6CisgKiAgICAgQ2zDqW1lbnQgTMOpZ2VyIDxjbGVnZXJA cml2b3NpbmMuY29tPgorICovCisKKyNpbmNsdWRlICJjb21tb24uUyIKKworLnRleHQKKworLm1h Y3JvIF9fZ2VuX3Rlc3RfaW5zdCBpbnN0LCBzcmNfcmVnCisJXGluc3QgYTIsIDAoXHNyY19yZWcp CisJbW92ZSBhMCwgYTIKKy5lbmRtCisKKy5tYWNybyBnZW5fZnVuY19oZWFkZXIgZnVuY19uYW1l LCBydmMKKwkub3B0aW9uIGFyY2gsXHJ2YworCS5nbG9iYWwgdGVzdF9cZnVuY19uYW1lCisJdGVz dF9cZnVuY19uYW1lOgorLmVuZG0KKworLm1hY3JvIGdlbl90ZXN0X2luc3QgaW5zdAorCS5vcHRp b24gcHVzaAorCWdlbl9mdW5jX2hlYWRlciBcaW5zdCwgLWMKKwlfX2dlbl90ZXN0X2luc3QgXGlu c3QsIGEwCisJLm9wdGlvbiBwb3AKKwlyZXQKKy5lbmRtCisKKy5tYWNybyBnZW5fdGVzdF9sd3UK Kwkub3B0aW9uIHB1c2gKKwlnZW5fZnVuY19oZWFkZXIgbHd1LCAtYworCV9fZ2VuX3Rlc3RfaW5z dCBsd3UsIGEwCisJLm9wdGlvbiBwb3AKKwkjIFJJU0MtViBBQkkgc3RhdGVzIHRoYXQgQyBleHBl Y3QgYSBzaWduIGV4dGVuZGVkIDMyIGJpdHMgaW50ZWdlcgorCXNleHQudyBhMCwgYTAKKwlyZXQK Ky5lbmRtCisKKy5tYWNybyBfX2dlbl90ZXN0X2luc3RfYyBuYW1lLCBzcmNfcmVnCisJLm9wdGlv biBwdXNoCisJZ2VuX2Z1bmNfaGVhZGVyIGNfXG5hbWUsICtjCisJIF9fZ2VuX3Rlc3RfaW5zdCBj LlxuYW1lLCBcc3JjX3JlZworCS5vcHRpb24gcG9wCisJcmV0CisuZW5kbQorCisubWFjcm8gZ2Vu X3Rlc3RfaW5zdF9jIG5hbWUKKyAJX19nZW5fdGVzdF9pbnN0X2MgXG5hbWUsIGEwCisuZW5kbQor CisKKy5tYWNybyBnZW5fdGVzdF9pbnN0X2NfbGRzcAorCS5vcHRpb24gcHVzaAorCWdlbl9mdW5j X2hlYWRlciBjX2xkc3AsICtjCisJc3Bfc3RhY2tfcHJvbG9ndWUgYTEKKwljb3B5X2xvbmdfdG8g dDAsIGEwLCBzcAorCWMubGRzcCBhMCwgMChzcCkKKwlzcF9zdGFja19lcGlsb2d1ZSBhMQorCS5v cHRpb24gcG9wCisJcmV0CisuZW5kbQorCisubWFjcm8gbGJfc3Bfc2JfYTAgcmVnLCBvZmZzZXQK KwlsYl9zYiBccmVnLCBcb2Zmc2V0LCBzcCwgYTAKKy5lbmRtCisKKy5tYWNybyBnZW5fdGVzdF9p bnN0X2Nfc2RzcAorCS5vcHRpb24gcHVzaAorCWdlbl9mdW5jX2hlYWRlciBjX3Nkc3AsICtjCisJ LyogTWlzYWxpZ24gc3RhY2sgcG9pbnRlciAqLworCXNwX3N0YWNrX3Byb2xvZ3VlIGExCisJLyog TWlzYWxpZ24gYWNjZXNzICovCisJYy5zZHNwIGEyLCAwKHNwKQorCWNvcHlfbG9uZ190byB0MCwg c3AsIGEwCisJc3Bfc3RhY2tfZXBpbG9ndWUgYTEKKwkub3B0aW9uIHBvcAorCXJldAorLmVuZG0K KworCisgLyoKKyAqIGEwID0gYWRkciB0byBsb2FkIGZyb20KKyAqIGExID0gYWRkcmVzcyBvZmZz ZXQKKyAqIGEyID0gdmFsdWUgdG8gYmUgbG9hZGVkCisgKi8KK2dlbl90ZXN0X2luc3QgbGgKK2dl bl90ZXN0X2luc3QgbGh1CitnZW5fdGVzdF9pbnN0IGx3CitnZW5fdGVzdF9sd3UKK2dlbl90ZXN0 X2luc3QgbGQKKyNpZmRlZiBfX3Jpc2N2X2NvbXByZXNzZWQKK2dlbl90ZXN0X2luc3RfYyBsdwor Z2VuX3Rlc3RfaW5zdF9jIGxkCitnZW5fdGVzdF9pbnN0X2NfbGRzcAorI2VuZGlmCisKKy8qCisg KiBhMCA9IGFkZHIgd2hlcmUgdG8gc3RvcmUgdmFsdWUKKyAqIGExID0gYWRkcmVzcyBvZmZzZXQK KyAqIGEyID0gdmFsdWUgdG8gYmUgc3RvcmVkCisgKi8KK2dlbl90ZXN0X2luc3Qgc2gKK2dlbl90 ZXN0X2luc3Qgc3cKK2dlbl90ZXN0X2luc3Qgc2QKKyNpZmRlZiBfX3Jpc2N2X2NvbXByZXNzZWQK K2dlbl90ZXN0X2luc3RfYyBzdworZ2VuX3Rlc3RfaW5zdF9jIHNkCitnZW5fdGVzdF9pbnN0X2Nf c2RzcAorI2VuZGlmCisKZGlmZiAtLWdpdCBhL3Rvb2xzL3Rlc3Rpbmcvc2VsZnRlc3RzL3Jpc2N2 L21pc2FsaWduZWQvbWlzYWxpZ25lZC5jIGIvdG9vbHMvdGVzdGluZy9zZWxmdGVzdHMvcmlzY3Yv bWlzYWxpZ25lZC9taXNhbGlnbmVkLmMKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAw MDAwMDAwLi41N2RkY2JkYzk0N2MKLS0tIC9kZXYvbnVsbAorKysgYi90b29scy90ZXN0aW5nL3Nl bGZ0ZXN0cy9yaXNjdi9taXNhbGlnbmVkL21pc2FsaWduZWQuYwpAQCAtMCwwICsxLDI4OCBAQAor Ly8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEdQTC0yLjAKKy8qCisgKiBDb3B5cmlnaHQgKGMp IDIwMjUgUml2b3MgSW5jLgorICoKKyAqIEF1dGhvcnM6CisgKiAgICAgQ2zDqW1lbnQgTMOpZ2Vy IDxjbGVnZXJAcml2b3NpbmMuY29tPgorICovCisjaW5jbHVkZSA8c2lnbmFsLmg+CisjaW5jbHVk ZSA8c3RkaW8uaD4KKyNpbmNsdWRlIDxzdGRsaWIuaD4KKyNpbmNsdWRlIDxsaW51eC9wdHJhY2Uu aD4KKyNpbmNsdWRlICIuLi8uLi9rc2VsZnRlc3RfaGFybmVzcy5oIgorCisjaW5jbHVkZSA8c3Rk bGliLmg+CisjaW5jbHVkZSA8c3RkaW8uaD4KKyNpbmNsdWRlIDxzdGRpbnQuaD4KKyNpbmNsdWRl IDxmbG9hdC5oPgorI2luY2x1ZGUgPGVycm5vLmg+CisjaW5jbHVkZSA8bWF0aC5oPgorI2luY2x1 ZGUgPHN0cmluZy5oPgorI2luY2x1ZGUgPHNpZ25hbC5oPgorI2luY2x1ZGUgPHN0ZGJvb2wuaD4K KyNpbmNsdWRlIDx1bmlzdGQuaD4KKyNpbmNsdWRlIDxpbnR0eXBlcy5oPgorI2luY2x1ZGUgPHVj b250ZXh0Lmg+CisKKyNpbmNsdWRlIDxzeXMvcHJjdGwuaD4KKworI2RlZmluZSBzdHJpbmdpZnko cykgX19zdHJpbmdpZnkocykKKyNkZWZpbmUgX19zdHJpbmdpZnkocykgI3MKKworI2RlZmluZSBV OF9NQVgJCSgodTgpfjBVKQorI2RlZmluZSBTOF9NQVgJCSgoczgpKFU4X01BWCA+PiAxKSkKKyNk ZWZpbmUgUzhfTUlOCQkoKHM4KSgtUzhfTUFYIC0gMSkpCisjZGVmaW5lIFUxNl9NQVgJCSgodTE2 KX4wVSkKKyNkZWZpbmUgUzE2X01BWAkJKChzMTYpKFUxNl9NQVggPj4gMSkpCisjZGVmaW5lIFMx Nl9NSU4JCSgoczE2KSgtUzE2X01BWCAtIDEpKQorI2RlZmluZSBVMzJfTUFYCQkoKHUzMil+MFUp CisjZGVmaW5lIFUzMl9NSU4JCSgodTMyKTApCisjZGVmaW5lIFMzMl9NQVgJCSgoczMyKShVMzJf TUFYID4+IDEpKQorI2RlZmluZSBTMzJfTUlOCQkoKHMzMikoLVMzMl9NQVggLSAxKSkKKyNkZWZp bmUgVTY0X01BWAkJKCh1NjQpfjBVTEwpCisjZGVmaW5lIFM2NF9NQVgJCSgoczY0KShVNjRfTUFY ID4+IDEpKQorI2RlZmluZSBTNjRfTUlOCQkoKHM2NCkoLVM2NF9NQVggLSAxKSkKKworI2RlZmlu ZSBpbnQxNl9URVNUX1ZBTFVFUwl7UzE2X01JTiwgUzE2X01JTi8yLCAtMSwgMSwgUzE2X01BWC8y LCBTMTZfTUFYfQorI2RlZmluZSBpbnQzMl9URVNUX1ZBTFVFUwl7UzMyX01JTiwgUzMyX01JTi8y LCAtMSwgMSwgUzMyX01BWC8yLCBTMzJfTUFYfQorI2RlZmluZSBpbnQ2NF9URVNUX1ZBTFVFUwl7 UzY0X01JTiwgUzY0X01JTi8yLCAtMSwgMSwgUzY0X01BWC8yLCBTNjRfTUFYfQorI2RlZmluZSB1 aW50MTZfVEVTVF9WQUxVRVMJezAsIFUxNl9NQVgvMiwgVTE2X01BWH0KKyNkZWZpbmUgdWludDMy X1RFU1RfVkFMVUVTCXswLCBVMzJfTUFYLzIsIFUzMl9NQVh9CisKKyNkZWZpbmUgZmxvYXRfVEVT VF9WQUxVRVMJe0ZMVF9NSU4sIEZMVF9NSU4vMiwgRkxUX01BWC8yLCBGTFRfTUFYfQorI2RlZmlu ZSBkb3VibGVfVEVTVF9WQUxVRVMJe0RCTF9NSU4sIERCTF9NSU4vMiwgREJMX01BWC8yLCBEQkxf TUFYfQorCitzdGF0aWMgYm9vbCBmbG9hdF9lcXVhbChmbG9hdCBhLCBmbG9hdCBiKQoreworCWZs b2F0IHNjYWxlZF9lcHNpbG9uOworCWZsb2F0IGRpZmZlcmVuY2UgPSBmYWJzZihhIC0gYik7CisK KwkvLyBTY2FsZSB0byB0aGUgbGFyZ2VzdCB2YWx1ZS4KKwlhID0gZmFic2YoYSk7CisJYiA9IGZh YnNmKGIpOworCWlmIChhID4gYikKKwkJc2NhbGVkX2Vwc2lsb24gPSBGTFRfRVBTSUxPTiAqIGE7 CisJZWxzZQorCQlzY2FsZWRfZXBzaWxvbiA9IEZMVF9FUFNJTE9OICogYjsKKworCXJldHVybiBk aWZmZXJlbmNlIDw9IHNjYWxlZF9lcHNpbG9uOworfQorCitzdGF0aWMgYm9vbCBkb3VibGVfZXF1 YWwoZG91YmxlIGEsIGRvdWJsZSBiKQoreworCWRvdWJsZSBzY2FsZWRfZXBzaWxvbjsKKwlkb3Vi bGUgZGlmZmVyZW5jZSA9IGZhYnNsKGEgLSBiKTsKKworCS8vIFNjYWxlIHRvIHRoZSBsYXJnZXN0 IHZhbHVlLgorCWEgPSBmYWJzKGEpOworCWIgPSBmYWJzKGIpOworCWlmIChhID4gYikKKwkJc2Nh bGVkX2Vwc2lsb24gPSBEQkxfRVBTSUxPTiAqIGE7CisJZWxzZQorCQlzY2FsZWRfZXBzaWxvbiA9 IERCTF9FUFNJTE9OICogYjsKKworCXJldHVybiBkaWZmZXJlbmNlIDw9IHNjYWxlZF9lcHNpbG9u OworfQorCisjZGVmaW5lIGZwdV9sb2FkX3Byb3RvKF9faW5zdCwgX190eXBlKSBcCitleHRlcm4g X190eXBlIHRlc3RfICMjIF9faW5zdCh1bnNpZ25lZCBsb25nIGZwX3JlZywgdm9pZCAqYWRkciwg dW5zaWduZWQgbG9uZyBvZmZzZXQsIF9fdHlwZSB2YWx1ZSkKKworZnB1X2xvYWRfcHJvdG8oZmx3 LCBmbG9hdCk7CitmcHVfbG9hZF9wcm90byhmbGQsIGRvdWJsZSk7CitmcHVfbG9hZF9wcm90byhj X2ZsdywgZmxvYXQpOworZnB1X2xvYWRfcHJvdG8oY19mbGQsIGRvdWJsZSk7CitmcHVfbG9hZF9w cm90byhjX2ZsZHNwLCBkb3VibGUpOworCisjZGVmaW5lIGZwdV9zdG9yZV9wcm90byhfX2luc3Qs IF9fdHlwZSkgXAorZXh0ZXJuIHZvaWQgdGVzdF8gIyMgX19pbnN0KHVuc2lnbmVkIGxvbmcgZnBf cmVnLCB2b2lkICphZGRyLCB1bnNpZ25lZCBsb25nIG9mZnNldCwgX190eXBlIHZhbHVlKQorCitm cHVfc3RvcmVfcHJvdG8oZnN3LCBmbG9hdCk7CitmcHVfc3RvcmVfcHJvdG8oZnNkLCBkb3VibGUp OworZnB1X3N0b3JlX3Byb3RvKGNfZnN3LCBmbG9hdCk7CitmcHVfc3RvcmVfcHJvdG8oY19mc2Qs IGRvdWJsZSk7CitmcHVfc3RvcmVfcHJvdG8oY19mc2RzcCwgZG91YmxlKTsKKworI2RlZmluZSBn cF9sb2FkX3Byb3RvKF9faW5zdCwgX190eXBlKSBcCitleHRlcm4gX190eXBlIHRlc3RfICMjIF9f aW5zdCh2b2lkICphZGRyLCB1bnNpZ25lZCBsb25nIG9mZnNldCwgX190eXBlIHZhbHVlKQorCitn cF9sb2FkX3Byb3RvKGxoLCBpbnQxNl90KTsKK2dwX2xvYWRfcHJvdG8obGh1LCB1aW50MTZfdCk7 CitncF9sb2FkX3Byb3RvKGx3LCBpbnQzMl90KTsKK2dwX2xvYWRfcHJvdG8obHd1LCB1aW50MzJf dCk7CitncF9sb2FkX3Byb3RvKGxkLCBpbnQ2NF90KTsKK2dwX2xvYWRfcHJvdG8oY19sdywgaW50 MzJfdCk7CitncF9sb2FkX3Byb3RvKGNfbGQsIGludDY0X3QpOworZ3BfbG9hZF9wcm90byhjX2xk c3AsIGludDY0X3QpOworCisjZGVmaW5lIGdwX3N0b3JlX3Byb3RvKF9faW5zdCwgX190eXBlKSBc CitleHRlcm4gdm9pZCB0ZXN0XyAjIyBfX2luc3Qodm9pZCAqYWRkciwgdW5zaWduZWQgbG9uZyBv ZmZzZXQsIF9fdHlwZSB2YWx1ZSkKKworZ3Bfc3RvcmVfcHJvdG8oc2gsIGludDE2X3QpOworZ3Bf c3RvcmVfcHJvdG8oc3csIGludDMyX3QpOworZ3Bfc3RvcmVfcHJvdG8oc2QsIGludDY0X3QpOwor Z3Bfc3RvcmVfcHJvdG8oY19zdywgaW50MzJfdCk7CitncF9zdG9yZV9wcm90byhjX3NkLCBpbnQ2 NF90KTsKK2dwX3N0b3JlX3Byb3RvKGNfc2RzcCwgaW50NjRfdCk7CisKKyNkZWZpbmUgVEVTVF9H UF9MT0FEKF9faW5zdCwgX190eXBlX3NpemUsIF9fdHlwZSkJCQkJCVwKK1RFU1QoZ3BfbG9hZF8g IyMgX19pbnN0KQkJCQkJCQkJXAorewkJCQkJCQkJCQkJXAorCWludCBvZmZzZXQsIHJldCwgdmFs X2k7CQkJCQkJCQlcCisJdWludDhfdCBidWZbMTZdIF9fYXR0cmlidXRlX18oKGFsaWduZWQoMTYp KSk7CQkJCQlcCisJX190eXBlICMjIF9fdHlwZV9zaXplICMjIF90IHRlc3RfdmFsW10gPSBfX3R5 cGUgIyMgX190eXBlX3NpemUgIyMgX1RFU1RfVkFMVUVTOwlcCisJCQkJCQkJCQkJCVwKKwlyZXQg PSBwcmN0bChQUl9TRVRfVU5BTElHTiwgUFJfVU5BTElHTl9OT1BSSU5UKTsJCQkJXAorCUFTU0VS VF9FUShyZXQsIDApOwkJCQkJCQkJXAorCQkJCQkJCQkJCQlcCisJZm9yIChvZmZzZXQgPSAxOyBv ZmZzZXQgPCAoX190eXBlX3NpemUpIC8gODsgb2Zmc2V0KyspIHsJCQlcCisJCWZvciAodmFsX2kg PSAwOyB2YWxfaSA8IEFSUkFZX1NJWkUodGVzdF92YWwpOyB2YWxfaSsrKSB7CQlcCisJCQlfX3R5 cGUgIyMgX190eXBlX3NpemUgIyMgX3QgcmVmX3ZhbCA9IHRlc3RfdmFsW3ZhbF9pXTsJCVwKKwkJ CV9fdHlwZSAjIyBfX3R5cGVfc2l6ZSAjIyBfdCAqcHRyID0JCQkJXAorCQkJCQkoX190eXBlICMj IF9fdHlwZV9zaXplICMjIF90ICopKGJ1ZiArIG9mZnNldCk7CVwKKwkJCW1lbWNweShwdHIsICZy ZWZfdmFsLCBzaXplb2YocmVmX3ZhbCkpOwkJCQlcCisJCQlfX3R5cGUgIyMgX190eXBlX3NpemUg IyMgX3QgdmFsID0JCQkJXAorCQkJCQkJdGVzdF8gIyMgX19pbnN0KHB0ciwgb2Zmc2V0LCByZWZf dmFsKTsJXAorCQkJRVhQRUNUX0VRKHJlZl92YWwsIHZhbCk7CQkJCQlcCisJCX0JCQkJCQkJCQlc CisJfQkJCQkJCQkJCQlcCit9CisKK1RFU1RfR1BfTE9BRChsaCwgMTYsIGludCkKK1RFU1RfR1Bf TE9BRChsaHUsIDE2LCB1aW50KQorVEVTVF9HUF9MT0FEKGx3LCAzMiwgaW50KQorVEVTVF9HUF9M T0FEKGx3dSwgMzIsIHVpbnQpCitURVNUX0dQX0xPQUQobGQsIDY0LCBpbnQpCisjaWZkZWYgX19y aXNjdl9jb21wcmVzc2VkCitURVNUX0dQX0xPQUQoY19sdywgMzIsIGludCkKK1RFU1RfR1BfTE9B RChjX2xkLCA2NCwgaW50KQorVEVTVF9HUF9MT0FEKGNfbGRzcCwgNjQsIGludCkKKyNlbmRpZgor CisjZGVmaW5lIFRFU1RfR1BfU1RPUkUoX19pbnN0LCBfX3R5cGVfc2l6ZSwgX190eXBlKQkJCQlc CitURVNUKGdwX3N0b3JlXyAjIyBfX2luc3QpCQkJCQkJCVwKK3sJCQkJCQkJCQkJXAorCWludCBv ZmZzZXQsIHJldCwgdmFsX2k7CQkJCQkJCVwKKwl1aW50OF90IGJ1ZlsxNl0gX19hdHRyaWJ1dGVf XygoYWxpZ25lZCgxNikpKTsJCQkJXAorCV9fdHlwZSAjIyBfX3R5cGVfc2l6ZSAjIyBfdCB0ZXN0 X3ZhbFtdID0JCQkJXAorCQkJCQlfX3R5cGUgIyMgX190eXBlX3NpemUgIyMgX1RFU1RfVkFMVUVT OwlcCisJCQkJCQkJCQkJXAorCXJldCA9IHByY3RsKFBSX1NFVF9VTkFMSUdOLCBQUl9VTkFMSUdO X05PUFJJTlQpOwkJCVwKKwlBU1NFUlRfRVEocmV0LCAwKTsJCQkJCQkJXAorCQkJCQkJCQkJCVwK Kwlmb3IgKHZhbF9pID0gMDsgdmFsX2kgPCBBUlJBWV9TSVpFKHRlc3RfdmFsKTsgdmFsX2krKykg ewkJXAorCQlfX3R5cGUgIyMgX190eXBlX3NpemUgIyMgX3QgcmVmX3ZhbCA9IHRlc3RfdmFsW3Zh bF9pXTsJCVwKKwkJZm9yIChvZmZzZXQgPSAxOyBvZmZzZXQgPCAoX190eXBlX3NpemUpIC8gODsg b2Zmc2V0KyspIHsJXAorCQkJX190eXBlICMjIF9fdHlwZV9zaXplICMjIF90IHZhbCA9IHJlZl92 YWw7CQlcCisJCQlfX3R5cGUgIyMgX190eXBlX3NpemUgIyMgX3QgKnB0ciA9CQkJXAorCQkJCSAo X190eXBlICMjIF9fdHlwZV9zaXplICMjIF90ICopKGJ1ZiArIG9mZnNldCk7IFwKKwkJCW1lbXNl dChwdHIsIDAsIHNpemVvZih2YWwpKTsJCQkJXAorCQkJdGVzdF8gIyMgX19pbnN0KHB0ciwgb2Zm c2V0LCB2YWwpOwkJCVwKKwkJCW1lbWNweSgmdmFsLCBwdHIsIHNpemVvZih2YWwpKTsJCQkJXAor CQkJRVhQRUNUX0VRKHJlZl92YWwsIHZhbCk7CQkJCVwKKwkJfQkJCQkJCQkJXAorCX0JCQkJCQkJ CQlcCit9CisKK1RFU1RfR1BfU1RPUkUoc2gsIDE2LCBpbnQpCitURVNUX0dQX1NUT1JFKHN3LCAz MiwgaW50KQorVEVTVF9HUF9TVE9SRShzZCwgNjQsIGludCkKKyNpZmRlZiBfX3Jpc2N2X2NvbXBy ZXNzZWQKK1RFU1RfR1BfU1RPUkUoY19zdywgMzIsIGludCkKK1RFU1RfR1BfU1RPUkUoY19zZCwg NjQsIGludCkKK1RFU1RfR1BfU1RPUkUoY19zZHNwLCA2NCwgaW50KQorI2VuZGlmCisKKyNkZWZp bmUgX19URVNUX0ZQVV9MT0FEKF9fdHlwZSwgX19pbnN0LCBfX3JlZ19zdGFydCwgX19yZWdfZW5k KQkJCQkJXAorVEVTVChmcHVfbG9hZF8gIyMgX19pbnN0KQkJCQkJCQkJCVwKK3sJCQkJCQkJCQkJ CQlcCisJaW50IHJldCwgb2Zmc2V0LCBmcF9yZWcsIHZhbF9pOwkJCQkJCQkJXAorCXVpbnQ4X3Qg YnVmWzE2XSBfX2F0dHJpYnV0ZV9fKChhbGlnbmVkKDE2KSkpOwkJCQkJCVwKKwlfX3R5cGUgdGVz dF92YWxbXSA9IF9fdHlwZSAjIyBfVEVTVF9WQUxVRVM7CQkJCQkJXAorCQkJCQkJCQkJCQkJXAor CXJldCA9IHByY3RsKFBSX1NFVF9VTkFMSUdOLCBQUl9VTkFMSUdOX05PUFJJTlQpOwkJCQkJXAor CUFTU0VSVF9FUShyZXQsIDApOwkJCQkJCQkJCVwKKwkJCQkJCQkJCQkJCVwKKwlmb3IgKGZwX3Jl ZyA9IF9fcmVnX3N0YXJ0OyBmcF9yZWcgPCBfX3JlZ19lbmQ7IGZwX3JlZysrKSB7CQkJCVwKKwkJ Zm9yIChvZmZzZXQgPSAxOyBvZmZzZXQgPCA0OyBvZmZzZXQrKykgewkJCQkJXAorCQkJZm9yICh2 YWxfaSA9IDA7IHZhbF9pIDwgQVJSQVlfU0laRSh0ZXN0X3ZhbCk7IHZhbF9pKyspIHsJCVwKKwkJ CQlfX3R5cGUgdmFsLCByZWZfdmFsID0gdGVzdF92YWxbdmFsX2ldOwkJCQlcCisJCQkJdm9pZCAq bG9hZF9hZGRyID0gKGJ1ZiArIG9mZnNldCk7CQkJCVwKKwkJCQkJCQkJCQkJCVwKKwkJCQltZW1j cHkobG9hZF9hZGRyLCAmcmVmX3ZhbCwgc2l6ZW9mKHJlZl92YWwpKTsJCQlcCisJCQkJdmFsID0g dGVzdF8gIyMgX19pbnN0KGZwX3JlZywgbG9hZF9hZGRyLCBvZmZzZXQsIHJlZl92YWwpOwlcCisJ CQkJRVhQRUNUX1RSVUUoX190eXBlICMjX2VxdWFsKHZhbCwgcmVmX3ZhbCkpOwkJCVwKKwkJCX0J CQkJCQkJCQlcCisJCX0JCQkJCQkJCQkJXAorCX0JCQkJCQkJCQkJCVwKK30KKworI2RlZmluZSBU RVNUX0ZQVV9MT0FEKF9fdHlwZSwgX19pbnN0KSBcCisJX19URVNUX0ZQVV9MT0FEKF9fdHlwZSwg X19pbnN0LCAwLCAzMikKKyNkZWZpbmUgVEVTVF9GUFVfTE9BRF9DT01QUkVTU0VEKF9fdHlwZSwg X19pbnN0KSBcCisJX19URVNUX0ZQVV9MT0FEKF9fdHlwZSwgX19pbnN0LCA4LCAxNikKKworVEVT VF9GUFVfTE9BRChmbG9hdCwgZmx3KQorVEVTVF9GUFVfTE9BRChkb3VibGUsIGZsZCkKKyNpZmRl ZiBfX3Jpc2N2X2NvbXByZXNzZWQKK1RFU1RfRlBVX0xPQURfQ09NUFJFU1NFRChkb3VibGUsIGNf ZmxkKQorVEVTVF9GUFVfTE9BRF9DT01QUkVTU0VEKGRvdWJsZSwgY19mbGRzcCkKKyNlbmRpZgor CisjZGVmaW5lIF9fVEVTVF9GUFVfU1RPUkUoX190eXBlLCBfX2luc3QsIF9fcmVnX3N0YXJ0LCBf X3JlZ19lbmQpCQkJXAorVEVTVChmcHVfc3RvcmVfICMjIF9faW5zdCkJCQkJCQkJCVwKK3sJCQkJ CQkJCQkJCVwKKwlpbnQgcmV0LCBvZmZzZXQsIGZwX3JlZywgdmFsX2k7CQkJCQkJCVwKKwl1aW50 OF90IGJ1ZlsxNl0gX19hdHRyaWJ1dGVfXygoYWxpZ25lZCgxNikpKTsJCQkJCVwKKwlfX3R5cGUg dGVzdF92YWxbXSA9IF9fdHlwZSAjIyBfVEVTVF9WQUxVRVM7CQkJCQlcCisJCQkJCQkJCQkJCVwK KwlyZXQgPSBwcmN0bChQUl9TRVRfVU5BTElHTiwgUFJfVU5BTElHTl9OT1BSSU5UKTsJCQkJXAor CUFTU0VSVF9FUShyZXQsIDApOwkJCQkJCQkJXAorCQkJCQkJCQkJCQlcCisJZm9yIChmcF9yZWcg PSBfX3JlZ19zdGFydDsgZnBfcmVnIDwgX19yZWdfZW5kOyBmcF9yZWcrKykgewkJCVwKKwkJZm9y IChvZmZzZXQgPSAxOyBvZmZzZXQgPCA0OyBvZmZzZXQrKykgewkJCQlcCisJCQlmb3IgKHZhbF9p ID0gMDsgdmFsX2kgPCBBUlJBWV9TSVpFKHRlc3RfdmFsKTsgdmFsX2krKykgewlcCisJCQkJX190 eXBlIHZhbCwgcmVmX3ZhbCA9IHRlc3RfdmFsW3ZhbF9pXTsJCQlcCisJCQkJCQkJCQkJCVwKKwkJ CQl2b2lkICpzdG9yZV9hZGRyID0gKGJ1ZiArIG9mZnNldCk7CQkJXAorCQkJCQkJCQkJCQlcCisJ CQkJdGVzdF8gIyMgX19pbnN0KGZwX3JlZywgc3RvcmVfYWRkciwgb2Zmc2V0LCByZWZfdmFsKTsJ XAorCQkJCW1lbWNweSgmdmFsLCBzdG9yZV9hZGRyLCBzaXplb2YodmFsKSk7CQkJXAorCQkJCUVY UEVDVF9UUlVFKF9fdHlwZSAjIyBfZXF1YWwodmFsLCByZWZfdmFsKSk7CQlcCisJCQl9CQkJCQkJ CQlcCisJCX0JCQkJCQkJCQlcCisJfQkJCQkJCQkJCQlcCit9CisjZGVmaW5lIFRFU1RfRlBVX1NU T1JFKF9fdHlwZSwgX19pbnN0KSBcCisJX19URVNUX0ZQVV9TVE9SRShfX3R5cGUsIF9faW5zdCwg MCwgMzIpCisjZGVmaW5lIFRFU1RfRlBVX1NUT1JFX0NPTVBSRVNTRUQoX190eXBlLCBfX2luc3Qp IFwKKwlfX1RFU1RfRlBVX1NUT1JFKF9fdHlwZSwgX19pbnN0LCA4LCAxNikKKworVEVTVF9GUFVf U1RPUkUoZmxvYXQsIGZzdykKK1RFU1RfRlBVX1NUT1JFKGRvdWJsZSwgZnNkKQorI2lmZGVmIF9f cmlzY3ZfY29tcHJlc3NlZAorVEVTVF9GUFVfU1RPUkVfQ09NUFJFU1NFRChkb3VibGUsIGNfZnNk KQorVEVTVF9GUFVfU1RPUkVfQ09NUFJFU1NFRChkb3VibGUsIGNfZnNkc3ApCisjZW5kaWYKKwor VEVTVF9TSUdOQUwoZ2VuX3NpZ2J1cywgU0lHQlVTKQoreworCXVpbnQzMl90IHZhbCA9IDB4REVB REJFRUY7CisJdWludDhfdCBidWZbMTZdIF9fYXR0cmlidXRlX18oKGFsaWduZWQoMTYpKSk7CisJ aW50IHJldDsKKworCXJldCA9IHByY3RsKFBSX1NFVF9VTkFMSUdOLCBQUl9VTkFMSUdOX1NJR0JV Uyk7CisJQVNTRVJUX0VRKHJldCwgMCk7CisKKwlhc20gdm9sYXRpbGUoInN3ICUwLCAxKCUxKSIg OiA6ICJyIih2YWwpLCAiciIoYnVmKSA6ICJtZW1vcnkiKTsKK30KKworaW50IG1haW4oaW50IGFy Z2MsIGNoYXIgKiphcmd2KQoreworCWludCByZXQsIHZhbDsKKworCXJldCA9IHByY3RsKFBSX0dF VF9VTkFMSUdOLCAmdmFsKTsKKwlpZiAocmV0ID09IC0xICYmIGVycm5vID09IEVJTlZBTCkKKwkJ a3NmdF9leGl0X3NraXAoIlNLSVAgR0VUX1VOQUxJR05fQ1RMIG5vdCBzdXBwb3J0ZWRcbiIpOwor CisJZXhpdCh0ZXN0X2hhcm5lc3NfcnVuKGFyZ2MsIGFyZ3YpKTsKK30KLS0gCjIuNDMuMAoKCl9f X19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fCmxpbnV4LXJpc2N2 IG1haWxpbmcgbGlzdApsaW51eC1yaXNjdkBsaXN0cy5pbmZyYWRlYWQub3JnCmh0dHA6Ly9saXN0 cy5pbmZyYWRlYWQub3JnL21haWxtYW4vbGlzdGluZm8vbGludXgtcmlzY3YK