[PATCH] windows on arm support
coshvji cujmlqef <[email protected]> Sun, 2 Aug 2026 20:23:53 +0800
| Newsgroups | gmane.comp.gnu.binutils |
|---|---|
| Message-ID | <CAJkdwqHNDCjW3BYd7+auC==nE3ir74gQZNDb_qC-i0O0vbZahQ@mail.gmail.com> |
--000000000000038c3b06580f7f8d Content-Type: multipart/alternative; boundary="000000000000038c3a06580f7f8b" --000000000000038c3a06580f7f8b Content-Type: text/plain; charset="UTF-8" From 776ee433b5cd3d74d43cb3ff006e484583f7beff Mon Sep 17 00:00:00 2001 From: trcrsired <[email protected]> Date: Thu, 30 Jul 2026 16:06:12 +0800 Subject: [PATCH] gas: Add AArch64 Windows SEH (pdata/xdata) support Implement Windows exception-handling (SEH) unwind info generation for the aarch64-w64-mingw32 target in GAS. The existing obj-coff-seh.c only handled x64. This adds full AArch64 support: * .seh_proc/.seh_endprologue and all AArch64 unwind directives (.seh_alloc_stack, .seh_save_fplr/x, .seh_save_reg/p/p_x, .seh_save_freg/p/p_x, .seh_save_lrpair, .seh_set_fp, .seh_add_fp, .seh_handler, etc.) * Correct xdata header layout (FunctionLength / CodeWords / EpilogCount / E / X bits) matching the MS ARM64 format * Emit the xdata extension word when CodeWords==0 and EpilogCount==0 so Windows exception parsers do not misread the next entry * Correct opcode encodings for register save pairs (save_regp etc.) * Function length computed from fragment positions instead of resolve_expression, which failed across fragments --- gas/config/obj-coff-seh.c | 884 ++++++++++++++++++++++++++++++-------- gas/config/obj-coff-seh.h | 80 +++- 2 files changed, 791 insertions(+), 173 deletions(-) diff --git a/gas/config/obj-coff-seh.c b/gas/config/obj-coff-seh.c index 1ac64f8f9ba..113c7a9b2b6 100644 --- a/gas/config/obj-coff-seh.c +++ b/gas/config/obj-coff-seh.c @@ -43,6 +43,8 @@ seh_get_target_kind (void) switch (bfd_get_arch (stdoutput)) { case bfd_arch_aarch64: + return seh_kind_aarch64; + case bfd_arch_arm: case bfd_arch_powerpc: case bfd_arch_sh: @@ -176,7 +178,8 @@ obj_coff_seh_handler (int what ATTRIBUTE_UNUSED) if (!skip_whitespace_and_comma (0)) return; - if (seh_get_target_kind () == seh_kind_x64) + if (seh_get_target_kind () == seh_kind_x64 + || seh_get_target_kind () == seh_kind_aarch64) { do { @@ -208,7 +211,7 @@ obj_coff_seh_handler (int what ATTRIBUTE_UNUSED) static void obj_coff_seh_handlerdata (int what ATTRIBUTE_UNUSED) { - if (!verify_context_and_target (".seh_handlerdata", seh_kind_x64)) + if (!verify_context_and_target (".seh_handlerdata", seh_get_target_kind ())) return; demand_empty_rest_of_line (); @@ -217,6 +220,46 @@ obj_coff_seh_handlerdata (int what ATTRIBUTE_UNUSED) /* Mark end of current context. */ +static void +out_one (int byte) +{ + char *p = frag_more (1); + md_number_to_chars (p, byte, 1); +} + +static void +out_two (int data) +{ + char *p = frag_more (2); + md_number_to_chars (p, data, 2); +} + +static void +out_four (int data) +{ + char *p = frag_more (4); + md_number_to_chars (p, data, 4); +} + +/* Write xdata for an x64 function (passthrough to existing + xdata output via prologue elements). */ + +static void +seh_x64_write_function_xdata (seh_context *c ATTRIBUTE_UNUSED) +{ + /* The x64 xdata is already emitted incrementally as prologue + elements are processed; this function is a no-op placeholder + for consistency with the aarch64 dispatch. */ +} + +/* Write pdata for an ARM (WinCE-style) function (no-op stub). */ + +static void +seh_arm_write_function_pdata (seh_context *c ATTRIBUTE_UNUSED) +{ + abort (); +} + static void do_seh_endproc (void) { @@ -272,7 +315,8 @@ obj_coff_seh_proc (int what ATTRIBUTE_UNUSED) seh_ctx_cur->code_seg = now_seg; - if (seh_get_target_kind () == seh_kind_x64) + if (seh_get_target_kind () == seh_kind_x64 + || seh_get_target_kind () == seh_kind_aarch64) { x_segcur = seh_hash_find_or_make (seh_ctx_cur->code_seg, ".xdata"); seh_ctx_cur->subsection = x_segcur->subseg; @@ -565,176 +609,711 @@ obj_coff_seh_setframe (int what ATTRIBUTE_UNUSED) seh_x64_make_prologue_element (UWOP_SET_FPREG, 0, 0); } } - -/* Data writing routines. */ -/* Output raw integers in 1, 2, or 4 bytes. */ +/* AArch64 support. */ + +/* AArch64 register name tables. */ +static const char * const aarch64_int_regs[31] = { + "x0", "x1", "x2", "x3", "x4", "x5", "x6", "x7", + "x8", "x9", "x10", "x11", "x12", "x13", "x14", "x15", + "x16", "x17", "x18", "x19", "x20", "x21", "x22", "x23", + "x24", "x25", "x26", "x27", "x28", "x29", "x30" +}; + +static const char * const aarch64_fp_regs[32] = { + "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", + "d8", "d9", "d10", "d11", "d12", "d13", "d14", "d15", + "d16", "d17", "d18", "d19", "d20", "d21", "d22", "d23", + "d24", "d25", "d26", "d27", "d28", "d29", "d30", "d31" +}; + +/* Read an AArch64 integer register from input stream. + Returns the register number (0-30) or -1 on error. + Also accepts "fp" (x29) and "lr" (x30). */ +static int +seh_aarch64_read_int_reg (const char *directive, int min_reg, int max_reg) +{ + char name_end; + char *symbol_name; + int i; + + SKIP_WHITESPACE (); + name_end = get_symbol_name (&symbol_name); -static inline void -out_one (int byte) + /* Check for special names. */ + if (strcasecmp (symbol_name, "fp") == 0) + i = 29; + else if (strcasecmp (symbol_name, "lr") == 0) + i = 30; + else + { + for (i = 0; i < 31; i++) + if (!strcasecmp (aarch64_int_regs[i], symbol_name)) + break; + } + + (void) restore_line_pointer (name_end); + + if (i > max_reg || i < min_reg) + { + as_bad (_("invalid register for %s"), directive); + return -1; + } + + return i; +} + +/* Read an AArch64 FP/SIMD register from input stream. + Returns the register number (0-31) or -1 on error. */ +static int +seh_aarch64_read_fp_reg (const char *directive) { - FRAG_APPEND_1_CHAR (byte); + char name_end; + char *symbol_name; + int i; + + SKIP_WHITESPACE (); + name_end = get_symbol_name (&symbol_name); + + for (i = 0; i < 32; i++) + if (!strcasecmp (aarch64_fp_regs[i], symbol_name)) + break; + + (void) restore_line_pointer (name_end); + + if (i == 32) + { + as_bad (_("invalid floating-point register for %s"), directive); + return -1; + } + + return i; } -static inline void -out_two (int data) +/* Add a prologue element to the AArch64 SEH context. */ +static void +seh_aarch64_make_prologue_element (int code, int info, offsetT off) { - md_number_to_chars (frag_more (2), data, 2); + seh_prologue_element *n; + + if (seh_ctx_cur == NULL) + return; + if (seh_ctx_cur->elems_count == seh_ctx_cur->elems_max) + { + seh_ctx_cur->elems_max += 8; + seh_ctx_cur->elems = XRESIZEVEC (seh_prologue_element, + seh_ctx_cur->elems, + seh_ctx_cur->elems_max); + } + + n = &seh_ctx_cur->elems[seh_ctx_cur->elems_count++]; + n->code = code; + n->info = info; + n->off = off; + n->pc_addr = symbol_temp_new_now (); } -static inline void -out_four (int data) +/* .seh_save_regp <reg1>, <reg2>, <offset> (aarch64) + Save register pair at offset from SP. */ +static void +obj_coff_seh_aarch64_save_regp (int what ATTRIBUTE_UNUSED) { - md_number_to_chars (frag_more (4), data, 4); + int reg1, reg2; + offsetT off; + + if (!verify_context_and_target (".seh_save_regp", seh_kind_aarch64) + || !seh_validate_seg (".seh_save_regp")) + return; + + reg1 = seh_aarch64_read_int_reg (".seh_save_regp", 0, 30); + if (!skip_whitespace_and_comma (1)) + return; + reg2 = seh_aarch64_read_int_reg (".seh_save_regp", 0, 30); + if (!skip_whitespace_and_comma (1)) + return; + off = get_absolute_expression (); + demand_empty_rest_of_line (); + + if (reg1 < 0 || reg2 < 0) + return; + if (off < 0 || (off & 7)) + { + as_bad (_(".seh_save_regp offset must be non-negative and 8-byte aligned")); + return; + } + + /* Check for special case: saving x29,x30 (FPLR pair). */ + if (reg1 == 29 && reg2 == 30) + { + if (off <= 0x3F * 8) + { + seh_aarch64_make_prologue_element (AARCH64_UOP_SAVE_FPLR, off >> 3, 0); + return; + } + } + + seh_aarch64_make_prologue_element (AARCH64_UOP_SAVE_REG_P, reg1, off); } -/* Write out prologue data for x64. */ +/* .seh_save_fregp <reg1>, <reg2>, <offset> (aarch64) + Save FP/SIMD register pair. */ +static void +obj_coff_seh_aarch64_save_fregp (int what ATTRIBUTE_UNUSED) +{ + int reg1, reg2; + offsetT off; + + if (!verify_context_and_target (".seh_save_fregp", seh_kind_aarch64) + || !seh_validate_seg (".seh_save_fregp")) + return; + + reg1 = seh_aarch64_read_fp_reg (".seh_save_fregp"); + if (!skip_whitespace_and_comma (1)) + return; + reg2 = seh_aarch64_read_fp_reg (".seh_save_fregp"); + if (!skip_whitespace_and_comma (1)) + return; + off = get_absolute_expression (); + demand_empty_rest_of_line (); + + if (reg1 < 0 || reg2 < 0) + return; + if (off < 0 || (off & 7)) + { + as_bad (_(".seh_save_fregp offset must be non-negative and 8-byte aligned")); + return; + } + + seh_aarch64_make_prologue_element (AARCH64_UOP_SAVE_FREG_P, reg1, off); +} +/* .seh_save_reg <reg>, <offset> (aarch64) + Save a single integer register. */ static void -seh_x64_write_prologue_data (const seh_context *c) +obj_coff_seh_aarch64_save_reg (int what ATTRIBUTE_UNUSED) { - int i; + int reg; + offsetT off; - /* We have to store in reverse order. */ - for (i = c->elems_count - 1; i >= 0; --i) + if (!verify_context_and_target (".seh_save_reg", seh_kind_aarch64) + || !seh_validate_seg (".seh_save_reg")) + return; + + reg = seh_aarch64_read_int_reg (".seh_save_reg", 0, 30); + if (!skip_whitespace_and_comma (1)) + return; + off = get_absolute_expression (); + demand_empty_rest_of_line (); + + if (reg < 0) + return; + if (off < 0 || (off & 7)) { - const seh_prologue_element *e = c->elems + i; - expressionS exp; + as_bad (_(".seh_save_reg offset must be non-negative and 8-byte aligned")); + return; + } - /* First comes byte offset in code. */ - exp.X_op = O_subtract; - exp.X_add_symbol = e->pc_addr; - exp.X_op_symbol = c->start_addr; - exp.X_add_number = 0; - emit_expr (&exp, 1); + seh_aarch64_make_prologue_element (AARCH64_UOP_SAVE_REG, reg, off); +} - /* Second comes code+info packed into a byte. */ - out_one ((e->info << 4) | e->code); +/* .seh_save_freg <reg>, <offset> (aarch64) + Save a single FP/SIMD register. */ +static void +obj_coff_seh_aarch64_save_freg (int what ATTRIBUTE_UNUSED) +{ + int reg; + offsetT off; - switch (e->code) - { - case UWOP_PUSH_NONVOL: - case UWOP_ALLOC_SMALL: - case UWOP_SET_FPREG: - case UWOP_PUSH_MACHFRAME: - /* These have no extra data. */ - break; + if (!verify_context_and_target (".seh_save_freg", seh_kind_aarch64) + || !seh_validate_seg (".seh_save_freg")) + return; - case UWOP_ALLOC_LARGE: - if (e->info) - { - case UWOP_SAVE_NONVOL_FAR: - case UWOP_SAVE_XMM128_FAR: - /* An unscaled 4 byte offset. */ - out_four (e->off); - break; - } - /* FALLTHRU */ + reg = seh_aarch64_read_fp_reg (".seh_save_freg"); + if (!skip_whitespace_and_comma (1)) + return; + off = get_absolute_expression (); + demand_empty_rest_of_line (); - case UWOP_SAVE_NONVOL: - case UWOP_SAVE_XMM128: - /* A scaled 2 byte offset. */ - out_two (e->off); - break; + if (reg < 0) + return; + if (off < 0 || (off & 7)) + { + as_bad (_(".seh_save_freg offset must be non-negative and 8-byte aligned")); + return; + } - default: - abort (); - } + seh_aarch64_make_prologue_element (AARCH64_UOP_SAVE_FREG, reg, off); +} + +/* .seh_save_fplr <offset> (aarch64) + Save x29 (FP) and x30 (LR) at a positive offset from SP. */ +static void +obj_coff_seh_aarch64_save_fplr (int what ATTRIBUTE_UNUSED) +{ + offsetT off; + + if (!verify_context_and_target (".seh_save_fplr", seh_kind_aarch64) + || !seh_validate_seg (".seh_save_fplr")) + return; + + off = get_absolute_expression (); + demand_empty_rest_of_line (); + + if (off < 0 || (off & 7)) + { + as_bad (_(".seh_save_fplr offset must be non-negative and 8-byte aligned")); + return; } + + seh_aarch64_make_prologue_element (AARCH64_UOP_SAVE_FPLR, off >> 3, 0); } +/* .seh_save_fplr_x <offset> (aarch64) + Save x29 (FP) and x30 (LR) with predecrement (stp x29, x30, [sp, #-N]!). */ +static void +obj_coff_seh_aarch64_save_fplr_x (int what ATTRIBUTE_UNUSED) +{ + offsetT off; + + if (!verify_context_and_target (".seh_save_fplr_x", seh_kind_aarch64) + || !seh_validate_seg (".seh_save_fplr_x")) + return; + + off = get_absolute_expression (); + demand_empty_rest_of_line (); + + if (off < 0 || (off & 15)) + { + as_bad (_(".seh_save_fplr_x offset must be negative and 16-byte aligned")); + return; + } + if (off > 0x3F * 8) + { + as_bad (_(".seh_save_fplr_x offset out of range (max 504)")); + return; + } + + seh_aarch64_make_prologue_element (AARCH64_UOP_SAVE_FPLRX, (off >> 3) - 1, 0); +} + +/* .seh_save_lrpair <reg>, <offset> (aarch64) + Save x30 (LR) and another register at offset from SP. */ +static void +obj_coff_seh_aarch64_save_lrpair (int what ATTRIBUTE_UNUSED) +{ + int reg; + offsetT off; + + if (!verify_context_and_target (".seh_save_lrpair", seh_kind_aarch64) + || !seh_validate_seg (".seh_save_lrpair")) + return; + + reg = seh_aarch64_read_int_reg (".seh_save_lrpair", 0, 28); + if (!skip_whitespace_and_comma (1)) + return; + off = get_absolute_expression (); + demand_empty_rest_of_line (); + + if (reg < 0) + return; + if (off < 0 || (off & 7)) + { + as_bad (_(".seh_save_lrpair offset must be non-negative and 8-byte aligned")); + return; + } + + seh_aarch64_make_prologue_element (AARCH64_UOP_SAVE_LRPAIR, (reg - 19) >> 1, off >> 3); +} + +/* .seh_set_fp (aarch64) + Set frame pointer (mov x29, sp). */ +static void +obj_coff_seh_aarch64_set_fp (int what ATTRIBUTE_UNUSED) +{ + if (!verify_context_and_target (".seh_set_fp", seh_kind_aarch64) + || !seh_validate_seg (".seh_set_fp")) + return; + demand_empty_rest_of_line (); + + seh_aarch64_make_prologue_element (AARCH64_UOP_SET_FP, 0, 0); +} + +/* .seh_add_fp <offset> (aarch64) + Add offset to frame pointer (add x29, sp, #N). */ +static void +obj_coff_seh_aarch64_add_fp (int what ATTRIBUTE_UNUSED) +{ + offsetT off; + + if (!verify_context_and_target (".seh_add_fp", seh_kind_aarch64) + || !seh_validate_seg (".seh_add_fp")) + return; + + off = get_absolute_expression (); + demand_empty_rest_of_line (); + + seh_aarch64_make_prologue_element (AARCH64_UOP_ADD_FP, off >> 3, 0); +} + +/* .seh_nop (aarch64) + No-op padding in the unwind code. */ +static void +obj_coff_seh_aarch64_nop (int what ATTRIBUTE_UNUSED) +{ + if (!verify_context_and_target (".seh_nop", seh_kind_aarch64) + || !seh_validate_seg (".seh_nop")) + return; + demand_empty_rest_of_line (); + + seh_aarch64_make_prologue_element (AARCH64_UOP_NOP, 0, 0); +} + +/* .seh_alloc_stack <size> (aarch64) + Allocate stack space. */ +static void +obj_coff_seh_aarch64_alloc_stack (int what ATTRIBUTE_UNUSED) +{ + offsetT off; + int code, info; + + if (!verify_context_and_target (".seh_alloc_stack", seh_kind_aarch64) + || !seh_validate_seg (".seh_alloc_stack")) + return; + + off = get_absolute_expression (); + demand_empty_rest_of_line (); + + if (off == 0) + return; + if (off < 0) + { + as_bad (_(".seh_alloc_stack offset is negative")); + return; + } + + if ((off & 15) == 0 && off <= 0x1F * 16) + { + code = AARCH64_UOP_ALLOC_SMALL; + info = (off / 16) - 1; + } + else if ((off & 15) == 0 && off <= 0x7FF * 16) + { + code = AARCH64_UOP_ALLOC_MEDIUM; + info = off / 16; + } + else if ((off & 15) == 0 && off <= (offsetT) 0xFFFFFF * 16) + { + code = AARCH64_UOP_ALLOC_LARGE; + info = 0; + off = off / 16; + } + else + { + as_bad (_(".seh_alloc_stack offset out of range")); + return; + } + + seh_aarch64_make_prologue_element (code, info, off); +} + +/* AArch64 xdata writing. */ + +/* Count the size of AArch64 unwind code data in bytes. */ static int -seh_x64_size_prologue_data (const seh_context *c) +seh_aarch64_size_prologue_data (const seh_context *c) { int i, ret = 0; for (i = c->elems_count - 1; i >= 0; --i) - switch (c->elems[i].code) - { - case UWOP_PUSH_NONVOL: - case UWOP_ALLOC_SMALL: - case UWOP_SET_FPREG: - case UWOP_PUSH_MACHFRAME: + { + int code = c->elems[i].code; + if (code == AARCH64_UOP_ALLOC_SMALL + || code == AARCH64_UOP_SAVE_R19R20X + || code == AARCH64_UOP_SAVE_FPLRX + || code == AARCH64_UOP_SAVE_FPLR + || code == AARCH64_UOP_SET_FP + || code == AARCH64_UOP_NOP + || code == AARCH64_UOP_END + || code == AARCH64_UOP_SAVE_NEXT + || code == AARCH64_UOP_TRAP_FRAME + || code == AARCH64_UOP_PUSH_MACH + || code == AARCH64_UOP_CONTEXT + || code == AARCH64_UOP_EC_CONTEXT + || code == AARCH64_UOP_CLEAR_UNWOUND_TO_CALL + || code == AARCH64_UOP_PAC_SIGN_LR) ret += 1; - break; - - case UWOP_SAVE_NONVOL: - case UWOP_SAVE_XMM128: + else if (code == AARCH64_UOP_ALLOC_MEDIUM + || code == AARCH64_UOP_SAVE_REG + || code == AARCH64_UOP_SAVE_REG_X + || code == AARCH64_UOP_SAVE_REG_P + || code == AARCH64_UOP_SAVE_REG_PX + || code == AARCH64_UOP_SAVE_LRPAIR + || code == AARCH64_UOP_SAVE_FREG + || code == AARCH64_UOP_SAVE_FREG_X + || code == AARCH64_UOP_SAVE_FREG_P + || code == AARCH64_UOP_SAVE_FREG_PX + || code == AARCH64_UOP_ADD_FP) ret += 2; - break; - - case UWOP_SAVE_NONVOL_FAR: - case UWOP_SAVE_XMM128_FAR: + else if (code == AARCH64_UOP_ALLOC_LARGE + || code == AARCH64_UOP_SAVE_ANY_REG_I + || code == AARCH64_UOP_SAVE_ANY_REG_IP + || code == AARCH64_UOP_SAVE_ANY_REG_D + || code == AARCH64_UOP_SAVE_ANY_REG_DP + || code == AARCH64_UOP_SAVE_ANY_REG_Q + || code == AARCH64_UOP_SAVE_ANY_REG_QP) ret += 3; - break; - - case UWOP_ALLOC_LARGE: - ret += (c->elems[i].info ? 3 : 2); - break; - - default: + else abort (); - } + } return ret; } -/* Write out the xdata information for one function (x64). */ +/* Write out AArch64 prologue unwind codes. */ +static void +seh_aarch64_write_prologue_data (const seh_context *c) +{ + int i; + + /* We have to store in reverse order. */ + for (i = c->elems_count - 1; i >= 0; --i) + { + const seh_prologue_element *e = c->elems + i; + + switch (e->code) + { + case AARCH64_UOP_ALLOC_SMALL: + out_one (AARCH64_UOP_ALLOC_SMALL | (e->info & 0x1f)); + break; + + case AARCH64_UOP_ALLOC_MEDIUM: + out_one (AARCH64_UOP_ALLOC_MEDIUM | ((e->info >> 8) & 3)); + out_one (e->info & 0xff); + break; + + case AARCH64_UOP_ALLOC_LARGE: + out_one (AARCH64_UOP_ALLOC_LARGE); + out_two (e->off); + break; + + case AARCH64_UOP_SAVE_R19R20X: + out_one (AARCH64_UOP_SAVE_R19R20X | (e->info & 0x1f)); + break; + + case AARCH64_UOP_SAVE_FPLRX: + out_one (AARCH64_UOP_SAVE_FPLRX | (e->info & 0x3f)); + break; + + case AARCH64_UOP_SAVE_FPLR: + out_one (AARCH64_UOP_SAVE_FPLR | (e->info & 0x3f)); + break; + + case AARCH64_UOP_SAVE_REG: + { + int r = e->info - 19; + out_one (AARCH64_UOP_SAVE_REG | ((r & 0xC) >> 2)); + out_one (((r & 0x3) << 6) | ((e->off >> 3) & 0x3f)); + } + break; + + case AARCH64_UOP_SAVE_REG_X: + { + int r = e->info - 19; + out_one (AARCH64_UOP_SAVE_REG_X | ((r & 0x8) >> 3)); + out_one (((r & 0x7) << 5) | (((e->off >> 3) - 1) & 0x1f)); + } + break; + + case AARCH64_UOP_SAVE_REG_P: + { + int r = e->info - 19; + out_one (AARCH64_UOP_SAVE_REG_P | ((r & 0xC) >> 2)); + out_one (((r & 0x3) << 6) | ((e->off >> 3) & 0x3f)); + } + break; + + case AARCH64_UOP_SAVE_REG_PX: + { + int r = e->info - 19; + out_one (AARCH64_UOP_SAVE_REG_PX | ((r & 0xC) >> 2)); + out_one (((r & 0x3) << 6) | (((e->off >> 3) - 1) & 0x3f)); + } + break; + + case AARCH64_UOP_SAVE_LRPAIR: + { + int r = e->info - 19; + out_one (AARCH64_UOP_SAVE_LRPAIR | ((r & 0xC) >> 2)); + out_one (((r & 0x3) << 6) | ((e->off >> 3) & 0x3f)); + } + break; + + case AARCH64_UOP_SAVE_FREG: + { + int r = e->info - 8; + out_one (AARCH64_UOP_SAVE_FREG | ((r & 0x4) >> 2)); + out_one (((r & 0x3) << 6) | ((e->off >> 3) & 0x3f)); + } + break; + + case AARCH64_UOP_SAVE_FREG_X: + { + int r = e->info - 8; + out_one (AARCH64_UOP_SAVE_FREG_X); + out_one (((r & 0x7) << 5) | (((e->off >> 3) - 1) & 0x1f)); + } + break; + + case AARCH64_UOP_SAVE_FREG_P: + { + int r = e->info - 8; + out_one (AARCH64_UOP_SAVE_FREG_P | ((r & 0x4) >> 2)); + out_one (((r & 0x3) << 6) | ((e->off >> 3) & 0x3f)); + } + break; + + case AARCH64_UOP_SAVE_FREG_PX: + { + int r = e->info - 8; + out_one (AARCH64_UOP_SAVE_FREG_PX | ((r & 0x4) >> 2)); + out_one (((r & 0x3) << 6) | (((e->off >> 3) - 1) & 0x3f)); + } + break; + + case AARCH64_UOP_SET_FP: + case AARCH64_UOP_NOP: + case AARCH64_UOP_END: + case AARCH64_UOP_SAVE_NEXT: + case AARCH64_UOP_TRAP_FRAME: + case AARCH64_UOP_PUSH_MACH: + case AARCH64_UOP_CONTEXT: + case AARCH64_UOP_EC_CONTEXT: + case AARCH64_UOP_CLEAR_UNWOUND_TO_CALL: + case AARCH64_UOP_PAC_SIGN_LR: + out_one (e->code); + break; + + case AARCH64_UOP_ADD_FP: + out_one (AARCH64_UOP_ADD_FP); + out_one (e->info & 0xff); + break; + + default: + abort (); + } + } + + /* Terminate with END opcode. */ + out_one (AARCH64_UOP_END); +} +/* Write the xdata for one AArch64 function. */ static void -seh_x64_write_function_xdata (seh_context *c) +seh_aarch64_write_function_xdata (seh_context *c) { - int flags, count_unwind_codes; - expressionS exp; + int code_words, epilog_count; + unsigned int func_length; - /* Set 4-byte alignment. */ + /* 4-byte alignment. */ frag_align (2, 0, 0); c->xdata_addr = symbol_temp_new_now (); - flags = c->handler_flags; - count_unwind_codes = seh_x64_size_prologue_data (c); - /* ubyte:3 version, ubyte:5 flags. */ - out_one ((flags << 3) | 1); - - /* Size of prologue. */ - if (c->endprologue_addr) + /* Calculate function length in 4-byte units. Compute it from the + symbols' fragment positions rather than resolve_expression, which + can fail when the symbols span multiple fragments. */ + { + addressT off1, off2; + fragS *f1 = symbol_get_frag_and_value (c->start_addr, &off1); + fragS *f2 = symbol_get_frag_and_value (c->end_addr, &off2); + long bytes = 0; + + if (f1 == f2) + bytes = off2 - off1; + else + { + /* Sum fragment sizes from f1 to f2. */ + bytes = off2; + for (fragS *f = f1; f && f != f2; f = f->fr_next) + { + if (!f->fr_next) + break; + bytes += f->fr_fix; + if (f->fr_var > 0) + bytes += f->fr_var * f->fr_subtype; + } + bytes -= off1; + } + func_length = bytes < 0 ? 0 : bytes >> 2; + } + + /* Count unwind code bytes, including the terminating END. */ + int code_bytes = seh_aarch64_size_prologue_data (c) + 1; + code_words = (code_bytes + 3) / 4; + + /* A function with no prologue codes only needs the END marker. + In that case, code_words is 0 and no unwind code bytes are emitted. */ + bool no_unwind_codes = (code_bytes == 1); + if (no_unwind_codes) + code_words = 0; + + /* Header word (Microsoft ARM64 SEH xdata format, matching LLVM MCWin64EH): + bits [0:17] = Function Length / 4 (18 bits) + bit [20] = X (Exception Handler Present) + bit [21] = E (Packed Epilog Present) + bits [26:22] = Epilog Count (5 bits) + bits [31:27] = Code Words (5 bits) */ + epilog_count = 0; + unsigned int header = func_length & 0x3ffff; + if (code_words > 0x1f) { - exp.X_op = O_subtract; - exp.X_add_symbol = c->endprologue_addr; - exp.X_op_symbol = c->start_addr; - exp.X_add_number = 0; - emit_expr (&exp, 1); + header |= (0 << 27); + header |= ((epilog_count & 0x1f) << 22); } else - out_one (0); + { + header |= ((code_words & 0x1f) << 27); + header |= ((epilog_count & 0x1f) << 22); + } + if (c->handler_flags & (UNW_FLAG_EHANDLER | UNW_FLAG_UHANDLER)) + header |= (1 << 20); - /* Number of slots (i.e. shorts) in the unwind codes array. */ - if (count_unwind_codes > 255) - as_fatal (_("too much unwind data in this .seh_proc")); - out_one (count_unwind_codes); + out_four (header); - /* ubyte:4 frame-reg, ubyte:4 frame-reg-offset. */ - /* Note that frameoff is already a multiple of 16, and therefore - the offset is already both scaled and shifted into place. */ - out_one (c->frameoff | c->framereg); + /* If extended code words needed, emit extension word. + bits [15:0] = Epilog Count, bits [23:16] = Code Words. + Also emit it when both the code words and epilog count are zero: + in that case Windows (and Wine) treat the packed fields as zero and + read the actual values from the extension word. */ + if (code_words > 0x1f || no_unwind_codes) + { + unsigned int ext = ((code_words & 0xff) << 16) + | (epilog_count & 0xffff); + out_four (ext); + } - seh_x64_write_prologue_data (c); + /* Write prologue unwind codes (skipped when no_unwind_codes). */ + if (!no_unwind_codes) + seh_aarch64_write_prologue_data (c); - /* We need to align prologue data. */ - if (count_unwind_codes & 1) - out_two (0); + /* Pad to 4-byte alignment. Only needed when unwind codes are present. */ + if (!no_unwind_codes) + { + int remainder = (code_bytes) & 3; + if (remainder) + for (int i = 0; i < 4 - remainder; i++) + out_one (AARCH64_UOP_NOP); + } - if (flags & (UNW_FLAG_EHANDLER | UNW_FLAG_UHANDLER)) + /* If exception handler present, emit it. */ + if (c->handler_flags & (UNW_FLAG_EHANDLER | UNW_FLAG_UHANDLER)) { - /* Force the use of segment-relative relocations instead of absolute - valued expressions. Don't adjust for constants (e.g. NULL). */ if (c->handler.X_op == O_symbol) - c->handler.X_op = O_symbol_rva; + c->handler.X_op = O_symbol_rva; emit_expr (&c->handler, 4); } - /* Handler data will be tacked in here by subsections. */ + /* Handler data follows in subsections. */ } /* Write out xdata for one function. */ @@ -745,67 +1324,21 @@ write_function_xdata (seh_context *c) segT save_seg = now_seg; int save_subseg = now_subseg; - /* MIPS, SH, ARM don't have xdata. */ - if (seh_get_target_kind () != seh_kind_x64) - return; - - switch_xdata (c->subsection, c->code_seg); - - seh_x64_write_function_xdata (c); + if (seh_get_target_kind () == seh_kind_x64) + { + switch_xdata (c->subsection, c->code_seg); + seh_x64_write_function_xdata (c); + } + else if (seh_get_target_kind () == seh_kind_aarch64) + { + switch_xdata (c->subsection, c->code_seg); + seh_aarch64_write_function_xdata (c); + } subseg_set (save_seg, save_subseg); } -/* Write pdata section data for one function (arm). */ - -static void -seh_arm_write_function_pdata (seh_context *c) -{ - expressionS exp; - unsigned int prol_len = 0, func_len = 0; - unsigned int val; - - /* Start address of the function. */ - exp.X_op = O_symbol; - exp.X_add_symbol = c->start_addr; - exp.X_add_number = 0; - emit_expr (&exp, 4); - - exp.X_op = O_subtract; - exp.X_add_symbol = c->end_addr; - exp.X_op_symbol = c->start_addr; - exp.X_add_number = 0; - if (resolve_expression (&exp) && exp.X_op == O_constant) - func_len = exp.X_add_number; - else - as_bad (_(".seh_endproc in a different section from .seh_proc")); - - if (c->endprologue_addr) - { - exp.X_op = O_subtract; - exp.X_add_symbol = c->endprologue_addr; - exp.X_op_symbol = c->start_addr; - exp.X_add_number = 0; - - if (resolve_expression (&exp) && exp.X_op == O_constant) - prol_len = exp.X_add_number; - else - as_bad (_(".seh_endprologue in a different section from .seh_proc")); - } - - /* Both function and prologue are in units of instructions. */ - func_len >>= (c->use_instruction_32 ? 2 : 1); - prol_len >>= (c->use_instruction_32 ? 2 : 1); - /* Assemble the second word of the pdata. */ - val = prol_len & 0xff; - val |= (func_len & 0x3fffff) << 8; - if (c->use_instruction_32) - val |= 0x40000000U; - if (c->handler_written) - val |= 0x80000000U; - out_four (val); -} /* Write out pdata for one function. */ @@ -858,6 +1391,17 @@ write_function_pdata (seh_context *c) seh_arm_write_function_pdata (c); break; + case seh_kind_aarch64: + exp.X_op = O_symbol_rva; + exp.X_add_number = 0; + exp.X_add_symbol = c->start_addr; + emit_expr (&exp, 4); + exp.X_op = O_symbol_rva; + exp.X_add_number = 0; + exp.X_add_symbol = c->xdata_addr; + emit_expr (&exp, 4); + break; + default: abort (); } diff --git a/gas/config/obj-coff-seh.h b/gas/config/obj-coff-seh.h index 8a3e1d602aa..f1b3535d138 100644 --- a/gas/config/obj-coff-seh.h +++ b/gas/config/obj-coff-seh.h @@ -25,6 +25,8 @@ The third is the IA64 and x64 version. Note, the IA64 isn't implemented yet, but to find information about it, please see specification about IA64 on http://download.intel.com/design/Itanium/Downloads/245358.pdf file. + The fourth is for AArch64 (ARM64) Windows, which uses the same pdata/xdata + model as x64 but with different unwind codes and a 2-word pdata entry. The first version has just entries in the pdata section: BeginAddress, EndAddress, ExceptionHandler, HandlerData, and PrologueEndAddress. Each @@ -41,10 +43,14 @@ prologue, exception-handler, and additional SEH data is stored within the UNWIND_DATA field in the xdata section. + The fourth (AArch64/ARM64) version has a 2-word pdata entry: + BeginAddress (RVA) and UnwindData (RVA), with xdata using ARM64-specific + unwind codes. + The pseudos: .seh_proc <fct_name> .seh_endprologue - .seh_handler <handler>[,@unwind][,@except] (x64) + .seh_handler <handler>[,@unwind][,@except] (x64, aarch64) .seh_handler <handler>[,<handler_data>] (others) .seh_handlerdata .seh_eh @@ -57,6 +63,17 @@ .seh_savexmm .seh_pushframe .seh_code + .seh_save_regp <reg1>,<reg2>,<offset> (aarch64) + .seh_save_fregp <reg1>,<reg2>,<offset> (aarch64) + .seh_save_reg <reg>,<offset> (aarch64) + .seh_save_freg <reg>,<offset> (aarch64) + .seh_save_fplr <offset> (aarch64) + .seh_save_fplr_x <offset> (aarch64) + .seh_save_lrpair <reg>,<offset> (aarch64) + .seh_set_fp (aarch64) + .seh_add_fp <offset> (aarch64) + .seh_nop (aarch64) + .seh_alloc_stack <size> (aarch64) */ #ifndef OBJ_COFF_SEH_H @@ -78,7 +95,18 @@ {"seh_no32", obj_coff_seh_32, 0}, \ {"seh_handler", obj_coff_seh_handler, 0}, \ {"seh_code", obj_coff_seh_code, 0}, \ - {"seh_handlerdata", obj_coff_seh_handlerdata, 0}, + {"seh_handlerdata", obj_coff_seh_handlerdata, 0}, \ + {"seh_save_regp", obj_coff_seh_aarch64_save_regp, 0}, \ + {"seh_save_fregp", obj_coff_seh_aarch64_save_fregp, 0}, \ + {"seh_save_reg", obj_coff_seh_aarch64_save_reg, 0}, \ + {"seh_save_freg", obj_coff_seh_aarch64_save_freg, 0}, \ + {"seh_save_fplr", obj_coff_seh_aarch64_save_fplr, 0}, \ + {"seh_save_fplr_x", obj_coff_seh_aarch64_save_fplr_x, 0}, \ + {"seh_save_lrpair", obj_coff_seh_aarch64_save_lrpair, 0}, \ + {"seh_set_fp", obj_coff_seh_aarch64_set_fp, 0}, \ + {"seh_add_fp", obj_coff_seh_aarch64_add_fp, 0}, \ + {"seh_nop", obj_coff_seh_aarch64_nop, 0}, \ + {"seh_alloc_stack", obj_coff_seh_aarch64_alloc_stack, 0}, /* Type definitions. */ @@ -135,9 +163,44 @@ typedef enum seh_kind { seh_kind_unknown = 0, seh_kind_mips = 1, /* Used for MIPS and x86 pdata generation. */ seh_kind_arm = 2, /* Used for ARM, PPC, SH3, and SH4 pdata (PDATA_EH) generation. */ - seh_kind_x64 = 3 /* Used for IA64 and x64 pdata/xdata generation. */ + seh_kind_x64 = 3, /* Used for IA64 and x64 pdata/xdata generation. */ + seh_kind_aarch64 = 4 /* Used for AArch64 (ARM64) Windows pdata/xdata generation. */ } seh_kind; +/* AArch64 unwind opcodes. */ +#define AARCH64_UOP_ALLOC_SMALL 0x00 +#define AARCH64_UOP_ALLOC_MEDIUM 0xC0 +#define AARCH64_UOP_ALLOC_LARGE 0xE0 +#define AARCH64_UOP_SAVE_R19R20X 0x20 +#define AARCH64_UOP_SAVE_FPLRX 0x80 +#define AARCH64_UOP_SAVE_FPLR 0x40 +#define AARCH64_UOP_SAVE_REG 0xD0 +#define AARCH64_UOP_SAVE_REG_X 0xD4 +#define AARCH64_UOP_SAVE_REG_P 0xC8 +#define AARCH64_UOP_SAVE_REG_PX 0xCC +#define AARCH64_UOP_SAVE_LRPAIR 0xD6 +#define AARCH64_UOP_SAVE_FREG 0xDC +#define AARCH64_UOP_SAVE_FREG_X 0xDE +#define AARCH64_UOP_SAVE_FREG_P 0xD8 +#define AARCH64_UOP_SAVE_FREG_PX 0xDA +#define AARCH64_UOP_SET_FP 0xE1 +#define AARCH64_UOP_ADD_FP 0xE2 +#define AARCH64_UOP_NOP 0xE3 +#define AARCH64_UOP_END 0xE4 +#define AARCH64_UOP_SAVE_NEXT 0xE6 +#define AARCH64_UOP_TRAP_FRAME 0xE8 +#define AARCH64_UOP_PUSH_MACH 0xE9 +#define AARCH64_UOP_CONTEXT 0xEA +#define AARCH64_UOP_EC_CONTEXT 0xEB +#define AARCH64_UOP_CLEAR_UNWOUND_TO_CALL 0xEC +#define AARCH64_UOP_PAC_SIGN_LR 0xFC +#define AARCH64_UOP_SAVE_ANY_REG_I 0xE7 +#define AARCH64_UOP_SAVE_ANY_REG_IP 0xE7 +#define AARCH64_UOP_SAVE_ANY_REG_D 0xE7 +#define AARCH64_UOP_SAVE_ANY_REG_DP 0xE7 +#define AARCH64_UOP_SAVE_ANY_REG_Q 0xE7 +#define AARCH64_UOP_SAVE_ANY_REG_QP 0xE7 + /* Forward declarations. */ static void obj_coff_seh_stackalloc (int); static void obj_coff_seh_setframe (int); @@ -152,6 +215,17 @@ static void obj_coff_seh_proc (int); static void obj_coff_seh_handler (int); static void obj_coff_seh_handlerdata (int); static void obj_coff_seh_code (int); +static void obj_coff_seh_aarch64_save_regp (int); +static void obj_coff_seh_aarch64_save_fregp (int); +static void obj_coff_seh_aarch64_save_reg (int); +static void obj_coff_seh_aarch64_save_freg (int); +static void obj_coff_seh_aarch64_save_fplr (int); +static void obj_coff_seh_aarch64_save_fplr_x (int); +static void obj_coff_seh_aarch64_save_lrpair (int); +static void obj_coff_seh_aarch64_set_fp (int); +static void obj_coff_seh_aarch64_add_fp (int); +static void obj_coff_seh_aarch64_nop (int); +static void obj_coff_seh_aarch64_alloc_stack (int); #define UNDSEC bfd_und_section_ptr -- 2.55.0 --000000000000038c3a06580f7f8b Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable <div dir=3D"ltr">From 776ee433b5cd3d74d43cb3ff006e484583f7beff Mon Sep 17 0= 0:00:00 2001<br>From: trcrsired <<a href=3D"mailto:[email protected]"= >[email protected]</a>><br>Date: Thu, 30 Jul 2026 16:06:12 +0800<br>S= ubject: [PATCH] gas: Add AArch64 Windows SEH (pdata/xdata) support<br><br>I= mplement Windows exception-handling (SEH) unwind info generation for<br>the= aarch64-w64-mingw32 target in GAS.<br><br>The existing obj-coff-seh.c only= handled x64.=C2=A0 This adds full AArch64<br>support:<br><br>* .seh_proc/.= seh_endprologue and all AArch64 unwind directives<br>=C2=A0 (.seh_alloc_sta= ck, .seh_save_fplr/x, .seh_save_reg/p/p_x,<br>=C2=A0 .seh_save_freg/p/p_x, = .seh_save_lrpair, .seh_set_fp, .seh_add_fp,<br>=C2=A0 .seh_handler, etc.)<b= r>* Correct xdata header layout (FunctionLength / CodeWords / EpilogCount /= <br>=C2=A0 E / X bits) matching the MS ARM64 format<br>* Emit the xdata ext= ension word when CodeWords=3D=3D0 and EpilogCount=3D=3D0 so<br>=C2=A0 Windo= ws exception parsers do not misread the next entry<br>* Correct opcode enco= dings for register save pairs (save_regp etc.)<br>* Function length compute= d from fragment positions instead of<br>=C2=A0 resolve_expression, which fa= iled across fragments<br>---<br>=C2=A0gas/config/obj-coff-seh.c | 884 +++++= +++++++++++++++++++++++++--------<br>=C2=A0gas/config/obj-coff-seh.h | =C2= =A080 +++-<br>=C2=A02 files changed, 791 insertions(+), 173 deletions(-)<br= ><br>diff --git a/gas/config/obj-coff-seh.c b/gas/config/obj-coff-seh.c<br>= index 1ac64f8f9ba..113c7a9b2b6 100644<br>--- a/gas/config/obj-coff-seh.c<br= >+++ b/gas/config/obj-coff-seh.c<br>@@ -43,6 +43,8 @@ seh_get_target_kind (= void)<br>=C2=A0 =C2=A0switch (bfd_get_arch (stdoutput))<br>=C2=A0 =C2=A0 = =C2=A0{<br>=C2=A0 =C2=A0 =C2=A0case bfd_arch_aarch64:<br>+ =C2=A0 =C2=A0 = =C2=A0return seh_kind_aarch64;<br>+<br>=C2=A0 =C2=A0 =C2=A0case bfd_arch_ar= m:<br>=C2=A0 =C2=A0 =C2=A0case bfd_arch_powerpc:<br>=C2=A0 =C2=A0 =C2=A0cas= e bfd_arch_sh:<br>@@ -176,7 +178,8 @@ obj_coff_seh_handler (int what ATTRIB= UTE_UNUSED)<br>=C2=A0 =C2=A0if (!skip_whitespace_and_comma (0))<br>=C2=A0 = =C2=A0 =C2=A0return;<br>=C2=A0<br>- =C2=A0if (seh_get_target_kind () =3D=3D= seh_kind_x64)<br>+ =C2=A0if (seh_get_target_kind () =3D=3D seh_kind_x64<br= >+ =C2=A0 =C2=A0 =C2=A0|| seh_get_target_kind () =3D=3D seh_kind_aarch64)<b= r>=C2=A0 =C2=A0 =C2=A0{<br>=C2=A0 =C2=A0 =C2=A0 =C2=A0do<br>=C2=A0 {<br>@@ = -208,7 +211,7 @@ obj_coff_seh_handler (int what ATTRIBUTE_UNUSED)<br>=C2=A0= static void<br>=C2=A0obj_coff_seh_handlerdata (int what ATTRIBUTE_UNUSED)<b= r>=C2=A0{<br>- =C2=A0if (!verify_context_and_target (".seh_handlerdata= ", seh_kind_x64))<br>+ =C2=A0if (!verify_context_and_target (".se= h_handlerdata", seh_get_target_kind ()))<br>=C2=A0 =C2=A0 =C2=A0return= ;<br>=C2=A0 =C2=A0demand_empty_rest_of_line ();<br>=C2=A0<br>@@ -217,6 +220= ,46 @@ obj_coff_seh_handlerdata (int what ATTRIBUTE_UNUSED)<br>=C2=A0<br>= =C2=A0/* Mark end of current context. =C2=A0*/<br>=C2=A0<br>+static void<br= >+out_one (int byte)<br>+{<br>+ =C2=A0char *p =3D frag_more (1);<br>+ =C2= =A0md_number_to_chars (p, byte, 1);<br>+}<br>+<br>+static void<br>+out_two = (int data)<br>+{<br>+ =C2=A0char *p =3D frag_more (2);<br>+ =C2=A0md_number= _to_chars (p, data, 2);<br>+}<br>+<br>+static void<br>+out_four (int data)<= br>+{<br>+ =C2=A0char *p =3D frag_more (4);<br>+ =C2=A0md_number_to_chars (= p, data, 4);<br>+}<br>+<br>+/* Write xdata for an x64 function (passthrough= to existing<br>+ =C2=A0 xdata output via prologue elements). =C2=A0*/<br>+= <br>+static void<br>+seh_x64_write_function_xdata (seh_context *c ATTRIBUTE= _UNUSED)<br>+{<br>+ =C2=A0/* The x64 xdata is already emitted incrementally= as prologue<br>+ =C2=A0 =C2=A0 elements are processed; this function is a = no-op placeholder<br>+ =C2=A0 =C2=A0 for consistency with the aarch64 dispa= tch. =C2=A0*/<br>+}<br>+<br>+/* Write pdata for an ARM (WinCE-style) functi= on (no-op stub). =C2=A0*/<br>+<br>+static void<br>+seh_arm_write_function_p= data (seh_context *c ATTRIBUTE_UNUSED)<br>+{<br>+ =C2=A0abort ();<br>+}<br>= +<br>=C2=A0static void<br>=C2=A0do_seh_endproc (void)<br>=C2=A0{<br>@@ -272= ,7 +315,8 @@ obj_coff_seh_proc (int what ATTRIBUTE_UNUSED)<br>=C2=A0<br>=C2= =A0 =C2=A0seh_ctx_cur->code_seg =3D now_seg;<br>=C2=A0<br>- =C2=A0if (se= h_get_target_kind () =3D=3D seh_kind_x64)<br>+ =C2=A0if (seh_get_target_kin= d () =3D=3D seh_kind_x64<br>+ =C2=A0 =C2=A0 =C2=A0|| seh_get_target_kind ()= =3D=3D seh_kind_aarch64)<br>=C2=A0 =C2=A0 =C2=A0{<br>=C2=A0 =C2=A0 =C2=A0 = =C2=A0x_segcur =3D seh_hash_find_or_make (seh_ctx_cur->code_seg, ".= xdata");<br>=C2=A0 =C2=A0 =C2=A0 =C2=A0seh_ctx_cur->subsection =3D = x_segcur->subseg;<br>@@ -565,176 +609,711 @@ obj_coff_seh_setframe (int = what ATTRIBUTE_UNUSED)<br>=C2=A0 =C2=A0 =C2=A0 =C2=A0seh_x64_make_prologue_= element (UWOP_SET_FPREG, 0, 0);<br>=C2=A0 =C2=A0 =C2=A0}<br>=C2=A0}<br>-=0C= <br>-/* Data writing routines. =C2=A0*/<br>=C2=A0<br>-/* Output raw integer= s in 1, 2, or 4 bytes. =C2=A0*/<br>+/* AArch64 support. =C2=A0*/<br>+<br>+/= * AArch64 register name tables. =C2=A0*/<br>+static const char * const aarc= h64_int_regs[31] =3D {<br>+ =C2=A0"x0", "x1", "x2&= quot;, "x3", "x4", "x5", "x6", &quo= t;x7",<br>+ =C2=A0"x8", "x9", "x10", &qu= ot;x11", "x12", "x13", "x14", "x15&= quot;,<br>+ =C2=A0"x16", "x17", "x18", "= x19", "x20", "x21", "x22", "x23&quo= t;,<br>+ =C2=A0"x24", "x25", "x26", "x27= ", "x28", "x29", "x30"<br>+};<br>+<br>+s= tatic const char * const aarch64_fp_regs[32] =3D {<br>+ =C2=A0"d0"= ;, "d1", "d2", "d3", "d4", "d5= ", "d6", "d7",<br>+ =C2=A0"d8", "d9= ", "d10", "d11", "d12", "d13",= "d14", "d15",<br>+ =C2=A0"d16", "d17&qu= ot;, "d18", "d19", "d20", "d21", &q= uot;d22", "d23",<br>+ =C2=A0"d24", "d25"= , "d26", "d27", "d28", "d29", "= ;d30", "d31"<br>+};<br>+<br>+/* Read an AArch64 integer regi= ster from input stream.<br>+ =C2=A0 Returns the register number (0-30) or -= 1 on error.<br>+ =C2=A0 Also accepts "fp" (x29) and "lr"= ; (x30). =C2=A0*/<br>+static int<br>+seh_aarch64_read_int_reg (const char *= directive, int min_reg, int max_reg)<br>+{<br>+ =C2=A0char name_end;<br>+ = =C2=A0char *symbol_name;<br>+ =C2=A0int i;<br>+<br>+ =C2=A0SKIP_WHITESPACE = ();<br>+ =C2=A0name_end =3D get_symbol_name (&symbol_name);<br>=C2=A0<b= r>-static inline void<br>-out_one (int byte)<br>+ =C2=A0/* Check for specia= l names. =C2=A0*/<br>+ =C2=A0if (strcasecmp (symbol_name, "fp") = =3D=3D 0)<br>+ =C2=A0 =C2=A0i =3D 29;<br>+ =C2=A0else if (strcasecmp (symbo= l_name, "lr") =3D=3D 0)<br>+ =C2=A0 =C2=A0i =3D 30;<br>+ =C2=A0el= se<br>+ =C2=A0 =C2=A0{<br>+ =C2=A0 =C2=A0 =C2=A0for (i =3D 0; i < 31; i+= +)<br>+ if (!strcasecmp (aarch64_int_regs[i], symbol_name))<br>+ =C2=A0bre= ak;<br>+ =C2=A0 =C2=A0}<br>+<br>+ =C2=A0(void) restore_line_pointer (name_e= nd);<br>+<br>+ =C2=A0if (i > max_reg || i < min_reg)<br>+ =C2=A0 =C2= =A0{<br>+ =C2=A0 =C2=A0 =C2=A0as_bad (_("invalid register for %s"= ), directive);<br>+ =C2=A0 =C2=A0 =C2=A0return -1;<br>+ =C2=A0 =C2=A0}<br>+= <br>+ =C2=A0return i;<br>+}<br>+<br>+/* Read an AArch64 FP/SIMD register fr= om input stream.<br>+ =C2=A0 Returns the register number (0-31) or -1 on er= ror. =C2=A0*/<br>+static int<br>+seh_aarch64_read_fp_reg (const char *direc= tive)<br>=C2=A0{<br>- =C2=A0FRAG_APPEND_1_CHAR (byte);<br>+ =C2=A0char name= _end;<br>+ =C2=A0char *symbol_name;<br>+ =C2=A0int i;<br>+<br>+ =C2=A0SKIP_= WHITESPACE ();<br>+ =C2=A0name_end =3D get_symbol_name (&symbol_name);<= br>+<br>+ =C2=A0for (i =3D 0; i < 32; i++)<br>+ =C2=A0 =C2=A0if (!strcas= ecmp (aarch64_fp_regs[i], symbol_name))<br>+ =C2=A0 =C2=A0 =C2=A0break;<br>= +<br>+ =C2=A0(void) restore_line_pointer (name_end);<br>+<br>+ =C2=A0if (i = =3D=3D 32)<br>+ =C2=A0 =C2=A0{<br>+ =C2=A0 =C2=A0 =C2=A0as_bad (_("inv= alid floating-point register for %s"), directive);<br>+ =C2=A0 =C2=A0 = =C2=A0return -1;<br>+ =C2=A0 =C2=A0}<br>+<br>+ =C2=A0return i;<br>=C2=A0}<b= r>=C2=A0<br>-static inline void<br>-out_two (int data)<br>+/* Add a prologu= e element to the AArch64 SEH context. =C2=A0*/<br>+static void<br>+seh_aarc= h64_make_prologue_element (int code, int info, offsetT off)<br>=C2=A0{<br>-= =C2=A0md_number_to_chars (frag_more (2), data, 2);<br>+ =C2=A0seh_prologue= _element *n;<br>+<br>+ =C2=A0if (seh_ctx_cur =3D=3D NULL)<br>+ =C2=A0 =C2= =A0return;<br>+ =C2=A0if (seh_ctx_cur->elems_count =3D=3D seh_ctx_cur-&g= t;elems_max)<br>+ =C2=A0 =C2=A0{<br>+ =C2=A0 =C2=A0 =C2=A0seh_ctx_cur->e= lems_max +=3D 8;<br>+ =C2=A0 =C2=A0 =C2=A0seh_ctx_cur->elems =3D XRESIZE= VEC (seh_prologue_element,<br>+ =C2=A0 =C2=A0 =C2=A0 seh_ctx_cur->el= ems,<br>+ =C2=A0 =C2=A0 =C2=A0 seh_ctx_cur->elems_max);<br>+ =C2=A0 = =C2=A0}<br>+<br>+ =C2=A0n =3D &seh_ctx_cur->elems[seh_ctx_cur->el= ems_count++];<br>+ =C2=A0n->code =3D code;<br>+ =C2=A0n->info =3D inf= o;<br>+ =C2=A0n->off =3D off;<br>+ =C2=A0n->pc_addr =3D symbol_temp_n= ew_now ();<br>=C2=A0}<br>=C2=A0<br>-static inline void<br>-out_four (int da= ta)<br>+/* .seh_save_regp <reg1>, <reg2>, <offset> (aarch= 64)<br>+ =C2=A0 Save register pair at offset from SP. =C2=A0*/<br>+static v= oid<br>+obj_coff_seh_aarch64_save_regp (int what ATTRIBUTE_UNUSED)<br>=C2= =A0{<br>- =C2=A0md_number_to_chars (frag_more (4), data, 4);<br>+ =C2=A0int= reg1, reg2;<br>+ =C2=A0offsetT off;<br>+<br>+ =C2=A0if (!verify_context_an= d_target (".seh_save_regp", seh_kind_aarch64)<br>+ =C2=A0 =C2=A0 = =C2=A0|| !seh_validate_seg (".seh_save_regp"))<br>+ =C2=A0 =C2=A0= return;<br>+<br>+ =C2=A0reg1 =3D seh_aarch64_read_int_reg (".seh_save_= regp", 0, 30);<br>+ =C2=A0if (!skip_whitespace_and_comma (1))<br>+ =C2= =A0 =C2=A0return;<br>+ =C2=A0reg2 =3D seh_aarch64_read_int_reg (".seh_= save_regp", 0, 30);<br>+ =C2=A0if (!skip_whitespace_and_comma (1))<br>= + =C2=A0 =C2=A0return;<br>+ =C2=A0off =3D get_absolute_expression ();<br>+ = =C2=A0demand_empty_rest_of_line ();<br>+<br>+ =C2=A0if (reg1 < 0 || reg2= < 0)<br>+ =C2=A0 =C2=A0return;<br>+ =C2=A0if (off < 0 || (off & = 7))<br>+ =C2=A0 =C2=A0{<br>+ =C2=A0 =C2=A0 =C2=A0as_bad (_(".seh_save_= regp offset must be non-negative and 8-byte aligned"));<br>+ =C2=A0 = =C2=A0 =C2=A0return;<br>+ =C2=A0 =C2=A0}<br>+<br>+ =C2=A0/* Check for speci= al case: saving x29,x30 (FPLR pair). =C2=A0*/<br>+ =C2=A0if (reg1 =3D=3D 29= && reg2 =3D=3D 30)<br>+ =C2=A0 =C2=A0{<br>+ =C2=A0 =C2=A0 =C2=A0if= (off <=3D 0x3F * 8)<br>+ {<br>+ =C2=A0seh_aarch64_make_prologue_elemen= t (AARCH64_UOP_SAVE_FPLR, off >> 3, 0);<br>+ =C2=A0return;<br>+ }<br= >+ =C2=A0 =C2=A0}<br>+<br>+ =C2=A0seh_aarch64_make_prologue_element (AARCH6= 4_UOP_SAVE_REG_P, reg1, off);<br>=C2=A0}<br>=C2=A0<br>-/* Write out prologu= e data for x64. =C2=A0*/<br>+/* .seh_save_fregp <reg1>, <reg2>,= <offset> (aarch64)<br>+ =C2=A0 Save FP/SIMD register pair. =C2=A0*/<= br>+static void<br>+obj_coff_seh_aarch64_save_fregp (int what ATTRIBUTE_UNU= SED)<br>+{<br>+ =C2=A0int reg1, reg2;<br>+ =C2=A0offsetT off;<br>+<br>+ =C2= =A0if (!verify_context_and_target (".seh_save_fregp", seh_kind_aa= rch64)<br>+ =C2=A0 =C2=A0 =C2=A0|| !seh_validate_seg (".seh_save_fregp= "))<br>+ =C2=A0 =C2=A0return;<br>+<br>+ =C2=A0reg1 =3D seh_aarch64_rea= d_fp_reg (".seh_save_fregp");<br>+ =C2=A0if (!skip_whitespace_and= _comma (1))<br>+ =C2=A0 =C2=A0return;<br>+ =C2=A0reg2 =3D seh_aarch64_read_= fp_reg (".seh_save_fregp");<br>+ =C2=A0if (!skip_whitespace_and_c= omma (1))<br>+ =C2=A0 =C2=A0return;<br>+ =C2=A0off =3D get_absolute_express= ion ();<br>+ =C2=A0demand_empty_rest_of_line ();<br>+<br>+ =C2=A0if (reg1 &= lt; 0 || reg2 < 0)<br>+ =C2=A0 =C2=A0return;<br>+ =C2=A0if (off < 0 |= | (off & 7))<br>+ =C2=A0 =C2=A0{<br>+ =C2=A0 =C2=A0 =C2=A0as_bad (_(&qu= ot;.seh_save_fregp offset must be non-negative and 8-byte aligned"));<= br>+ =C2=A0 =C2=A0 =C2=A0return;<br>+ =C2=A0 =C2=A0}<br>+<br>+ =C2=A0seh_aa= rch64_make_prologue_element (AARCH64_UOP_SAVE_FREG_P, reg1, off);<br>+}<br>= =C2=A0<br>+/* .seh_save_reg <reg>, <offset> (aarch64)<br>+ =C2= =A0 Save a single integer register. =C2=A0*/<br>=C2=A0static void<br>-seh_x= 64_write_prologue_data (const seh_context *c)<br>+obj_coff_seh_aarch64_save= _reg (int what ATTRIBUTE_UNUSED)<br>=C2=A0{<br>- =C2=A0int i;<br>+ =C2=A0in= t reg;<br>+ =C2=A0offsetT off;<br>=C2=A0<br>- =C2=A0/* We have to store in = reverse order. =C2=A0*/<br>- =C2=A0for (i =3D c->elems_count - 1; i >= =3D 0; --i)<br>+ =C2=A0if (!verify_context_and_target (".seh_save_reg&= quot;, seh_kind_aarch64)<br>+ =C2=A0 =C2=A0 =C2=A0|| !seh_validate_seg (&qu= ot;.seh_save_reg"))<br>+ =C2=A0 =C2=A0return;<br>+<br>+ =C2=A0reg =3D = seh_aarch64_read_int_reg (".seh_save_reg", 0, 30);<br>+ =C2=A0if = (!skip_whitespace_and_comma (1))<br>+ =C2=A0 =C2=A0return;<br>+ =C2=A0off = =3D get_absolute_expression ();<br>+ =C2=A0demand_empty_rest_of_line ();<br= >+<br>+ =C2=A0if (reg < 0)<br>+ =C2=A0 =C2=A0return;<br>+ =C2=A0if (off = < 0 || (off & 7))<br>=C2=A0 =C2=A0 =C2=A0{<br>- =C2=A0 =C2=A0 =C2=A0= const seh_prologue_element *e =3D c->elems + i;<br>- =C2=A0 =C2=A0 =C2= =A0expressionS exp;<br>+ =C2=A0 =C2=A0 =C2=A0as_bad (_(".seh_save_reg = offset must be non-negative and 8-byte aligned"));<br>+ =C2=A0 =C2=A0 = =C2=A0return;<br>+ =C2=A0 =C2=A0}<br>=C2=A0<br>- =C2=A0 =C2=A0 =C2=A0/* Fir= st comes byte offset in code. =C2=A0*/<br>- =C2=A0 =C2=A0 =C2=A0exp.X_op = =3D O_subtract;<br>- =C2=A0 =C2=A0 =C2=A0exp.X_add_symbol =3D e->pc_addr= ;<br>- =C2=A0 =C2=A0 =C2=A0exp.X_op_symbol =3D c->start_addr;<br>- =C2= =A0 =C2=A0 =C2=A0exp.X_add_number =3D 0;<br>- =C2=A0 =C2=A0 =C2=A0emit_expr= (&exp, 1);<br>+ =C2=A0seh_aarch64_make_prologue_element (AARCH64_UOP_S= AVE_REG, reg, off);<br>+}<br>=C2=A0<br>- =C2=A0 =C2=A0 =C2=A0/* Second come= s code+info packed into a byte. =C2=A0*/<br>- =C2=A0 =C2=A0 =C2=A0out_one (= (e->info << 4) | e->code);<br>+/* .seh_save_freg <reg>, &= lt;offset> (aarch64)<br>+ =C2=A0 Save a single FP/SIMD register. =C2=A0*= /<br>+static void<br>+obj_coff_seh_aarch64_save_freg (int what ATTRIBUTE_UN= USED)<br>+{<br>+ =C2=A0int reg;<br>+ =C2=A0offsetT off;<br>=C2=A0<br>- =C2= =A0 =C2=A0 =C2=A0switch (e->code)<br>- {<br>- case UWOP_PUSH_NONVOL:<br>= - case UWOP_ALLOC_SMALL:<br>- case UWOP_SET_FPREG:<br>- case UWOP_PUSH_MACH= FRAME:<br>- =C2=A0/* These have no extra data. =C2=A0*/<br>- =C2=A0break;= <br>+ =C2=A0if (!verify_context_and_target (".seh_save_freg", seh= _kind_aarch64)<br>+ =C2=A0 =C2=A0 =C2=A0|| !seh_validate_seg (".seh_sa= ve_freg"))<br>+ =C2=A0 =C2=A0return;<br>=C2=A0<br>- case UWOP_ALLOC_LA= RGE:<br>- =C2=A0if (e->info)<br>- =C2=A0 =C2=A0{<br>- case UWOP_SAVE_N= ONVOL_FAR:<br>- case UWOP_SAVE_XMM128_FAR:<br>- =C2=A0 =C2=A0 =C2=A0/* An = unscaled 4 byte offset. =C2=A0*/<br>- =C2=A0 =C2=A0 =C2=A0out_four (e->= off);<br>- =C2=A0 =C2=A0 =C2=A0break;<br>- =C2=A0 =C2=A0}<br>- =C2=A0/* = FALLTHRU */<br>+ =C2=A0reg =3D seh_aarch64_read_fp_reg (".seh_save_fre= g");<br>+ =C2=A0if (!skip_whitespace_and_comma (1))<br>+ =C2=A0 =C2=A0= return;<br>+ =C2=A0off =3D get_absolute_expression ();<br>+ =C2=A0demand_em= pty_rest_of_line ();<br>=C2=A0<br>- case UWOP_SAVE_NONVOL:<br>- case UWOP_S= AVE_XMM128:<br>- =C2=A0/* A scaled 2 byte offset. =C2=A0*/<br>- =C2=A0out= _two (e->off);<br>- =C2=A0break;<br>+ =C2=A0if (reg < 0)<br>+ =C2=A0= =C2=A0return;<br>+ =C2=A0if (off < 0 || (off & 7))<br>+ =C2=A0 =C2= =A0{<br>+ =C2=A0 =C2=A0 =C2=A0as_bad (_(".seh_save_freg offset must be= non-negative and 8-byte aligned"));<br>+ =C2=A0 =C2=A0 =C2=A0return;<= br>+ =C2=A0 =C2=A0}<br>=C2=A0<br>- default:<br>- =C2=A0abort ();<br>- }<br= >+ =C2=A0seh_aarch64_make_prologue_element (AARCH64_UOP_SAVE_FREG, reg, off= );<br>+}<br>+<br>+/* .seh_save_fplr <offset> (aarch64)<br>+ =C2=A0 Sa= ve x29 (FP) and x30 (LR) at a positive offset from SP. =C2=A0*/<br>+static = void<br>+obj_coff_seh_aarch64_save_fplr (int what ATTRIBUTE_UNUSED)<br>+{<b= r>+ =C2=A0offsetT off;<br>+<br>+ =C2=A0if (!verify_context_and_target (&quo= t;.seh_save_fplr", seh_kind_aarch64)<br>+ =C2=A0 =C2=A0 =C2=A0|| !seh_= validate_seg (".seh_save_fplr"))<br>+ =C2=A0 =C2=A0return;<br>+<b= r>+ =C2=A0off =3D get_absolute_expression ();<br>+ =C2=A0demand_empty_rest_= of_line ();<br>+<br>+ =C2=A0if (off < 0 || (off & 7))<br>+ =C2=A0 = =C2=A0{<br>+ =C2=A0 =C2=A0 =C2=A0as_bad (_(".seh_save_fplr offset must= be non-negative and 8-byte aligned"));<br>+ =C2=A0 =C2=A0 =C2=A0retur= n;<br>=C2=A0 =C2=A0 =C2=A0}<br>+<br>+ =C2=A0seh_aarch64_make_prologue_eleme= nt (AARCH64_UOP_SAVE_FPLR, off >> 3, 0);<br>=C2=A0}<br>=C2=A0<br>+/* = .seh_save_fplr_x <offset> (aarch64)<br>+ =C2=A0 Save x29 (FP) and x30= (LR) with predecrement (stp x29, x30, [sp, #-N]!). =C2=A0*/<br>+static voi= d<br>+obj_coff_seh_aarch64_save_fplr_x (int what ATTRIBUTE_UNUSED)<br>+{<br= >+ =C2=A0offsetT off;<br>+<br>+ =C2=A0if (!verify_context_and_target ("= ;.seh_save_fplr_x", seh_kind_aarch64)<br>+ =C2=A0 =C2=A0 =C2=A0|| !seh= _validate_seg (".seh_save_fplr_x"))<br>+ =C2=A0 =C2=A0return;<br>= +<br>+ =C2=A0off =3D get_absolute_expression ();<br>+ =C2=A0demand_empty_re= st_of_line ();<br>+<br>+ =C2=A0if (off < 0 || (off & 15))<br>+ =C2= =A0 =C2=A0{<br>+ =C2=A0 =C2=A0 =C2=A0as_bad (_(".seh_save_fplr_x offse= t must be negative and 16-byte aligned"));<br>+ =C2=A0 =C2=A0 =C2=A0re= turn;<br>+ =C2=A0 =C2=A0}<br>+ =C2=A0if (off > 0x3F * 8)<br>+ =C2=A0 =C2= =A0{<br>+ =C2=A0 =C2=A0 =C2=A0as_bad (_(".seh_save_fplr_x offset out o= f range (max 504)"));<br>+ =C2=A0 =C2=A0 =C2=A0return;<br>+ =C2=A0 =C2= =A0}<br>+<br>+ =C2=A0seh_aarch64_make_prologue_element (AARCH64_UOP_SAVE_FP= LRX, (off >> 3) - 1, 0);<br>+}<br>+<br>+/* .seh_save_lrpair <reg&g= t;, <offset> (aarch64)<br>+ =C2=A0 Save x30 (LR) and another register= at offset from SP. =C2=A0*/<br>+static void<br>+obj_coff_seh_aarch64_save_= lrpair (int what ATTRIBUTE_UNUSED)<br>+{<br>+ =C2=A0int reg;<br>+ =C2=A0off= setT off;<br>+<br>+ =C2=A0if (!verify_context_and_target (".seh_save_l= rpair", seh_kind_aarch64)<br>+ =C2=A0 =C2=A0 =C2=A0|| !seh_validate_se= g (".seh_save_lrpair"))<br>+ =C2=A0 =C2=A0return;<br>+<br>+ =C2= =A0reg =3D seh_aarch64_read_int_reg (".seh_save_lrpair", 0, 28);<= br>+ =C2=A0if (!skip_whitespace_and_comma (1))<br>+ =C2=A0 =C2=A0return;<br= >+ =C2=A0off =3D get_absolute_expression ();<br>+ =C2=A0demand_empty_rest_o= f_line ();<br>+<br>+ =C2=A0if (reg < 0)<br>+ =C2=A0 =C2=A0return;<br>+ = =C2=A0if (off < 0 || (off & 7))<br>+ =C2=A0 =C2=A0{<br>+ =C2=A0 =C2= =A0 =C2=A0as_bad (_(".seh_save_lrpair offset must be non-negative and = 8-byte aligned"));<br>+ =C2=A0 =C2=A0 =C2=A0return;<br>+ =C2=A0 =C2=A0= }<br>+<br>+ =C2=A0seh_aarch64_make_prologue_element (AARCH64_UOP_SAVE_LRPAI= R, (reg - 19) >> 1, off >> 3);<br>+}<br>+<br>+/* .seh_set_fp (a= arch64)<br>+ =C2=A0 Set frame pointer (mov x29, sp). =C2=A0*/<br>+static vo= id<br>+obj_coff_seh_aarch64_set_fp (int what ATTRIBUTE_UNUSED)<br>+{<br>+ = =C2=A0if (!verify_context_and_target (".seh_set_fp", seh_kind_aar= ch64)<br>+ =C2=A0 =C2=A0 =C2=A0|| !seh_validate_seg (".seh_set_fp"= ;))<br>+ =C2=A0 =C2=A0return;<br>+ =C2=A0demand_empty_rest_of_line ();<br>+= <br>+ =C2=A0seh_aarch64_make_prologue_element (AARCH64_UOP_SET_FP, 0, 0);<b= r>+}<br>+<br>+/* .seh_add_fp <offset> (aarch64)<br>+ =C2=A0 Add offse= t to frame pointer (add x29, sp, #N). =C2=A0*/<br>+static void<br>+obj_coff= _seh_aarch64_add_fp (int what ATTRIBUTE_UNUSED)<br>+{<br>+ =C2=A0offsetT of= f;<br>+<br>+ =C2=A0if (!verify_context_and_target (".seh_add_fp",= seh_kind_aarch64)<br>+ =C2=A0 =C2=A0 =C2=A0|| !seh_validate_seg (".se= h_add_fp"))<br>+ =C2=A0 =C2=A0return;<br>+<br>+ =C2=A0off =3D get_abso= lute_expression ();<br>+ =C2=A0demand_empty_rest_of_line ();<br>+<br>+ =C2= =A0seh_aarch64_make_prologue_element (AARCH64_UOP_ADD_FP, off >> 3, 0= );<br>+}<br>+<br>+/* .seh_nop (aarch64)<br>+ =C2=A0 No-op padding in the un= wind code. =C2=A0*/<br>+static void<br>+obj_coff_seh_aarch64_nop (int what = ATTRIBUTE_UNUSED)<br>+{<br>+ =C2=A0if (!verify_context_and_target (".s= eh_nop", seh_kind_aarch64)<br>+ =C2=A0 =C2=A0 =C2=A0|| !seh_validate_s= eg (".seh_nop"))<br>+ =C2=A0 =C2=A0return;<br>+ =C2=A0demand_empt= y_rest_of_line ();<br>+<br>+ =C2=A0seh_aarch64_make_prologue_element (AARCH= 64_UOP_NOP, 0, 0);<br>+}<br>+<br>+/* .seh_alloc_stack <size> (aarch64= )<br>+ =C2=A0 Allocate stack space. =C2=A0*/<br>+static void<br>+obj_coff_s= eh_aarch64_alloc_stack (int what ATTRIBUTE_UNUSED)<br>+{<br>+ =C2=A0offsetT= off;<br>+ =C2=A0int code, info;<br>+<br>+ =C2=A0if (!verify_context_and_ta= rget (".seh_alloc_stack", seh_kind_aarch64)<br>+ =C2=A0 =C2=A0 = =C2=A0|| !seh_validate_seg (".seh_alloc_stack"))<br>+ =C2=A0 =C2= =A0return;<br>+<br>+ =C2=A0off =3D get_absolute_expression ();<br>+ =C2=A0d= emand_empty_rest_of_line ();<br>+<br>+ =C2=A0if (off =3D=3D 0)<br>+ =C2=A0 = =C2=A0return;<br>+ =C2=A0if (off < 0)<br>+ =C2=A0 =C2=A0{<br>+ =C2=A0 = =C2=A0 =C2=A0as_bad (_(".seh_alloc_stack offset is negative"));<b= r>+ =C2=A0 =C2=A0 =C2=A0return;<br>+ =C2=A0 =C2=A0}<br>+<br>+ =C2=A0if ((of= f & 15) =3D=3D 0 && off <=3D 0x1F * 16)<br>+ =C2=A0 =C2=A0{<= br>+ =C2=A0 =C2=A0 =C2=A0code =3D AARCH64_UOP_ALLOC_SMALL;<br>+ =C2=A0 =C2= =A0 =C2=A0info =3D (off / 16) - 1;<br>+ =C2=A0 =C2=A0}<br>+ =C2=A0else if (= (off & 15) =3D=3D 0 && off <=3D 0x7FF * 16)<br>+ =C2=A0 =C2= =A0{<br>+ =C2=A0 =C2=A0 =C2=A0code =3D AARCH64_UOP_ALLOC_MEDIUM;<br>+ =C2= =A0 =C2=A0 =C2=A0info =3D off / 16;<br>+ =C2=A0 =C2=A0}<br>+ =C2=A0else if = ((off & 15) =3D=3D 0 && off <=3D (offsetT) 0xFFFFFF * 16)<br= >+ =C2=A0 =C2=A0{<br>+ =C2=A0 =C2=A0 =C2=A0code =3D AARCH64_UOP_ALLOC_LARGE= ;<br>+ =C2=A0 =C2=A0 =C2=A0info =3D 0;<br>+ =C2=A0 =C2=A0 =C2=A0off =3D off= / 16;<br>+ =C2=A0 =C2=A0}<br>+ =C2=A0else<br>+ =C2=A0 =C2=A0{<br>+ =C2=A0 = =C2=A0 =C2=A0as_bad (_(".seh_alloc_stack offset out of range"));<= br>+ =C2=A0 =C2=A0 =C2=A0return;<br>+ =C2=A0 =C2=A0}<br>+<br>+ =C2=A0seh_aa= rch64_make_prologue_element (code, info, off);<br>+}<br>+<br>+/* AArch64 xd= ata writing. =C2=A0*/<br>+<br>+/* Count the size of AArch64 unwind code dat= a in bytes. =C2=A0*/<br>=C2=A0static int<br>-seh_x64_size_prologue_data (co= nst seh_context *c)<br>+seh_aarch64_size_prologue_data (const seh_context *= c)<br>=C2=A0{<br>=C2=A0 =C2=A0int i, ret =3D 0;<br>=C2=A0<br>=C2=A0 =C2=A0f= or (i =3D c->elems_count - 1; i >=3D 0; --i)<br>- =C2=A0 =C2=A0switch= (c->elems[i].code)<br>- =C2=A0 =C2=A0 =C2=A0{<br>- =C2=A0 =C2=A0 =C2=A0= case UWOP_PUSH_NONVOL:<br>- =C2=A0 =C2=A0 =C2=A0case UWOP_ALLOC_SMALL:<br>-= =C2=A0 =C2=A0 =C2=A0case UWOP_SET_FPREG:<br>- =C2=A0 =C2=A0 =C2=A0case UWO= P_PUSH_MACHFRAME:<br>+ =C2=A0 =C2=A0{<br>+ =C2=A0 =C2=A0 =C2=A0int code =3D= c->elems[i].code;<br>+ =C2=A0 =C2=A0 =C2=A0if (code =3D=3D AARCH64_UOP_= ALLOC_SMALL<br>+ =C2=A0|| code =3D=3D AARCH64_UOP_SAVE_R19R20X<br>+ =C2= =A0|| code =3D=3D AARCH64_UOP_SAVE_FPLRX<br>+ =C2=A0|| code =3D=3D AARCH64= _UOP_SAVE_FPLR<br>+ =C2=A0|| code =3D=3D AARCH64_UOP_SET_FP<br>+ =C2=A0||= code =3D=3D AARCH64_UOP_NOP<br>+ =C2=A0|| code =3D=3D AARCH64_UOP_END<br>= + =C2=A0|| code =3D=3D AARCH64_UOP_SAVE_NEXT<br>+ =C2=A0|| code =3D=3D AA= RCH64_UOP_TRAP_FRAME<br>+ =C2=A0|| code =3D=3D AARCH64_UOP_PUSH_MACH<br>+ = =C2=A0|| code =3D=3D AARCH64_UOP_CONTEXT<br>+ =C2=A0|| code =3D=3D AARCH6= 4_UOP_EC_CONTEXT<br>+ =C2=A0|| code =3D=3D AARCH64_UOP_CLEAR_UNWOUND_TO_CA= LL<br>+ =C2=A0|| code =3D=3D AARCH64_UOP_PAC_SIGN_LR)<br>=C2=A0 ret +=3D 1= ;<br>- break;<br>-<br>- =C2=A0 =C2=A0 =C2=A0case UWOP_SAVE_NONVOL:<br>- =C2= =A0 =C2=A0 =C2=A0case UWOP_SAVE_XMM128:<br>+ =C2=A0 =C2=A0 =C2=A0else if (c= ode =3D=3D AARCH64_UOP_ALLOC_MEDIUM<br>+ =C2=A0 =C2=A0 =C2=A0 || code =3D= =3D AARCH64_UOP_SAVE_REG<br>+ =C2=A0 =C2=A0 =C2=A0 || code =3D=3D AARCH64_= UOP_SAVE_REG_X<br>+ =C2=A0 =C2=A0 =C2=A0 || code =3D=3D AARCH64_UOP_SAVE_R= EG_P<br>+ =C2=A0 =C2=A0 =C2=A0 || code =3D=3D AARCH64_UOP_SAVE_REG_PX<br>+= =C2=A0 =C2=A0 =C2=A0 || code =3D=3D AARCH64_UOP_SAVE_LRPAIR<br>+ =C2=A0 = =C2=A0 =C2=A0 || code =3D=3D AARCH64_UOP_SAVE_FREG<br>+ =C2=A0 =C2=A0 =C2= =A0 || code =3D=3D AARCH64_UOP_SAVE_FREG_X<br>+ =C2=A0 =C2=A0 =C2=A0 || co= de =3D=3D AARCH64_UOP_SAVE_FREG_P<br>+ =C2=A0 =C2=A0 =C2=A0 || code =3D=3D= AARCH64_UOP_SAVE_FREG_PX<br>+ =C2=A0 =C2=A0 =C2=A0 || code =3D=3D AARCH64= _UOP_ADD_FP)<br>=C2=A0 ret +=3D 2;<br>- break;<br>-<br>- =C2=A0 =C2=A0 =C2= =A0case UWOP_SAVE_NONVOL_FAR:<br>- =C2=A0 =C2=A0 =C2=A0case UWOP_SAVE_XMM12= 8_FAR:<br>+ =C2=A0 =C2=A0 =C2=A0else if (code =3D=3D AARCH64_UOP_ALLOC_LARG= E<br>+ =C2=A0 =C2=A0 =C2=A0 || code =3D=3D AARCH64_UOP_SAVE_ANY_REG_I<br>+= =C2=A0 =C2=A0 =C2=A0 || code =3D=3D AARCH64_UOP_SAVE_ANY_REG_IP<br>+ =C2= =A0 =C2=A0 =C2=A0 || code =3D=3D AARCH64_UOP_SAVE_ANY_REG_D<br>+ =C2=A0 = =C2=A0 =C2=A0 || code =3D=3D AARCH64_UOP_SAVE_ANY_REG_DP<br>+ =C2=A0 =C2= =A0 =C2=A0 || code =3D=3D AARCH64_UOP_SAVE_ANY_REG_Q<br>+ =C2=A0 =C2=A0 = =C2=A0 || code =3D=3D AARCH64_UOP_SAVE_ANY_REG_QP)<br>=C2=A0 ret +=3D 3;<br= >- break;<br>-<br>- =C2=A0 =C2=A0 =C2=A0case UWOP_ALLOC_LARGE:<br>- ret += =3D (c->elems[i].info ? 3 : 2);<br>- break;<br>-<br>- =C2=A0 =C2=A0 =C2= =A0default:<br>+ =C2=A0 =C2=A0 =C2=A0else<br>=C2=A0 abort ();<br>- =C2=A0 = =C2=A0 =C2=A0}<br>+ =C2=A0 =C2=A0}<br>=C2=A0<br>=C2=A0 =C2=A0return ret;<br= >=C2=A0}<br>=C2=A0<br>-/* Write out the xdata information for one function = (x64). =C2=A0*/<br>+/* Write out AArch64 prologue unwind codes. =C2=A0*/<br= >+static void<br>+seh_aarch64_write_prologue_data (const seh_context *c)<br= >+{<br>+ =C2=A0int i;<br>+<br>+ =C2=A0/* We have to store in reverse order.= =C2=A0*/<br>+ =C2=A0for (i =3D c->elems_count - 1; i >=3D 0; --i)<br= >+ =C2=A0 =C2=A0{<br>+ =C2=A0 =C2=A0 =C2=A0const seh_prologue_element *e = =3D c->elems + i;<br>+<br>+ =C2=A0 =C2=A0 =C2=A0switch (e->code)<br>+= {<br>+ case AARCH64_UOP_ALLOC_SMALL:<br>+ =C2=A0out_one (AARCH64_UOP_ALLO= C_SMALL | (e->info & 0x1f));<br>+ =C2=A0break;<br>+<br>+ case AARCH= 64_UOP_ALLOC_MEDIUM:<br>+ =C2=A0out_one (AARCH64_UOP_ALLOC_MEDIUM | ((e-&g= t;info >> 8) & 3));<br>+ =C2=A0out_one (e->info & 0xff);<= br>+ =C2=A0break;<br>+<br>+ case AARCH64_UOP_ALLOC_LARGE:<br>+ =C2=A0out_= one (AARCH64_UOP_ALLOC_LARGE);<br>+ =C2=A0out_two (e->off);<br>+ =C2= =A0break;<br>+<br>+ case AARCH64_UOP_SAVE_R19R20X:<br>+ =C2=A0out_one (AAR= CH64_UOP_SAVE_R19R20X | (e->info & 0x1f));<br>+ =C2=A0break;<br>+<b= r>+ case AARCH64_UOP_SAVE_FPLRX:<br>+ =C2=A0out_one (AARCH64_UOP_SAVE_FPLR= X | (e->info & 0x3f));<br>+ =C2=A0break;<br>+<br>+ case AARCH64_UOP= _SAVE_FPLR:<br>+ =C2=A0out_one (AARCH64_UOP_SAVE_FPLR | (e->info & = 0x3f));<br>+ =C2=A0break;<br>+<br>+ case AARCH64_UOP_SAVE_REG:<br>+ =C2= =A0{<br>+ =C2=A0 =C2=A0int r =3D e->info - 19;<br>+ =C2=A0 =C2=A0out_o= ne (AARCH64_UOP_SAVE_REG | ((r & 0xC) >> 2));<br>+ =C2=A0 =C2=A0= out_one (((r & 0x3) << 6) | ((e->off >> 3) & 0x3f));= <br>+ =C2=A0}<br>+ =C2=A0break;<br>+<br>+ case AARCH64_UOP_SAVE_REG_X:<br= >+ =C2=A0{<br>+ =C2=A0 =C2=A0int r =3D e->info - 19;<br>+ =C2=A0 =C2= =A0out_one (AARCH64_UOP_SAVE_REG_X | ((r & 0x8) >> 3));<br>+ =C2= =A0 =C2=A0out_one (((r & 0x7) << 5) | (((e->off >> 3) - = 1) & 0x1f));<br>+ =C2=A0}<br>+ =C2=A0break;<br>+<br>+ case AARCH64_UO= P_SAVE_REG_P:<br>+ =C2=A0{<br>+ =C2=A0 =C2=A0int r =3D e->info - 19;<b= r>+ =C2=A0 =C2=A0out_one (AARCH64_UOP_SAVE_REG_P | ((r & 0xC) >>= 2));<br>+ =C2=A0 =C2=A0out_one (((r & 0x3) << 6) | ((e->off = >> 3) & 0x3f));<br>+ =C2=A0}<br>+ =C2=A0break;<br>+<br>+ case A= ARCH64_UOP_SAVE_REG_PX:<br>+ =C2=A0{<br>+ =C2=A0 =C2=A0int r =3D e->in= fo - 19;<br>+ =C2=A0 =C2=A0out_one (AARCH64_UOP_SAVE_REG_PX | ((r & 0x= C) >> 2));<br>+ =C2=A0 =C2=A0out_one (((r & 0x3) << 6) | (= ((e->off >> 3) - 1) & 0x3f));<br>+ =C2=A0}<br>+ =C2=A0break;= <br>+<br>+ case AARCH64_UOP_SAVE_LRPAIR:<br>+ =C2=A0{<br>+ =C2=A0 =C2=A0i= nt r =3D e->info - 19;<br>+ =C2=A0 =C2=A0out_one (AARCH64_UOP_SAVE_LRPA= IR | ((r & 0xC) >> 2));<br>+ =C2=A0 =C2=A0out_one (((r & 0x3= ) << 6) | ((e->off >> 3) & 0x3f));<br>+ =C2=A0}<br>+ = =C2=A0break;<br>+<br>+ case AARCH64_UOP_SAVE_FREG:<br>+ =C2=A0{<br>+ =C2= =A0 =C2=A0int r =3D e->info - 8;<br>+ =C2=A0 =C2=A0out_one (AARCH64_UOP= _SAVE_FREG | ((r & 0x4) >> 2));<br>+ =C2=A0 =C2=A0out_one (((r &= amp; 0x3) << 6) | ((e->off >> 3) & 0x3f));<br>+ =C2=A0}= <br>+ =C2=A0break;<br>+<br>+ case AARCH64_UOP_SAVE_FREG_X:<br>+ =C2=A0{<b= r>+ =C2=A0 =C2=A0int r =3D e->info - 8;<br>+ =C2=A0 =C2=A0out_one (AAR= CH64_UOP_SAVE_FREG_X);<br>+ =C2=A0 =C2=A0out_one (((r & 0x7) << = 5) | (((e->off >> 3) - 1) & 0x1f));<br>+ =C2=A0}<br>+ =C2=A0= break;<br>+<br>+ case AARCH64_UOP_SAVE_FREG_P:<br>+ =C2=A0{<br>+ =C2=A0 = =C2=A0int r =3D e->info - 8;<br>+ =C2=A0 =C2=A0out_one (AARCH64_UOP_SAV= E_FREG_P | ((r & 0x4) >> 2));<br>+ =C2=A0 =C2=A0out_one (((r &am= p; 0x3) << 6) | ((e->off >> 3) & 0x3f));<br>+ =C2=A0}<b= r>+ =C2=A0break;<br>+<br>+ case AARCH64_UOP_SAVE_FREG_PX:<br>+ =C2=A0{<br= >+ =C2=A0 =C2=A0int r =3D e->info - 8;<br>+ =C2=A0 =C2=A0out_one (AARC= H64_UOP_SAVE_FREG_PX | ((r & 0x4) >> 2));<br>+ =C2=A0 =C2=A0out_= one (((r & 0x3) << 6) | (((e->off >> 3) - 1) & 0x3f)= );<br>+ =C2=A0}<br>+ =C2=A0break;<br>+<br>+ case AARCH64_UOP_SET_FP:<br>+= case AARCH64_UOP_NOP:<br>+ case AARCH64_UOP_END:<br>+ case AARCH64_UOP_SAV= E_NEXT:<br>+ case AARCH64_UOP_TRAP_FRAME:<br>+ case AARCH64_UOP_PUSH_MACH:<= br>+ case AARCH64_UOP_CONTEXT:<br>+ case AARCH64_UOP_EC_CONTEXT:<br>+ case = AARCH64_UOP_CLEAR_UNWOUND_TO_CALL:<br>+ case AARCH64_UOP_PAC_SIGN_LR:<br>+ = =C2=A0out_one (e->code);<br>+ =C2=A0break;<br>+<br>+ case AARCH64_UOP_= ADD_FP:<br>+ =C2=A0out_one (AARCH64_UOP_ADD_FP);<br>+ =C2=A0out_one (e-&g= t;info & 0xff);<br>+ =C2=A0break;<br>+<br>+ default:<br>+ =C2=A0abort= ();<br>+ }<br>+ =C2=A0 =C2=A0}<br>+<br>+ =C2=A0/* Terminate with END opcod= e. =C2=A0*/<br>+ =C2=A0out_one (AARCH64_UOP_END);<br>+}<br>=C2=A0<br>+/* Wr= ite the xdata for one AArch64 function. =C2=A0*/<br>=C2=A0static void<br>-s= eh_x64_write_function_xdata (seh_context *c)<br>+seh_aarch64_write_function= _xdata (seh_context *c)<br>=C2=A0{<br>- =C2=A0int flags, count_unwind_codes= ;<br>- =C2=A0expressionS exp;<br>+ =C2=A0int code_words, epilog_count;<br>+= =C2=A0unsigned int func_length;<br>=C2=A0<br>- =C2=A0/* Set 4-byte alignme= nt. =C2=A0*/<br>+ =C2=A0/* 4-byte alignment. =C2=A0*/<br>=C2=A0 =C2=A0frag_= align (2, 0, 0);<br>=C2=A0<br>=C2=A0 =C2=A0c->xdata_addr =3D symbol_temp= _new_now ();<br>- =C2=A0flags =3D c->handler_flags;<br>- =C2=A0count_unw= ind_codes =3D seh_x64_size_prologue_data (c);<br>=C2=A0<br>- =C2=A0/* ubyte= :3 version, ubyte:5 flags. =C2=A0*/<br>- =C2=A0out_one ((flags << 3) = | 1);<br>-<br>- =C2=A0/* Size of prologue. =C2=A0*/<br>- =C2=A0if (c->en= dprologue_addr)<br>+ =C2=A0/* Calculate function length in 4-byte units.=C2= =A0 Compute it from the<br>+ =C2=A0 =C2=A0 symbols' fragment positions = rather than resolve_expression, which<br>+ =C2=A0 =C2=A0 can fail when the = symbols span multiple fragments. =C2=A0*/<br>+ =C2=A0{<br>+ =C2=A0 =C2=A0ad= dressT off1, off2;<br>+ =C2=A0 =C2=A0fragS *f1 =3D symbol_get_frag_and_valu= e (c->start_addr, &off1);<br>+ =C2=A0 =C2=A0fragS *f2 =3D symbol_get= _frag_and_value (c->end_addr, &off2);<br>+ =C2=A0 =C2=A0long bytes = =3D 0;<br>+<br>+ =C2=A0 =C2=A0if (f1 =3D=3D f2)<br>+ =C2=A0 =C2=A0 =C2=A0by= tes =3D off2 - off1;<br>+ =C2=A0 =C2=A0else<br>+ =C2=A0 =C2=A0 =C2=A0{<br>+= /* Sum fragment sizes from f1 to f2. =C2=A0*/<br>+ bytes =3D off2;<br>+ fo= r (fragS *f =3D f1; f && f !=3D f2; f =3D f->fr_next)<br>+ =C2= =A0{<br>+ =C2=A0 =C2=A0if (!f->fr_next)<br>+ =C2=A0 =C2=A0 =C2=A0break= ;<br>+ =C2=A0 =C2=A0bytes +=3D f->fr_fix;<br>+ =C2=A0 =C2=A0if (f->= fr_var > 0)<br>+ =C2=A0 =C2=A0 =C2=A0bytes +=3D f->fr_var * f->fr= _subtype;<br>+ =C2=A0}<br>+ bytes -=3D off1;<br>+ =C2=A0 =C2=A0 =C2=A0}<br= >+ =C2=A0 =C2=A0func_length =3D bytes < 0 ? 0 : bytes >> 2;<br>+ = =C2=A0}<br>+<br>+ =C2=A0/* Count unwind code bytes, including the terminati= ng END. =C2=A0*/<br>+ =C2=A0int code_bytes =3D seh_aarch64_size_prologue_da= ta (c) + 1;<br>+ =C2=A0code_words =3D (code_bytes + 3) / 4;<br>+<br>+ =C2= =A0/* A function with no prologue codes only needs the END marker.<br>+ =C2= =A0 =C2=A0 In that case, code_words is 0 and no unwind code bytes are emitt= ed. =C2=A0*/<br>+ =C2=A0bool no_unwind_codes =3D (code_bytes =3D=3D 1);<br>= + =C2=A0if (no_unwind_codes)<br>+ =C2=A0 =C2=A0code_words =3D 0;<br>+<br>+ = =C2=A0/* Header word (Microsoft ARM64 SEH xdata format, matching LLVM MCWin= 64EH):<br>+ =C2=A0 =C2=A0 bits [0:17] =C2=A0=3D Function Length / 4 (18 bit= s)<br>+ =C2=A0 =C2=A0 bit =C2=A0[20] =C2=A0 =C2=A0=3D X (Exception Handler = Present)<br>+ =C2=A0 =C2=A0 bit =C2=A0[21] =C2=A0 =C2=A0=3D E (Packed Epilo= g Present)<br>+ =C2=A0 =C2=A0 bits [26:22] =3D Epilog Count (5 bits)<br>+ = =C2=A0 =C2=A0 bits [31:27] =3D Code Words (5 bits) */<br>+ =C2=A0epilog_cou= nt =3D 0;<br>+ =C2=A0unsigned int header =3D func_length & 0x3ffff;<br>= + =C2=A0if (code_words > 0x1f)<br>=C2=A0 =C2=A0 =C2=A0{<br>- =C2=A0 =C2= =A0 =C2=A0exp.X_op =3D O_subtract;<br>- =C2=A0 =C2=A0 =C2=A0exp.X_add_symbo= l =3D c->endprologue_addr;<br>- =C2=A0 =C2=A0 =C2=A0exp.X_op_symbol =3D = c->start_addr;<br>- =C2=A0 =C2=A0 =C2=A0exp.X_add_number =3D 0;<br>- =C2= =A0 =C2=A0 =C2=A0emit_expr (&exp, 1);<br>+ =C2=A0 =C2=A0 =C2=A0header |= =3D (0 << 27);<br>+ =C2=A0 =C2=A0 =C2=A0header |=3D ((epilog_count &a= mp; 0x1f) << 22);<br>=C2=A0 =C2=A0 =C2=A0}<br>=C2=A0 =C2=A0else<br>- = =C2=A0 =C2=A0out_one (0);<br>+ =C2=A0 =C2=A0{<br>+ =C2=A0 =C2=A0 =C2=A0head= er |=3D ((code_words & 0x1f) << 27);<br>+ =C2=A0 =C2=A0 =C2=A0hea= der |=3D ((epilog_count & 0x1f) << 22);<br>+ =C2=A0 =C2=A0}<br>+ = =C2=A0if (c->handler_flags & (UNW_FLAG_EHANDLER | UNW_FLAG_UHANDLER)= )<br>+ =C2=A0 =C2=A0header |=3D (1 << 20);<br>=C2=A0<br>- =C2=A0/* Nu= mber of slots (i.e. shorts) in the unwind codes array. =C2=A0*/<br>- =C2=A0= if (count_unwind_codes > 255)<br>- =C2=A0 =C2=A0as_fatal (_("too mu= ch unwind data in this .seh_proc"));<br>- =C2=A0out_one (count_unwind_= codes);<br>+ =C2=A0out_four (header);<br>=C2=A0<br>- =C2=A0/* ubyte:4 frame= -reg, ubyte:4 frame-reg-offset. =C2=A0*/<br>- =C2=A0/* Note that frameoff i= s already a multiple of 16, and therefore<br>- =C2=A0 =C2=A0 the offset is = already both scaled and shifted into place. =C2=A0*/<br>- =C2=A0out_one (c-= >frameoff | c->framereg);<br>+ =C2=A0/* If extended code words needed= , emit extension word.<br>+ =C2=A0 =C2=A0 bits [15:0] =3D Epilog Count, bit= s [23:16] =3D Code Words.<br>+ =C2=A0 =C2=A0 Also emit it when both the cod= e words and epilog count are zero:<br>+ =C2=A0 =C2=A0 in that case Windows = (and Wine) treat the packed fields as zero and<br>+ =C2=A0 =C2=A0 read the = actual values from the extension word. =C2=A0*/<br>+ =C2=A0if (code_words &= gt; 0x1f || no_unwind_codes)<br>+ =C2=A0 =C2=A0{<br>+ =C2=A0 =C2=A0 =C2=A0u= nsigned int ext =3D ((code_words & 0xff) << 16)<br>+ =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 |= (epilog_count & 0xffff);<br>+ =C2=A0 =C2=A0 =C2=A0out_four (ext);<br>+= =C2=A0 =C2=A0}<br>=C2=A0<br>- =C2=A0seh_x64_write_prologue_data (c);<br>+ = =C2=A0/* Write prologue unwind codes (skipped when no_unwind_codes). =C2=A0= */<br>+ =C2=A0if (!no_unwind_codes)<br>+ =C2=A0 =C2=A0seh_aarch64_write_pro= logue_data (c);<br>=C2=A0<br>- =C2=A0/* We need to align prologue data. =C2= =A0*/<br>- =C2=A0if (count_unwind_codes & 1)<br>- =C2=A0 =C2=A0out_two = (0);<br>+ =C2=A0/* Pad to 4-byte alignment.=C2=A0 Only needed when unwind c= odes are present. =C2=A0*/<br>+ =C2=A0if (!no_unwind_codes)<br>+ =C2=A0 =C2= =A0{<br>+ =C2=A0 =C2=A0 =C2=A0int remainder =3D (code_bytes) & 3;<br>+ = =C2=A0 =C2=A0 =C2=A0if (remainder)<br>+ =C2=A0 =C2=A0 =C2=A0 =C2=A0for (int= i =3D 0; i < 4 - remainder; i++)<br>+ =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0out_one (AARCH64_UOP_NOP);<br>+ =C2=A0 =C2=A0}<br>=C2=A0<br>- =C2=A0if (= flags & (UNW_FLAG_EHANDLER | UNW_FLAG_UHANDLER))<br>+ =C2=A0/* If excep= tion handler present, emit it. =C2=A0*/<br>+ =C2=A0if (c->handler_flags = & (UNW_FLAG_EHANDLER | UNW_FLAG_UHANDLER))<br>=C2=A0 =C2=A0 =C2=A0{<br>= - =C2=A0 =C2=A0 =C2=A0/* Force the use of segment-relative relocations inst= ead of absolute<br>- =C2=A0 =C2=A0 =C2=A0 =C2=A0 valued expressions.=C2=A0 = Don't adjust for constants (e.g. NULL). =C2=A0*/<br>=C2=A0 =C2=A0 =C2= =A0 =C2=A0if (c->handler.X_op =3D=3D O_symbol)<br>- =C2=A0 =C2=A0 =C2=A0= =C2=A0c->handler.X_op =3D O_symbol_rva;<br>+ c->handler.X_op =3D O_s= ymbol_rva;<br>=C2=A0 =C2=A0 =C2=A0 =C2=A0emit_expr (&c->handler, 4);= <br>=C2=A0 =C2=A0 =C2=A0}<br>=C2=A0<br>- =C2=A0/* Handler data will be tack= ed in here by subsections. =C2=A0*/<br>+ =C2=A0/* Handler data follows in s= ubsections. =C2=A0*/<br>=C2=A0}<br>=C2=A0<br>=C2=A0/* Write out xdata for o= ne function. =C2=A0*/<br>@@ -745,67 +1324,21 @@ write_function_xdata (seh_c= ontext *c)<br>=C2=A0 =C2=A0segT save_seg =3D now_seg;<br>=C2=A0 =C2=A0int s= ave_subseg =3D now_subseg;<br>=C2=A0<br>- =C2=A0/* MIPS, SH, ARM don't = have xdata. =C2=A0*/<br>- =C2=A0if (seh_get_target_kind () !=3D seh_kind_x6= 4)<br>- =C2=A0 =C2=A0return;<br>-<br>- =C2=A0switch_xdata (c->subsection= , c->code_seg);<br>-<br>- =C2=A0seh_x64_write_function_xdata (c);<br>+ = =C2=A0if (seh_get_target_kind () =3D=3D seh_kind_x64)<br>+ =C2=A0 =C2=A0{<b= r>+ =C2=A0 =C2=A0 =C2=A0switch_xdata (c->subsection, c->code_seg);<br= >+ =C2=A0 =C2=A0 =C2=A0seh_x64_write_function_xdata (c);<br>+ =C2=A0 =C2=A0= }<br>+ =C2=A0else if (seh_get_target_kind () =3D=3D seh_kind_aarch64)<br>+ = =C2=A0 =C2=A0{<br>+ =C2=A0 =C2=A0 =C2=A0switch_xdata (c->subsection, c-&= gt;code_seg);<br>+ =C2=A0 =C2=A0 =C2=A0seh_aarch64_write_function_xdata (c)= ;<br>+ =C2=A0 =C2=A0}<br>=C2=A0<br>=C2=A0 =C2=A0subseg_set (save_seg, save_= subseg);<br>=C2=A0}<br>=C2=A0<br>-/* Write pdata section data for one funct= ion (arm). =C2=A0*/<br>-<br>-static void<br>-seh_arm_write_function_pdata (= seh_context *c)<br>-{<br>- =C2=A0expressionS exp;<br>- =C2=A0unsigned int p= rol_len =3D 0, func_len =3D 0;<br>- =C2=A0unsigned int val;<br>-<br>- =C2= =A0/* Start address of the function. =C2=A0*/<br>- =C2=A0exp.X_op =3D O_sym= bol;<br>- =C2=A0exp.X_add_symbol =3D c->start_addr;<br>- =C2=A0exp.X_add= _number =3D 0;<br>- =C2=A0emit_expr (&exp, 4);<br>-<br>- =C2=A0exp.X_op= =3D O_subtract;<br>- =C2=A0exp.X_add_symbol =3D c->end_addr;<br>- =C2= =A0exp.X_op_symbol =3D c->start_addr;<br>- =C2=A0exp.X_add_number =3D 0;= <br>- =C2=A0if (resolve_expression (&exp) && exp.X_op =3D=3D O_= constant)<br>- =C2=A0 =C2=A0func_len =3D exp.X_add_number;<br>- =C2=A0else<= br>- =C2=A0 =C2=A0as_bad (_(".seh_endproc in a different section from = .seh_proc"));<br>-<br>- =C2=A0if (c->endprologue_addr)<br>- =C2=A0 = =C2=A0{<br>- =C2=A0 =C2=A0 =C2=A0exp.X_op =3D O_subtract;<br>- =C2=A0 =C2= =A0 =C2=A0exp.X_add_symbol =3D c->endprologue_addr;<br>- =C2=A0 =C2=A0 = =C2=A0exp.X_op_symbol =3D c->start_addr;<br>- =C2=A0 =C2=A0 =C2=A0exp.X_= add_number =3D 0;<br>-<br>- =C2=A0 =C2=A0 =C2=A0if (resolve_expression (&am= p;exp) && exp.X_op =3D=3D O_constant)<br>- prol_len =3D exp.X_add_n= umber;<br>- =C2=A0 =C2=A0 =C2=A0else<br>- as_bad (_(".seh_endprologue = in a different section from .seh_proc"));<br>- =C2=A0 =C2=A0}<br>-<br>= - =C2=A0/* Both function and prologue are in units of instructions. =C2=A0*= /<br>- =C2=A0func_len >>=3D (c->use_instruction_32 ? 2 : 1);<br>- = =C2=A0prol_len >>=3D (c->use_instruction_32 ? 2 : 1);<br>=C2=A0<br= >- =C2=A0/* Assemble the second word of the pdata. =C2=A0*/<br>- =C2=A0val = =C2=A0=3D prol_len & 0xff;<br>- =C2=A0val |=3D (func_len & 0x3fffff= ) << 8;<br>- =C2=A0if (c->use_instruction_32)<br>- =C2=A0 =C2=A0va= l |=3D 0x40000000U;<br>- =C2=A0if (c->handler_written)<br>- =C2=A0 =C2= =A0val |=3D 0x80000000U;<br>- =C2=A0out_four (val);<br>-}<br>=C2=A0<br>=C2= =A0/* Write out pdata for one function. =C2=A0*/<br>=C2=A0<br>@@ -858,6 +13= 91,17 @@ write_function_pdata (seh_context *c)<br>=C2=A0 =C2=A0 =C2=A0 =C2= =A0seh_arm_write_function_pdata (c);<br>=C2=A0 =C2=A0 =C2=A0 =C2=A0break;<b= r>=C2=A0<br>+ =C2=A0 =C2=A0case seh_kind_aarch64:<br>+ =C2=A0 =C2=A0 =C2=A0= exp.X_op =3D O_symbol_rva;<br>+ =C2=A0 =C2=A0 =C2=A0exp.X_add_number =3D 0;= <br>+ =C2=A0 =C2=A0 =C2=A0exp.X_add_symbol =3D c->start_addr;<br>+ =C2= =A0 =C2=A0 =C2=A0emit_expr (&exp, 4);<br>+ =C2=A0 =C2=A0 =C2=A0exp.X_op= =3D O_symbol_rva;<br>+ =C2=A0 =C2=A0 =C2=A0exp.X_add_number =3D 0;<br>+ = =C2=A0 =C2=A0 =C2=A0exp.X_add_symbol =3D c->xdata_addr;<br>+ =C2=A0 =C2= =A0 =C2=A0emit_expr (&exp, 4);<br>+ =C2=A0 =C2=A0 =C2=A0break;<br>+<br>= =C2=A0 =C2=A0 =C2=A0default:<br>=C2=A0 =C2=A0 =C2=A0 =C2=A0abort ();<br>=C2= =A0 =C2=A0 =C2=A0}<br>diff --git a/gas/config/obj-coff-seh.h b/gas/config/o= bj-coff-seh.h<br>index 8a3e1d602aa..f1b3535d138 100644<br>--- a/gas/config/= obj-coff-seh.h<br>+++ b/gas/config/obj-coff-seh.h<br>@@ -25,6 +25,8 @@<br>= =C2=A0 =C2=A0The third is the IA64 and x64 version. Note, the IA64 isn'= t implemented yet,<br>=C2=A0 =C2=A0but to find information about it, please= see specification about IA64 on<br>=C2=A0 =C2=A0<a href=3D"http://download= .intel.com/design/Itanium/Downloads/245358.pdf">http://download.intel.com/d= esign/Itanium/Downloads/245358.pdf</a> file.<br>+ =C2=A0The fourth is for A= Arch64 (ARM64) Windows, which uses the same pdata/xdata<br>+ =C2=A0model as= x64 but with different unwind codes and a 2-word pdata entry.<br>=C2=A0<br= >=C2=A0 =C2=A0The first version has just entries in the pdata section: Begi= nAddress,<br>=C2=A0 =C2=A0EndAddress, ExceptionHandler, HandlerData, and Pr= ologueEndAddress. Each<br>@@ -41,10 +43,14 @@<br>=C2=A0 =C2=A0prologue, exc= eption-handler, and additional SEH data is stored<br>=C2=A0 =C2=A0within th= e UNWIND_DATA field in the xdata section.<br>=C2=A0<br>+ =C2=A0The fourth (= AArch64/ARM64) version has a 2-word pdata entry:<br>+ =C2=A0BeginAddress (R= VA) and UnwindData (RVA), with xdata using ARM64-specific<br>+ =C2=A0unwind= codes.<br>+<br>=C2=A0 =C2=A0The pseudos:<br>=C2=A0 =C2=A0.seh_proc <fct= _name><br>=C2=A0 =C2=A0.seh_endprologue<br>- =C2=A0.seh_handler <hand= ler>[,@unwind][,@except] (x64)<br>+ =C2=A0.seh_handler <handler>[,= @unwind][,@except] (x64, aarch64)<br>=C2=A0 =C2=A0.seh_handler <handler&= gt;[,<handler_data>] (others)<br>=C2=A0 =C2=A0.seh_handlerdata<br>=C2= =A0 =C2=A0.seh_eh<br>@@ -57,6 +63,17 @@<br>=C2=A0 =C2=A0.seh_savexmm<br>=C2= =A0 =C2=A0.seh_pushframe<br>=C2=A0 =C2=A0.seh_code<br>+ =C2=A0.seh_save_reg= p <reg1>,<reg2>,<offset> (aarch64)<br>+ =C2=A0.seh_save_= fregp <reg1>,<reg2>,<offset> (aarch64)<br>+ =C2=A0.seh_sa= ve_reg <reg>,<offset> (aarch64)<br>+ =C2=A0.seh_save_freg <= ;reg>,<offset> (aarch64)<br>+ =C2=A0.seh_save_fplr <offset>= ; (aarch64)<br>+ =C2=A0.seh_save_fplr_x <offset> (aarch64)<br>+ = =C2=A0.seh_save_lrpair <reg>,<offset> (aarch64)<br>+ =C2=A0.se= h_set_fp (aarch64)<br>+ =C2=A0.seh_add_fp <offset> (aarch64)<b= r>+ =C2=A0.seh_nop (aarch64)<br>+ =C2=A0.seh_alloc_stack <size> = (aarch64)<br>=C2=A0*/<br>=C2=A0<br>=C2=A0#ifndef OBJ_COFF_SEH_H<br>@@ -78,= 7 +95,18 @@<br>=C2=A0 {"seh_no32", obj_coff_seh_32, 0}, \<br>=C2= =A0 {"seh_handler", obj_coff_seh_handler, 0}, \<br>=C2=A0 {"= seh_code", obj_coff_seh_code, 0}, \<br>- {"seh_handlerdata",= obj_coff_seh_handlerdata, 0},<br>+ {"seh_handlerdata", obj_coff_= seh_handlerdata, 0}, \<br>+ {"seh_save_regp", obj_coff_seh_aarch6= 4_save_regp, 0}, \<br>+ {"seh_save_fregp", obj_coff_seh_aarch64_s= ave_fregp, 0}, \<br>+ {"seh_save_reg", obj_coff_seh_aarch64_save_= reg, 0}, \<br>+ {"seh_save_freg", obj_coff_seh_aarch64_save_freg,= 0}, \<br>+ {"seh_save_fplr", obj_coff_seh_aarch64_save_fplr, 0},= \<br>+ {"seh_save_fplr_x", obj_coff_seh_aarch64_save_fplr_x, 0},= \<br>+ {"seh_save_lrpair", obj_coff_seh_aarch64_save_lrpair, 0},= \<br>+ {"seh_set_fp", obj_coff_seh_aarch64_set_fp, 0}, \<br>+ {&= quot;seh_add_fp", obj_coff_seh_aarch64_add_fp, 0}, \<br>+ {"seh_n= op", obj_coff_seh_aarch64_nop, 0}, \<br>+ {"seh_alloc_stack"= , obj_coff_seh_aarch64_alloc_stack, 0},<br>=C2=A0<br>=C2=A0/* Type definiti= ons. =C2=A0*/<br>=C2=A0<br>@@ -135,9 +163,44 @@ typedef enum seh_kind {<br>= =C2=A0 =C2=A0seh_kind_unknown =3D 0,<br>=C2=A0 =C2=A0seh_kind_mips =3D 1, = =C2=A0/* Used for MIPS and x86 pdata generation. =C2=A0*/<br>=C2=A0 =C2=A0s= eh_kind_arm =3D 2, =C2=A0 /* Used for ARM, PPC, SH3, and SH4 pdata (PDATA_E= H) generation. =C2=A0*/<br>- =C2=A0seh_kind_x64 =3D 3 =C2=A0 =C2=A0/* Used = for IA64 and x64 pdata/xdata generation. =C2=A0*/<br>+ =C2=A0seh_kind_x64 = =3D 3, =C2=A0 /* Used for IA64 and x64 pdata/xdata generation. =C2=A0*/<br>= + =C2=A0seh_kind_aarch64 =3D 4 /* Used for AArch64 (ARM64) Windows pdata/xd= ata generation. =C2=A0*/<br>=C2=A0} seh_kind;<br>=C2=A0<br>+/* AArch64 unwi= nd opcodes. =C2=A0*/<br>+#define AARCH64_UOP_ALLOC_SMALL =C2=A00x00<br>+#de= fine AARCH64_UOP_ALLOC_MEDIUM 0xC0<br>+#define AARCH64_UOP_ALLOC_LARGE =C2= =A00xE0<br>+#define AARCH64_UOP_SAVE_R19R20X 0x20<br>+#define AARCH64_UOP_S= AVE_FPLRX =C2=A0 0x80<br>+#define AARCH64_UOP_SAVE_FPLR =C2=A0 =C2=A00x40<b= r>+#define AARCH64_UOP_SAVE_REG =C2=A0 =C2=A0 0xD0<br>+#define AARCH64_UOP_= SAVE_REG_X =C2=A0 0xD4<br>+#define AARCH64_UOP_SAVE_REG_P =C2=A0 0xC8<br>+#= define AARCH64_UOP_SAVE_REG_PX =C2=A00xCC<br>+#define AARCH64_UOP_SAVE_LRPA= IR =C2=A00xD6<br>+#define AARCH64_UOP_SAVE_FREG =C2=A0 =C2=A00xDC<br>+#defi= ne AARCH64_UOP_SAVE_FREG_X =C2=A00xDE<br>+#define AARCH64_UOP_SAVE_FREG_P = =C2=A00xD8<br>+#define AARCH64_UOP_SAVE_FREG_PX 0xDA<br>+#define AARCH64_UO= P_SET_FP =C2=A0 =C2=A0 =C2=A0 0xE1<br>+#define AARCH64_UOP_ADD_FP =C2=A0 = =C2=A0 =C2=A0 0xE2<br>+#define AARCH64_UOP_NOP =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A00xE3<br>+#define AARCH64_UOP_END =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A00x= E4<br>+#define AARCH64_UOP_SAVE_NEXT =C2=A0 =C2=A00xE6<br>+#define AARCH64_= UOP_TRAP_FRAME =C2=A0 0xE8<br>+#define AARCH64_UOP_PUSH_MACH =C2=A0 =C2=A00= xE9<br>+#define AARCH64_UOP_CONTEXT =C2=A0 =C2=A0 =C2=A00xEA<br>+#define AA= RCH64_UOP_EC_CONTEXT =C2=A0 0xEB<br>+#define AARCH64_UOP_CLEAR_UNWOUND_TO_C= ALL 0xEC<br>+#define AARCH64_UOP_PAC_SIGN_LR =C2=A00xFC<br>+#define AARCH64= _UOP_SAVE_ANY_REG_I =C2=A0 0xE7<br>+#define AARCH64_UOP_SAVE_ANY_REG_IP =C2= =A00xE7<br>+#define AARCH64_UOP_SAVE_ANY_REG_D =C2=A0 0xE7<br>+#define AARC= H64_UOP_SAVE_ANY_REG_DP =C2=A00xE7<br>+#define AARCH64_UOP_SAVE_ANY_REG_Q = =C2=A0 0xE7<br>+#define AARCH64_UOP_SAVE_ANY_REG_QP =C2=A00xE7<br>+<br>=C2= =A0/* Forward declarations. =C2=A0*/<br>=C2=A0static void obj_coff_seh_stac= kalloc (int);<br>=C2=A0static void obj_coff_seh_setframe (int);<br>@@ -152,= 6 +215,17 @@ static void obj_coff_seh_proc =C2=A0(int);<br>=C2=A0static voi= d obj_coff_seh_handler (int);<br>=C2=A0static void obj_coff_seh_handlerdata= (int);<br>=C2=A0static void obj_coff_seh_code (int);<br>+static void obj_c= off_seh_aarch64_save_regp (int);<br>+static void obj_coff_seh_aarch64_save_= fregp (int);<br>+static void obj_coff_seh_aarch64_save_reg (int);<br>+stati= c void obj_coff_seh_aarch64_save_freg (int);<br>+static void obj_coff_seh_a= arch64_save_fplr (int);<br>+static void obj_coff_seh_aarch64_save_fplr_x (i= nt);<br>+static void obj_coff_seh_aarch64_save_lrpair (int);<br>+static voi= d obj_coff_seh_aarch64_set_fp (int);<br>+static void obj_coff_seh_aarch64_a= dd_fp (int);<br>+static void obj_coff_seh_aarch64_nop (int);<br>+static voi= d obj_coff_seh_aarch64_alloc_stack (int);<br>=C2=A0<br>=C2=A0#define UNDSEC= bfd_und_section_ptr<br>=C2=A0<br>-- <br>2.55.0<br><br></div> --000000000000038c3a06580f7f8b-- --000000000000038c3b06580f7f8d Content-Type: application/octet-stream; name="0001-gas-Add-AArch64-Windows-SEH-pdata-xdata-support.patch" Content-Disposition: attachment; filename="0001-gas-Add-AArch64-Windows-SEH-pdata-xdata-support.patch" Content-Transfer-Encoding: base64 Content-ID: <f_msbrtw6k0> X-Attachment-Id: f_msbrtw6k0 RnJvbSA3NzZlZTQzM2I1Y2QzZDc0ZDQzY2IzZmYwMDZlNDg0NTgzZjdiZWZmIE1vbiBTZXAgMTcg MDA6MDA6MDAgMjAwMQpGcm9tOiB0cmNyc2lyZWQgPG95emF3cWdjZmNAZ21haWwuY29tPgpEYXRl OiBUaHUsIDMwIEp1bCAyMDI2IDE2OjA2OjEyICswODAwClN1YmplY3Q6IFtQQVRDSF0gZ2FzOiBB ZGQgQUFyY2g2NCBXaW5kb3dzIFNFSCAocGRhdGEveGRhdGEpIHN1cHBvcnQKCkltcGxlbWVudCBX aW5kb3dzIGV4Y2VwdGlvbi1oYW5kbGluZyAoU0VIKSB1bndpbmQgaW5mbyBnZW5lcmF0aW9uIGZv cgp0aGUgYWFyY2g2NC13NjQtbWluZ3czMiB0YXJnZXQgaW4gR0FTLgoKVGhlIGV4aXN0aW5nIG9i ai1jb2ZmLXNlaC5jIG9ubHkgaGFuZGxlZCB4NjQuICBUaGlzIGFkZHMgZnVsbCBBQXJjaDY0CnN1 cHBvcnQ6CgoqIC5zZWhfcHJvYy8uc2VoX2VuZHByb2xvZ3VlIGFuZCBhbGwgQUFyY2g2NCB1bndp bmQgZGlyZWN0aXZlcwogICguc2VoX2FsbG9jX3N0YWNrLCAuc2VoX3NhdmVfZnBsci94LCAuc2Vo X3NhdmVfcmVnL3AvcF94LAogIC5zZWhfc2F2ZV9mcmVnL3AvcF94LCAuc2VoX3NhdmVfbHJwYWly LCAuc2VoX3NldF9mcCwgLnNlaF9hZGRfZnAsCiAgLnNlaF9oYW5kbGVyLCBldGMuKQoqIENvcnJl Y3QgeGRhdGEgaGVhZGVyIGxheW91dCAoRnVuY3Rpb25MZW5ndGggLyBDb2RlV29yZHMgLyBFcGls b2dDb3VudCAvCiAgRSAvIFggYml0cykgbWF0Y2hpbmcgdGhlIE1TIEFSTTY0IGZvcm1hdAoqIEVt aXQgdGhlIHhkYXRhIGV4dGVuc2lvbiB3b3JkIHdoZW4gQ29kZVdvcmRzPT0wIGFuZCBFcGlsb2dD b3VudD09MCBzbwogIFdpbmRvd3MgZXhjZXB0aW9uIHBhcnNlcnMgZG8gbm90IG1pc3JlYWQgdGhl IG5leHQgZW50cnkKKiBDb3JyZWN0IG9wY29kZSBlbmNvZGluZ3MgZm9yIHJlZ2lzdGVyIHNhdmUg cGFpcnMgKHNhdmVfcmVncCBldGMuKQoqIEZ1bmN0aW9uIGxlbmd0aCBjb21wdXRlZCBmcm9tIGZy YWdtZW50IHBvc2l0aW9ucyBpbnN0ZWFkIG9mCiAgcmVzb2x2ZV9leHByZXNzaW9uLCB3aGljaCBm YWlsZWQgYWNyb3NzIGZyYWdtZW50cwotLS0KIGdhcy9jb25maWcvb2JqLWNvZmYtc2VoLmMgfCA4 ODQgKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrLS0tLS0tLS0KIGdhcy9jb25maWcvb2Jq LWNvZmYtc2VoLmggfCAgODAgKysrLQogMiBmaWxlcyBjaGFuZ2VkLCA3OTEgaW5zZXJ0aW9ucygr KSwgMTczIGRlbGV0aW9ucygtKQoKZGlmZiAtLWdpdCBhL2dhcy9jb25maWcvb2JqLWNvZmYtc2Vo LmMgYi9nYXMvY29uZmlnL29iai1jb2ZmLXNlaC5jCmluZGV4IDFhYzY0ZjhmOWJhLi4xMTNjN2E5 YjJiNiAxMDA2NDQKLS0tIGEvZ2FzL2NvbmZpZy9vYmotY29mZi1zZWguYworKysgYi9nYXMvY29u ZmlnL29iai1jb2ZmLXNlaC5jCkBAIC00Myw2ICs0Myw4IEBAIHNlaF9nZXRfdGFyZ2V0X2tpbmQg KHZvaWQpCiAgIHN3aXRjaCAoYmZkX2dldF9hcmNoIChzdGRvdXRwdXQpKQogICAgIHsKICAgICBj YXNlIGJmZF9hcmNoX2FhcmNoNjQ6CisgICAgICByZXR1cm4gc2VoX2tpbmRfYWFyY2g2NDsKKwog ICAgIGNhc2UgYmZkX2FyY2hfYXJtOgogICAgIGNhc2UgYmZkX2FyY2hfcG93ZXJwYzoKICAgICBj YXNlIGJmZF9hcmNoX3NoOgpAQCAtMTc2LDcgKzE3OCw4IEBAIG9ial9jb2ZmX3NlaF9oYW5kbGVy IChpbnQgd2hhdCBBVFRSSUJVVEVfVU5VU0VEKQogICBpZiAoIXNraXBfd2hpdGVzcGFjZV9hbmRf Y29tbWEgKDApKQogICAgIHJldHVybjsKIAotICBpZiAoc2VoX2dldF90YXJnZXRfa2luZCAoKSA9 PSBzZWhfa2luZF94NjQpCisgIGlmIChzZWhfZ2V0X3RhcmdldF9raW5kICgpID09IHNlaF9raW5k X3g2NAorICAgICAgfHwgc2VoX2dldF90YXJnZXRfa2luZCAoKSA9PSBzZWhfa2luZF9hYXJjaDY0 KQogICAgIHsKICAgICAgIGRvCiAJewpAQCAtMjA4LDcgKzIxMSw3IEBAIG9ial9jb2ZmX3NlaF9o YW5kbGVyIChpbnQgd2hhdCBBVFRSSUJVVEVfVU5VU0VEKQogc3RhdGljIHZvaWQKIG9ial9jb2Zm X3NlaF9oYW5kbGVyZGF0YSAoaW50IHdoYXQgQVRUUklCVVRFX1VOVVNFRCkKIHsKLSAgaWYgKCF2 ZXJpZnlfY29udGV4dF9hbmRfdGFyZ2V0ICgiLnNlaF9oYW5kbGVyZGF0YSIsIHNlaF9raW5kX3g2 NCkpCisgIGlmICghdmVyaWZ5X2NvbnRleHRfYW5kX3RhcmdldCAoIi5zZWhfaGFuZGxlcmRhdGEi LCBzZWhfZ2V0X3RhcmdldF9raW5kICgpKSkKICAgICByZXR1cm47CiAgIGRlbWFuZF9lbXB0eV9y ZXN0X29mX2xpbmUgKCk7CiAKQEAgLTIxNyw2ICsyMjAsNDYgQEAgb2JqX2NvZmZfc2VoX2hhbmRs ZXJkYXRhIChpbnQgd2hhdCBBVFRSSUJVVEVfVU5VU0VEKQogCiAvKiBNYXJrIGVuZCBvZiBjdXJy ZW50IGNvbnRleHQuICAqLwogCitzdGF0aWMgdm9pZAorb3V0X29uZSAoaW50IGJ5dGUpCit7Cisg IGNoYXIgKnAgPSBmcmFnX21vcmUgKDEpOworICBtZF9udW1iZXJfdG9fY2hhcnMgKHAsIGJ5dGUs IDEpOworfQorCitzdGF0aWMgdm9pZAorb3V0X3R3byAoaW50IGRhdGEpCit7CisgIGNoYXIgKnAg PSBmcmFnX21vcmUgKDIpOworICBtZF9udW1iZXJfdG9fY2hhcnMgKHAsIGRhdGEsIDIpOworfQor CitzdGF0aWMgdm9pZAorb3V0X2ZvdXIgKGludCBkYXRhKQoreworICBjaGFyICpwID0gZnJhZ19t b3JlICg0KTsKKyAgbWRfbnVtYmVyX3RvX2NoYXJzIChwLCBkYXRhLCA0KTsKK30KKworLyogV3Jp dGUgeGRhdGEgZm9yIGFuIHg2NCBmdW5jdGlvbiAocGFzc3Rocm91Z2ggdG8gZXhpc3RpbmcKKyAg IHhkYXRhIG91dHB1dCB2aWEgcHJvbG9ndWUgZWxlbWVudHMpLiAgKi8KKworc3RhdGljIHZvaWQK K3NlaF94NjRfd3JpdGVfZnVuY3Rpb25feGRhdGEgKHNlaF9jb250ZXh0ICpjIEFUVFJJQlVURV9V TlVTRUQpCit7CisgIC8qIFRoZSB4NjQgeGRhdGEgaXMgYWxyZWFkeSBlbWl0dGVkIGluY3JlbWVu dGFsbHkgYXMgcHJvbG9ndWUKKyAgICAgZWxlbWVudHMgYXJlIHByb2Nlc3NlZDsgdGhpcyBmdW5j dGlvbiBpcyBhIG5vLW9wIHBsYWNlaG9sZGVyCisgICAgIGZvciBjb25zaXN0ZW5jeSB3aXRoIHRo ZSBhYXJjaDY0IGRpc3BhdGNoLiAgKi8KK30KKworLyogV3JpdGUgcGRhdGEgZm9yIGFuIEFSTSAo V2luQ0Utc3R5bGUpIGZ1bmN0aW9uIChuby1vcCBzdHViKS4gICovCisKK3N0YXRpYyB2b2lkCitz ZWhfYXJtX3dyaXRlX2Z1bmN0aW9uX3BkYXRhIChzZWhfY29udGV4dCAqYyBBVFRSSUJVVEVfVU5V U0VEKQoreworICBhYm9ydCAoKTsKK30KKwogc3RhdGljIHZvaWQKIGRvX3NlaF9lbmRwcm9jICh2 b2lkKQogewpAQCAtMjcyLDcgKzMxNSw4IEBAIG9ial9jb2ZmX3NlaF9wcm9jIChpbnQgd2hhdCBB VFRSSUJVVEVfVU5VU0VEKQogCiAgIHNlaF9jdHhfY3VyLT5jb2RlX3NlZyA9IG5vd19zZWc7CiAK LSAgaWYgKHNlaF9nZXRfdGFyZ2V0X2tpbmQgKCkgPT0gc2VoX2tpbmRfeDY0KQorICBpZiAoc2Vo X2dldF90YXJnZXRfa2luZCAoKSA9PSBzZWhfa2luZF94NjQKKyAgICAgIHx8IHNlaF9nZXRfdGFy Z2V0X2tpbmQgKCkgPT0gc2VoX2tpbmRfYWFyY2g2NCkKICAgICB7CiAgICAgICB4X3NlZ2N1ciA9 IHNlaF9oYXNoX2ZpbmRfb3JfbWFrZSAoc2VoX2N0eF9jdXItPmNvZGVfc2VnLCAiLnhkYXRhIik7 CiAgICAgICBzZWhfY3R4X2N1ci0+c3Vic2VjdGlvbiA9IHhfc2VnY3VyLT5zdWJzZWc7CkBAIC01 NjUsMTc2ICs2MDksNzExIEBAIG9ial9jb2ZmX3NlaF9zZXRmcmFtZSAoaW50IHdoYXQgQVRUUklC VVRFX1VOVVNFRCkKICAgICAgIHNlaF94NjRfbWFrZV9wcm9sb2d1ZV9lbGVtZW50IChVV09QX1NF VF9GUFJFRywgMCwgMCk7CiAgICAgfQogfQotDAotLyogRGF0YSB3cml0aW5nIHJvdXRpbmVzLiAg Ki8KIAotLyogT3V0cHV0IHJhdyBpbnRlZ2VycyBpbiAxLCAyLCBvciA0IGJ5dGVzLiAgKi8KKy8q IEFBcmNoNjQgc3VwcG9ydC4gICovCisKKy8qIEFBcmNoNjQgcmVnaXN0ZXIgbmFtZSB0YWJsZXMu ICAqLworc3RhdGljIGNvbnN0IGNoYXIgKiBjb25zdCBhYXJjaDY0X2ludF9yZWdzWzMxXSA9IHsK KyAgIngwIiwgIngxIiwgIngyIiwgIngzIiwgIng0IiwgIng1IiwgIng2IiwgIng3IiwKKyAgIng4 IiwgIng5IiwgIngxMCIsICJ4MTEiLCAieDEyIiwgIngxMyIsICJ4MTQiLCAieDE1IiwKKyAgIngx NiIsICJ4MTciLCAieDE4IiwgIngxOSIsICJ4MjAiLCAieDIxIiwgIngyMiIsICJ4MjMiLAorICAi eDI0IiwgIngyNSIsICJ4MjYiLCAieDI3IiwgIngyOCIsICJ4MjkiLCAieDMwIgorfTsKKworc3Rh dGljIGNvbnN0IGNoYXIgKiBjb25zdCBhYXJjaDY0X2ZwX3JlZ3NbMzJdID0geworICAiZDAiLCAi ZDEiLCAiZDIiLCAiZDMiLCAiZDQiLCAiZDUiLCAiZDYiLCAiZDciLAorICAiZDgiLCAiZDkiLCAi ZDEwIiwgImQxMSIsICJkMTIiLCAiZDEzIiwgImQxNCIsICJkMTUiLAorICAiZDE2IiwgImQxNyIs ICJkMTgiLCAiZDE5IiwgImQyMCIsICJkMjEiLCAiZDIyIiwgImQyMyIsCisgICJkMjQiLCAiZDI1 IiwgImQyNiIsICJkMjciLCAiZDI4IiwgImQyOSIsICJkMzAiLCAiZDMxIgorfTsKKworLyogUmVh ZCBhbiBBQXJjaDY0IGludGVnZXIgcmVnaXN0ZXIgZnJvbSBpbnB1dCBzdHJlYW0uCisgICBSZXR1 cm5zIHRoZSByZWdpc3RlciBudW1iZXIgKDAtMzApIG9yIC0xIG9uIGVycm9yLgorICAgQWxzbyBh Y2NlcHRzICJmcCIgKHgyOSkgYW5kICJsciIgKHgzMCkuICAqLworc3RhdGljIGludAorc2VoX2Fh cmNoNjRfcmVhZF9pbnRfcmVnIChjb25zdCBjaGFyICpkaXJlY3RpdmUsIGludCBtaW5fcmVnLCBp bnQgbWF4X3JlZykKK3sKKyAgY2hhciBuYW1lX2VuZDsKKyAgY2hhciAqc3ltYm9sX25hbWU7Cisg IGludCBpOworCisgIFNLSVBfV0hJVEVTUEFDRSAoKTsKKyAgbmFtZV9lbmQgPSBnZXRfc3ltYm9s X25hbWUgKCZzeW1ib2xfbmFtZSk7CiAKLXN0YXRpYyBpbmxpbmUgdm9pZAotb3V0X29uZSAoaW50 IGJ5dGUpCisgIC8qIENoZWNrIGZvciBzcGVjaWFsIG5hbWVzLiAgKi8KKyAgaWYgKHN0cmNhc2Vj bXAgKHN5bWJvbF9uYW1lLCAiZnAiKSA9PSAwKQorICAgIGkgPSAyOTsKKyAgZWxzZSBpZiAoc3Ry Y2FzZWNtcCAoc3ltYm9sX25hbWUsICJsciIpID09IDApCisgICAgaSA9IDMwOworICBlbHNlCisg ICAgeworICAgICAgZm9yIChpID0gMDsgaSA8IDMxOyBpKyspCisJaWYgKCFzdHJjYXNlY21wIChh YXJjaDY0X2ludF9yZWdzW2ldLCBzeW1ib2xfbmFtZSkpCisJICBicmVhazsKKyAgICB9CisKKyAg KHZvaWQpIHJlc3RvcmVfbGluZV9wb2ludGVyIChuYW1lX2VuZCk7CisKKyAgaWYgKGkgPiBtYXhf cmVnIHx8IGkgPCBtaW5fcmVnKQorICAgIHsKKyAgICAgIGFzX2JhZCAoXygiaW52YWxpZCByZWdp c3RlciBmb3IgJXMiKSwgZGlyZWN0aXZlKTsKKyAgICAgIHJldHVybiAtMTsKKyAgICB9CisKKyAg cmV0dXJuIGk7Cit9CisKKy8qIFJlYWQgYW4gQUFyY2g2NCBGUC9TSU1EIHJlZ2lzdGVyIGZyb20g aW5wdXQgc3RyZWFtLgorICAgUmV0dXJucyB0aGUgcmVnaXN0ZXIgbnVtYmVyICgwLTMxKSBvciAt MSBvbiBlcnJvci4gICovCitzdGF0aWMgaW50CitzZWhfYWFyY2g2NF9yZWFkX2ZwX3JlZyAoY29u c3QgY2hhciAqZGlyZWN0aXZlKQogewotICBGUkFHX0FQUEVORF8xX0NIQVIgKGJ5dGUpOworICBj aGFyIG5hbWVfZW5kOworICBjaGFyICpzeW1ib2xfbmFtZTsKKyAgaW50IGk7CisKKyAgU0tJUF9X SElURVNQQUNFICgpOworICBuYW1lX2VuZCA9IGdldF9zeW1ib2xfbmFtZSAoJnN5bWJvbF9uYW1l KTsKKworICBmb3IgKGkgPSAwOyBpIDwgMzI7IGkrKykKKyAgICBpZiAoIXN0cmNhc2VjbXAgKGFh cmNoNjRfZnBfcmVnc1tpXSwgc3ltYm9sX25hbWUpKQorICAgICAgYnJlYWs7CisKKyAgKHZvaWQp IHJlc3RvcmVfbGluZV9wb2ludGVyIChuYW1lX2VuZCk7CisKKyAgaWYgKGkgPT0gMzIpCisgICAg eworICAgICAgYXNfYmFkIChfKCJpbnZhbGlkIGZsb2F0aW5nLXBvaW50IHJlZ2lzdGVyIGZvciAl cyIpLCBkaXJlY3RpdmUpOworICAgICAgcmV0dXJuIC0xOworICAgIH0KKworICByZXR1cm4gaTsK IH0KIAotc3RhdGljIGlubGluZSB2b2lkCi1vdXRfdHdvIChpbnQgZGF0YSkKKy8qIEFkZCBhIHBy b2xvZ3VlIGVsZW1lbnQgdG8gdGhlIEFBcmNoNjQgU0VIIGNvbnRleHQuICAqLworc3RhdGljIHZv aWQKK3NlaF9hYXJjaDY0X21ha2VfcHJvbG9ndWVfZWxlbWVudCAoaW50IGNvZGUsIGludCBpbmZv LCBvZmZzZXRUIG9mZikKIHsKLSAgbWRfbnVtYmVyX3RvX2NoYXJzIChmcmFnX21vcmUgKDIpLCBk YXRhLCAyKTsKKyAgc2VoX3Byb2xvZ3VlX2VsZW1lbnQgKm47CisKKyAgaWYgKHNlaF9jdHhfY3Vy ID09IE5VTEwpCisgICAgcmV0dXJuOworICBpZiAoc2VoX2N0eF9jdXItPmVsZW1zX2NvdW50ID09 IHNlaF9jdHhfY3VyLT5lbGVtc19tYXgpCisgICAgeworICAgICAgc2VoX2N0eF9jdXItPmVsZW1z X21heCArPSA4OworICAgICAgc2VoX2N0eF9jdXItPmVsZW1zID0gWFJFU0laRVZFQyAoc2VoX3By b2xvZ3VlX2VsZW1lbnQsCisJCQkJICAgICAgIHNlaF9jdHhfY3VyLT5lbGVtcywKKwkJCQkgICAg ICAgc2VoX2N0eF9jdXItPmVsZW1zX21heCk7CisgICAgfQorCisgIG4gPSAmc2VoX2N0eF9jdXIt PmVsZW1zW3NlaF9jdHhfY3VyLT5lbGVtc19jb3VudCsrXTsKKyAgbi0+Y29kZSA9IGNvZGU7Cisg IG4tPmluZm8gPSBpbmZvOworICBuLT5vZmYgPSBvZmY7CisgIG4tPnBjX2FkZHIgPSBzeW1ib2xf dGVtcF9uZXdfbm93ICgpOwogfQogCi1zdGF0aWMgaW5saW5lIHZvaWQKLW91dF9mb3VyIChpbnQg ZGF0YSkKKy8qIC5zZWhfc2F2ZV9yZWdwIDxyZWcxPiwgPHJlZzI+LCA8b2Zmc2V0PiAoYWFyY2g2 NCkKKyAgIFNhdmUgcmVnaXN0ZXIgcGFpciBhdCBvZmZzZXQgZnJvbSBTUC4gICovCitzdGF0aWMg dm9pZAorb2JqX2NvZmZfc2VoX2FhcmNoNjRfc2F2ZV9yZWdwIChpbnQgd2hhdCBBVFRSSUJVVEVf VU5VU0VEKQogewotICBtZF9udW1iZXJfdG9fY2hhcnMgKGZyYWdfbW9yZSAoNCksIGRhdGEsIDQp OworICBpbnQgcmVnMSwgcmVnMjsKKyAgb2Zmc2V0VCBvZmY7CisKKyAgaWYgKCF2ZXJpZnlfY29u dGV4dF9hbmRfdGFyZ2V0ICgiLnNlaF9zYXZlX3JlZ3AiLCBzZWhfa2luZF9hYXJjaDY0KQorICAg ICAgfHwgIXNlaF92YWxpZGF0ZV9zZWcgKCIuc2VoX3NhdmVfcmVncCIpKQorICAgIHJldHVybjsK KworICByZWcxID0gc2VoX2FhcmNoNjRfcmVhZF9pbnRfcmVnICgiLnNlaF9zYXZlX3JlZ3AiLCAw LCAzMCk7CisgIGlmICghc2tpcF93aGl0ZXNwYWNlX2FuZF9jb21tYSAoMSkpCisgICAgcmV0dXJu OworICByZWcyID0gc2VoX2FhcmNoNjRfcmVhZF9pbnRfcmVnICgiLnNlaF9zYXZlX3JlZ3AiLCAw LCAzMCk7CisgIGlmICghc2tpcF93aGl0ZXNwYWNlX2FuZF9jb21tYSAoMSkpCisgICAgcmV0dXJu OworICBvZmYgPSBnZXRfYWJzb2x1dGVfZXhwcmVzc2lvbiAoKTsKKyAgZGVtYW5kX2VtcHR5X3Jl c3Rfb2ZfbGluZSAoKTsKKworICBpZiAocmVnMSA8IDAgfHwgcmVnMiA8IDApCisgICAgcmV0dXJu OworICBpZiAob2ZmIDwgMCB8fCAob2ZmICYgNykpCisgICAgeworICAgICAgYXNfYmFkIChfKCIu c2VoX3NhdmVfcmVncCBvZmZzZXQgbXVzdCBiZSBub24tbmVnYXRpdmUgYW5kIDgtYnl0ZSBhbGln bmVkIikpOworICAgICAgcmV0dXJuOworICAgIH0KKworICAvKiBDaGVjayBmb3Igc3BlY2lhbCBj YXNlOiBzYXZpbmcgeDI5LHgzMCAoRlBMUiBwYWlyKS4gICovCisgIGlmIChyZWcxID09IDI5ICYm IHJlZzIgPT0gMzApCisgICAgeworICAgICAgaWYgKG9mZiA8PSAweDNGICogOCkKKwl7CisJICBz ZWhfYWFyY2g2NF9tYWtlX3Byb2xvZ3VlX2VsZW1lbnQgKEFBUkNINjRfVU9QX1NBVkVfRlBMUiwg b2ZmID4+IDMsIDApOworCSAgcmV0dXJuOworCX0KKyAgICB9CisKKyAgc2VoX2FhcmNoNjRfbWFr ZV9wcm9sb2d1ZV9lbGVtZW50IChBQVJDSDY0X1VPUF9TQVZFX1JFR19QLCByZWcxLCBvZmYpOwog fQogCi0vKiBXcml0ZSBvdXQgcHJvbG9ndWUgZGF0YSBmb3IgeDY0LiAgKi8KKy8qIC5zZWhfc2F2 ZV9mcmVncCA8cmVnMT4sIDxyZWcyPiwgPG9mZnNldD4gKGFhcmNoNjQpCisgICBTYXZlIEZQL1NJ TUQgcmVnaXN0ZXIgcGFpci4gICovCitzdGF0aWMgdm9pZAorb2JqX2NvZmZfc2VoX2FhcmNoNjRf c2F2ZV9mcmVncCAoaW50IHdoYXQgQVRUUklCVVRFX1VOVVNFRCkKK3sKKyAgaW50IHJlZzEsIHJl ZzI7CisgIG9mZnNldFQgb2ZmOworCisgIGlmICghdmVyaWZ5X2NvbnRleHRfYW5kX3RhcmdldCAo Ii5zZWhfc2F2ZV9mcmVncCIsIHNlaF9raW5kX2FhcmNoNjQpCisgICAgICB8fCAhc2VoX3ZhbGlk YXRlX3NlZyAoIi5zZWhfc2F2ZV9mcmVncCIpKQorICAgIHJldHVybjsKKworICByZWcxID0gc2Vo X2FhcmNoNjRfcmVhZF9mcF9yZWcgKCIuc2VoX3NhdmVfZnJlZ3AiKTsKKyAgaWYgKCFza2lwX3do aXRlc3BhY2VfYW5kX2NvbW1hICgxKSkKKyAgICByZXR1cm47CisgIHJlZzIgPSBzZWhfYWFyY2g2 NF9yZWFkX2ZwX3JlZyAoIi5zZWhfc2F2ZV9mcmVncCIpOworICBpZiAoIXNraXBfd2hpdGVzcGFj ZV9hbmRfY29tbWEgKDEpKQorICAgIHJldHVybjsKKyAgb2ZmID0gZ2V0X2Fic29sdXRlX2V4cHJl c3Npb24gKCk7CisgIGRlbWFuZF9lbXB0eV9yZXN0X29mX2xpbmUgKCk7CisKKyAgaWYgKHJlZzEg PCAwIHx8IHJlZzIgPCAwKQorICAgIHJldHVybjsKKyAgaWYgKG9mZiA8IDAgfHwgKG9mZiAmIDcp KQorICAgIHsKKyAgICAgIGFzX2JhZCAoXygiLnNlaF9zYXZlX2ZyZWdwIG9mZnNldCBtdXN0IGJl IG5vbi1uZWdhdGl2ZSBhbmQgOC1ieXRlIGFsaWduZWQiKSk7CisgICAgICByZXR1cm47CisgICAg fQorCisgIHNlaF9hYXJjaDY0X21ha2VfcHJvbG9ndWVfZWxlbWVudCAoQUFSQ0g2NF9VT1BfU0FW RV9GUkVHX1AsIHJlZzEsIG9mZik7Cit9CiAKKy8qIC5zZWhfc2F2ZV9yZWcgPHJlZz4sIDxvZmZz ZXQ+IChhYXJjaDY0KQorICAgU2F2ZSBhIHNpbmdsZSBpbnRlZ2VyIHJlZ2lzdGVyLiAgKi8KIHN0 YXRpYyB2b2lkCi1zZWhfeDY0X3dyaXRlX3Byb2xvZ3VlX2RhdGEgKGNvbnN0IHNlaF9jb250ZXh0 ICpjKQorb2JqX2NvZmZfc2VoX2FhcmNoNjRfc2F2ZV9yZWcgKGludCB3aGF0IEFUVFJJQlVURV9V TlVTRUQpCiB7Ci0gIGludCBpOworICBpbnQgcmVnOworICBvZmZzZXRUIG9mZjsKIAotICAvKiBX ZSBoYXZlIHRvIHN0b3JlIGluIHJldmVyc2Ugb3JkZXIuICAqLwotICBmb3IgKGkgPSBjLT5lbGVt c19jb3VudCAtIDE7IGkgPj0gMDsgLS1pKQorICBpZiAoIXZlcmlmeV9jb250ZXh0X2FuZF90YXJn ZXQgKCIuc2VoX3NhdmVfcmVnIiwgc2VoX2tpbmRfYWFyY2g2NCkKKyAgICAgIHx8ICFzZWhfdmFs aWRhdGVfc2VnICgiLnNlaF9zYXZlX3JlZyIpKQorICAgIHJldHVybjsKKworICByZWcgPSBzZWhf YWFyY2g2NF9yZWFkX2ludF9yZWcgKCIuc2VoX3NhdmVfcmVnIiwgMCwgMzApOworICBpZiAoIXNr aXBfd2hpdGVzcGFjZV9hbmRfY29tbWEgKDEpKQorICAgIHJldHVybjsKKyAgb2ZmID0gZ2V0X2Fi c29sdXRlX2V4cHJlc3Npb24gKCk7CisgIGRlbWFuZF9lbXB0eV9yZXN0X29mX2xpbmUgKCk7CisK KyAgaWYgKHJlZyA8IDApCisgICAgcmV0dXJuOworICBpZiAob2ZmIDwgMCB8fCAob2ZmICYgNykp CiAgICAgewotICAgICAgY29uc3Qgc2VoX3Byb2xvZ3VlX2VsZW1lbnQgKmUgPSBjLT5lbGVtcyAr IGk7Ci0gICAgICBleHByZXNzaW9uUyBleHA7CisgICAgICBhc19iYWQgKF8oIi5zZWhfc2F2ZV9y ZWcgb2Zmc2V0IG11c3QgYmUgbm9uLW5lZ2F0aXZlIGFuZCA4LWJ5dGUgYWxpZ25lZCIpKTsKKyAg ICAgIHJldHVybjsKKyAgICB9CiAKLSAgICAgIC8qIEZpcnN0IGNvbWVzIGJ5dGUgb2Zmc2V0IGlu IGNvZGUuICAqLwotICAgICAgZXhwLlhfb3AgPSBPX3N1YnRyYWN0OwotICAgICAgZXhwLlhfYWRk X3N5bWJvbCA9IGUtPnBjX2FkZHI7Ci0gICAgICBleHAuWF9vcF9zeW1ib2wgPSBjLT5zdGFydF9h ZGRyOwotICAgICAgZXhwLlhfYWRkX251bWJlciA9IDA7Ci0gICAgICBlbWl0X2V4cHIgKCZleHAs IDEpOworICBzZWhfYWFyY2g2NF9tYWtlX3Byb2xvZ3VlX2VsZW1lbnQgKEFBUkNINjRfVU9QX1NB VkVfUkVHLCByZWcsIG9mZik7Cit9CiAKLSAgICAgIC8qIFNlY29uZCBjb21lcyBjb2RlK2luZm8g cGFja2VkIGludG8gYSBieXRlLiAgKi8KLSAgICAgIG91dF9vbmUgKChlLT5pbmZvIDw8IDQpIHwg ZS0+Y29kZSk7CisvKiAuc2VoX3NhdmVfZnJlZyA8cmVnPiwgPG9mZnNldD4gKGFhcmNoNjQpCisg ICBTYXZlIGEgc2luZ2xlIEZQL1NJTUQgcmVnaXN0ZXIuICAqLworc3RhdGljIHZvaWQKK29ial9j b2ZmX3NlaF9hYXJjaDY0X3NhdmVfZnJlZyAoaW50IHdoYXQgQVRUUklCVVRFX1VOVVNFRCkKK3sK KyAgaW50IHJlZzsKKyAgb2Zmc2V0VCBvZmY7CiAKLSAgICAgIHN3aXRjaCAoZS0+Y29kZSkKLQl7 Ci0JY2FzZSBVV09QX1BVU0hfTk9OVk9MOgotCWNhc2UgVVdPUF9BTExPQ19TTUFMTDoKLQljYXNl IFVXT1BfU0VUX0ZQUkVHOgotCWNhc2UgVVdPUF9QVVNIX01BQ0hGUkFNRToKLQkgIC8qIFRoZXNl IGhhdmUgbm8gZXh0cmEgZGF0YS4gICovCi0JICBicmVhazsKKyAgaWYgKCF2ZXJpZnlfY29udGV4 dF9hbmRfdGFyZ2V0ICgiLnNlaF9zYXZlX2ZyZWciLCBzZWhfa2luZF9hYXJjaDY0KQorICAgICAg fHwgIXNlaF92YWxpZGF0ZV9zZWcgKCIuc2VoX3NhdmVfZnJlZyIpKQorICAgIHJldHVybjsKIAot CWNhc2UgVVdPUF9BTExPQ19MQVJHRToKLQkgIGlmIChlLT5pbmZvKQotCSAgICB7Ci0JY2FzZSBV V09QX1NBVkVfTk9OVk9MX0ZBUjoKLQljYXNlIFVXT1BfU0FWRV9YTU0xMjhfRkFSOgotCSAgICAg IC8qIEFuIHVuc2NhbGVkIDQgYnl0ZSBvZmZzZXQuICAqLwotCSAgICAgIG91dF9mb3VyIChlLT5v ZmYpOwotCSAgICAgIGJyZWFrOwotCSAgICB9Ci0JICAvKiBGQUxMVEhSVSAqLworICByZWcgPSBz ZWhfYWFyY2g2NF9yZWFkX2ZwX3JlZyAoIi5zZWhfc2F2ZV9mcmVnIik7CisgIGlmICghc2tpcF93 aGl0ZXNwYWNlX2FuZF9jb21tYSAoMSkpCisgICAgcmV0dXJuOworICBvZmYgPSBnZXRfYWJzb2x1 dGVfZXhwcmVzc2lvbiAoKTsKKyAgZGVtYW5kX2VtcHR5X3Jlc3Rfb2ZfbGluZSAoKTsKIAotCWNh c2UgVVdPUF9TQVZFX05PTlZPTDoKLQljYXNlIFVXT1BfU0FWRV9YTU0xMjg6Ci0JICAvKiBBIHNj YWxlZCAyIGJ5dGUgb2Zmc2V0LiAgKi8KLQkgIG91dF90d28gKGUtPm9mZik7Ci0JICBicmVhazsK KyAgaWYgKHJlZyA8IDApCisgICAgcmV0dXJuOworICBpZiAob2ZmIDwgMCB8fCAob2ZmICYgNykp CisgICAgeworICAgICAgYXNfYmFkIChfKCIuc2VoX3NhdmVfZnJlZyBvZmZzZXQgbXVzdCBiZSBu b24tbmVnYXRpdmUgYW5kIDgtYnl0ZSBhbGlnbmVkIikpOworICAgICAgcmV0dXJuOworICAgIH0K IAotCWRlZmF1bHQ6Ci0JICBhYm9ydCAoKTsKLQl9CisgIHNlaF9hYXJjaDY0X21ha2VfcHJvbG9n dWVfZWxlbWVudCAoQUFSQ0g2NF9VT1BfU0FWRV9GUkVHLCByZWcsIG9mZik7Cit9CisKKy8qIC5z ZWhfc2F2ZV9mcGxyIDxvZmZzZXQ+IChhYXJjaDY0KQorICAgU2F2ZSB4MjkgKEZQKSBhbmQgeDMw IChMUikgYXQgYSBwb3NpdGl2ZSBvZmZzZXQgZnJvbSBTUC4gICovCitzdGF0aWMgdm9pZAorb2Jq X2NvZmZfc2VoX2FhcmNoNjRfc2F2ZV9mcGxyIChpbnQgd2hhdCBBVFRSSUJVVEVfVU5VU0VEKQor eworICBvZmZzZXRUIG9mZjsKKworICBpZiAoIXZlcmlmeV9jb250ZXh0X2FuZF90YXJnZXQgKCIu c2VoX3NhdmVfZnBsciIsIHNlaF9raW5kX2FhcmNoNjQpCisgICAgICB8fCAhc2VoX3ZhbGlkYXRl X3NlZyAoIi5zZWhfc2F2ZV9mcGxyIikpCisgICAgcmV0dXJuOworCisgIG9mZiA9IGdldF9hYnNv bHV0ZV9leHByZXNzaW9uICgpOworICBkZW1hbmRfZW1wdHlfcmVzdF9vZl9saW5lICgpOworCisg IGlmIChvZmYgPCAwIHx8IChvZmYgJiA3KSkKKyAgICB7CisgICAgICBhc19iYWQgKF8oIi5zZWhf c2F2ZV9mcGxyIG9mZnNldCBtdXN0IGJlIG5vbi1uZWdhdGl2ZSBhbmQgOC1ieXRlIGFsaWduZWQi KSk7CisgICAgICByZXR1cm47CiAgICAgfQorCisgIHNlaF9hYXJjaDY0X21ha2VfcHJvbG9ndWVf ZWxlbWVudCAoQUFSQ0g2NF9VT1BfU0FWRV9GUExSLCBvZmYgPj4gMywgMCk7CiB9CiAKKy8qIC5z ZWhfc2F2ZV9mcGxyX3ggPG9mZnNldD4gKGFhcmNoNjQpCisgICBTYXZlIHgyOSAoRlApIGFuZCB4 MzAgKExSKSB3aXRoIHByZWRlY3JlbWVudCAoc3RwIHgyOSwgeDMwLCBbc3AsICMtTl0hKS4gICov CitzdGF0aWMgdm9pZAorb2JqX2NvZmZfc2VoX2FhcmNoNjRfc2F2ZV9mcGxyX3ggKGludCB3aGF0 IEFUVFJJQlVURV9VTlVTRUQpCit7CisgIG9mZnNldFQgb2ZmOworCisgIGlmICghdmVyaWZ5X2Nv bnRleHRfYW5kX3RhcmdldCAoIi5zZWhfc2F2ZV9mcGxyX3giLCBzZWhfa2luZF9hYXJjaDY0KQor ICAgICAgfHwgIXNlaF92YWxpZGF0ZV9zZWcgKCIuc2VoX3NhdmVfZnBscl94IikpCisgICAgcmV0 dXJuOworCisgIG9mZiA9IGdldF9hYnNvbHV0ZV9leHByZXNzaW9uICgpOworICBkZW1hbmRfZW1w dHlfcmVzdF9vZl9saW5lICgpOworCisgIGlmIChvZmYgPCAwIHx8IChvZmYgJiAxNSkpCisgICAg eworICAgICAgYXNfYmFkIChfKCIuc2VoX3NhdmVfZnBscl94IG9mZnNldCBtdXN0IGJlIG5lZ2F0 aXZlIGFuZCAxNi1ieXRlIGFsaWduZWQiKSk7CisgICAgICByZXR1cm47CisgICAgfQorICBpZiAo b2ZmID4gMHgzRiAqIDgpCisgICAgeworICAgICAgYXNfYmFkIChfKCIuc2VoX3NhdmVfZnBscl94 IG9mZnNldCBvdXQgb2YgcmFuZ2UgKG1heCA1MDQpIikpOworICAgICAgcmV0dXJuOworICAgIH0K KworICBzZWhfYWFyY2g2NF9tYWtlX3Byb2xvZ3VlX2VsZW1lbnQgKEFBUkNINjRfVU9QX1NBVkVf RlBMUlgsIChvZmYgPj4gMykgLSAxLCAwKTsKK30KKworLyogLnNlaF9zYXZlX2xycGFpciA8cmVn PiwgPG9mZnNldD4gKGFhcmNoNjQpCisgICBTYXZlIHgzMCAoTFIpIGFuZCBhbm90aGVyIHJlZ2lz dGVyIGF0IG9mZnNldCBmcm9tIFNQLiAgKi8KK3N0YXRpYyB2b2lkCitvYmpfY29mZl9zZWhfYWFy Y2g2NF9zYXZlX2xycGFpciAoaW50IHdoYXQgQVRUUklCVVRFX1VOVVNFRCkKK3sKKyAgaW50IHJl ZzsKKyAgb2Zmc2V0VCBvZmY7CisKKyAgaWYgKCF2ZXJpZnlfY29udGV4dF9hbmRfdGFyZ2V0ICgi LnNlaF9zYXZlX2xycGFpciIsIHNlaF9raW5kX2FhcmNoNjQpCisgICAgICB8fCAhc2VoX3ZhbGlk YXRlX3NlZyAoIi5zZWhfc2F2ZV9scnBhaXIiKSkKKyAgICByZXR1cm47CisKKyAgcmVnID0gc2Vo X2FhcmNoNjRfcmVhZF9pbnRfcmVnICgiLnNlaF9zYXZlX2xycGFpciIsIDAsIDI4KTsKKyAgaWYg KCFza2lwX3doaXRlc3BhY2VfYW5kX2NvbW1hICgxKSkKKyAgICByZXR1cm47CisgIG9mZiA9IGdl dF9hYnNvbHV0ZV9leHByZXNzaW9uICgpOworICBkZW1hbmRfZW1wdHlfcmVzdF9vZl9saW5lICgp OworCisgIGlmIChyZWcgPCAwKQorICAgIHJldHVybjsKKyAgaWYgKG9mZiA8IDAgfHwgKG9mZiAm IDcpKQorICAgIHsKKyAgICAgIGFzX2JhZCAoXygiLnNlaF9zYXZlX2xycGFpciBvZmZzZXQgbXVz dCBiZSBub24tbmVnYXRpdmUgYW5kIDgtYnl0ZSBhbGlnbmVkIikpOworICAgICAgcmV0dXJuOwor ICAgIH0KKworICBzZWhfYWFyY2g2NF9tYWtlX3Byb2xvZ3VlX2VsZW1lbnQgKEFBUkNINjRfVU9Q X1NBVkVfTFJQQUlSLCAocmVnIC0gMTkpID4+IDEsIG9mZiA+PiAzKTsKK30KKworLyogLnNlaF9z ZXRfZnAgKGFhcmNoNjQpCisgICBTZXQgZnJhbWUgcG9pbnRlciAobW92IHgyOSwgc3ApLiAgKi8K K3N0YXRpYyB2b2lkCitvYmpfY29mZl9zZWhfYWFyY2g2NF9zZXRfZnAgKGludCB3aGF0IEFUVFJJ QlVURV9VTlVTRUQpCit7CisgIGlmICghdmVyaWZ5X2NvbnRleHRfYW5kX3RhcmdldCAoIi5zZWhf c2V0X2ZwIiwgc2VoX2tpbmRfYWFyY2g2NCkKKyAgICAgIHx8ICFzZWhfdmFsaWRhdGVfc2VnICgi LnNlaF9zZXRfZnAiKSkKKyAgICByZXR1cm47CisgIGRlbWFuZF9lbXB0eV9yZXN0X29mX2xpbmUg KCk7CisKKyAgc2VoX2FhcmNoNjRfbWFrZV9wcm9sb2d1ZV9lbGVtZW50IChBQVJDSDY0X1VPUF9T RVRfRlAsIDAsIDApOworfQorCisvKiAuc2VoX2FkZF9mcCA8b2Zmc2V0PiAoYWFyY2g2NCkKKyAg IEFkZCBvZmZzZXQgdG8gZnJhbWUgcG9pbnRlciAoYWRkIHgyOSwgc3AsICNOKS4gICovCitzdGF0 aWMgdm9pZAorb2JqX2NvZmZfc2VoX2FhcmNoNjRfYWRkX2ZwIChpbnQgd2hhdCBBVFRSSUJVVEVf VU5VU0VEKQoreworICBvZmZzZXRUIG9mZjsKKworICBpZiAoIXZlcmlmeV9jb250ZXh0X2FuZF90 YXJnZXQgKCIuc2VoX2FkZF9mcCIsIHNlaF9raW5kX2FhcmNoNjQpCisgICAgICB8fCAhc2VoX3Zh bGlkYXRlX3NlZyAoIi5zZWhfYWRkX2ZwIikpCisgICAgcmV0dXJuOworCisgIG9mZiA9IGdldF9h YnNvbHV0ZV9leHByZXNzaW9uICgpOworICBkZW1hbmRfZW1wdHlfcmVzdF9vZl9saW5lICgpOwor CisgIHNlaF9hYXJjaDY0X21ha2VfcHJvbG9ndWVfZWxlbWVudCAoQUFSQ0g2NF9VT1BfQUREX0ZQ LCBvZmYgPj4gMywgMCk7Cit9CisKKy8qIC5zZWhfbm9wIChhYXJjaDY0KQorICAgTm8tb3AgcGFk ZGluZyBpbiB0aGUgdW53aW5kIGNvZGUuICAqLworc3RhdGljIHZvaWQKK29ial9jb2ZmX3NlaF9h YXJjaDY0X25vcCAoaW50IHdoYXQgQVRUUklCVVRFX1VOVVNFRCkKK3sKKyAgaWYgKCF2ZXJpZnlf Y29udGV4dF9hbmRfdGFyZ2V0ICgiLnNlaF9ub3AiLCBzZWhfa2luZF9hYXJjaDY0KQorICAgICAg fHwgIXNlaF92YWxpZGF0ZV9zZWcgKCIuc2VoX25vcCIpKQorICAgIHJldHVybjsKKyAgZGVtYW5k X2VtcHR5X3Jlc3Rfb2ZfbGluZSAoKTsKKworICBzZWhfYWFyY2g2NF9tYWtlX3Byb2xvZ3VlX2Vs ZW1lbnQgKEFBUkNINjRfVU9QX05PUCwgMCwgMCk7Cit9CisKKy8qIC5zZWhfYWxsb2Nfc3RhY2sg PHNpemU+IChhYXJjaDY0KQorICAgQWxsb2NhdGUgc3RhY2sgc3BhY2UuICAqLworc3RhdGljIHZv aWQKK29ial9jb2ZmX3NlaF9hYXJjaDY0X2FsbG9jX3N0YWNrIChpbnQgd2hhdCBBVFRSSUJVVEVf VU5VU0VEKQoreworICBvZmZzZXRUIG9mZjsKKyAgaW50IGNvZGUsIGluZm87CisKKyAgaWYgKCF2 ZXJpZnlfY29udGV4dF9hbmRfdGFyZ2V0ICgiLnNlaF9hbGxvY19zdGFjayIsIHNlaF9raW5kX2Fh cmNoNjQpCisgICAgICB8fCAhc2VoX3ZhbGlkYXRlX3NlZyAoIi5zZWhfYWxsb2Nfc3RhY2siKSkK KyAgICByZXR1cm47CisKKyAgb2ZmID0gZ2V0X2Fic29sdXRlX2V4cHJlc3Npb24gKCk7CisgIGRl bWFuZF9lbXB0eV9yZXN0X29mX2xpbmUgKCk7CisKKyAgaWYgKG9mZiA9PSAwKQorICAgIHJldHVy bjsKKyAgaWYgKG9mZiA8IDApCisgICAgeworICAgICAgYXNfYmFkIChfKCIuc2VoX2FsbG9jX3N0 YWNrIG9mZnNldCBpcyBuZWdhdGl2ZSIpKTsKKyAgICAgIHJldHVybjsKKyAgICB9CisKKyAgaWYg KChvZmYgJiAxNSkgPT0gMCAmJiBvZmYgPD0gMHgxRiAqIDE2KQorICAgIHsKKyAgICAgIGNvZGUg PSBBQVJDSDY0X1VPUF9BTExPQ19TTUFMTDsKKyAgICAgIGluZm8gPSAob2ZmIC8gMTYpIC0gMTsK KyAgICB9CisgIGVsc2UgaWYgKChvZmYgJiAxNSkgPT0gMCAmJiBvZmYgPD0gMHg3RkYgKiAxNikK KyAgICB7CisgICAgICBjb2RlID0gQUFSQ0g2NF9VT1BfQUxMT0NfTUVESVVNOworICAgICAgaW5m byA9IG9mZiAvIDE2OworICAgIH0KKyAgZWxzZSBpZiAoKG9mZiAmIDE1KSA9PSAwICYmIG9mZiA8 PSAob2Zmc2V0VCkgMHhGRkZGRkYgKiAxNikKKyAgICB7CisgICAgICBjb2RlID0gQUFSQ0g2NF9V T1BfQUxMT0NfTEFSR0U7CisgICAgICBpbmZvID0gMDsKKyAgICAgIG9mZiA9IG9mZiAvIDE2Owor ICAgIH0KKyAgZWxzZQorICAgIHsKKyAgICAgIGFzX2JhZCAoXygiLnNlaF9hbGxvY19zdGFjayBv ZmZzZXQgb3V0IG9mIHJhbmdlIikpOworICAgICAgcmV0dXJuOworICAgIH0KKworICBzZWhfYWFy Y2g2NF9tYWtlX3Byb2xvZ3VlX2VsZW1lbnQgKGNvZGUsIGluZm8sIG9mZik7Cit9CisKKy8qIEFB cmNoNjQgeGRhdGEgd3JpdGluZy4gICovCisKKy8qIENvdW50IHRoZSBzaXplIG9mIEFBcmNoNjQg dW53aW5kIGNvZGUgZGF0YSBpbiBieXRlcy4gICovCiBzdGF0aWMgaW50Ci1zZWhfeDY0X3NpemVf cHJvbG9ndWVfZGF0YSAoY29uc3Qgc2VoX2NvbnRleHQgKmMpCitzZWhfYWFyY2g2NF9zaXplX3By b2xvZ3VlX2RhdGEgKGNvbnN0IHNlaF9jb250ZXh0ICpjKQogewogICBpbnQgaSwgcmV0ID0gMDsK IAogICBmb3IgKGkgPSBjLT5lbGVtc19jb3VudCAtIDE7IGkgPj0gMDsgLS1pKQotICAgIHN3aXRj aCAoYy0+ZWxlbXNbaV0uY29kZSkKLSAgICAgIHsKLSAgICAgIGNhc2UgVVdPUF9QVVNIX05PTlZP TDoKLSAgICAgIGNhc2UgVVdPUF9BTExPQ19TTUFMTDoKLSAgICAgIGNhc2UgVVdPUF9TRVRfRlBS RUc6Ci0gICAgICBjYXNlIFVXT1BfUFVTSF9NQUNIRlJBTUU6CisgICAgeworICAgICAgaW50IGNv ZGUgPSBjLT5lbGVtc1tpXS5jb2RlOworICAgICAgaWYgKGNvZGUgPT0gQUFSQ0g2NF9VT1BfQUxM T0NfU01BTEwKKwkgIHx8IGNvZGUgPT0gQUFSQ0g2NF9VT1BfU0FWRV9SMTlSMjBYCisJICB8fCBj b2RlID09IEFBUkNINjRfVU9QX1NBVkVfRlBMUlgKKwkgIHx8IGNvZGUgPT0gQUFSQ0g2NF9VT1Bf U0FWRV9GUExSCisJICB8fCBjb2RlID09IEFBUkNINjRfVU9QX1NFVF9GUAorCSAgfHwgY29kZSA9 PSBBQVJDSDY0X1VPUF9OT1AKKwkgIHx8IGNvZGUgPT0gQUFSQ0g2NF9VT1BfRU5ECisJICB8fCBj b2RlID09IEFBUkNINjRfVU9QX1NBVkVfTkVYVAorCSAgfHwgY29kZSA9PSBBQVJDSDY0X1VPUF9U UkFQX0ZSQU1FCisJICB8fCBjb2RlID09IEFBUkNINjRfVU9QX1BVU0hfTUFDSAorCSAgfHwgY29k ZSA9PSBBQVJDSDY0X1VPUF9DT05URVhUCisJICB8fCBjb2RlID09IEFBUkNINjRfVU9QX0VDX0NP TlRFWFQKKwkgIHx8IGNvZGUgPT0gQUFSQ0g2NF9VT1BfQ0xFQVJfVU5XT1VORF9UT19DQUxMCisJ ICB8fCBjb2RlID09IEFBUkNINjRfVU9QX1BBQ19TSUdOX0xSKQogCXJldCArPSAxOwotCWJyZWFr OwotCi0gICAgICBjYXNlIFVXT1BfU0FWRV9OT05WT0w6Ci0gICAgICBjYXNlIFVXT1BfU0FWRV9Y TU0xMjg6CisgICAgICBlbHNlIGlmIChjb2RlID09IEFBUkNINjRfVU9QX0FMTE9DX01FRElVTQor CSAgICAgICB8fCBjb2RlID09IEFBUkNINjRfVU9QX1NBVkVfUkVHCisJICAgICAgIHx8IGNvZGUg PT0gQUFSQ0g2NF9VT1BfU0FWRV9SRUdfWAorCSAgICAgICB8fCBjb2RlID09IEFBUkNINjRfVU9Q X1NBVkVfUkVHX1AKKwkgICAgICAgfHwgY29kZSA9PSBBQVJDSDY0X1VPUF9TQVZFX1JFR19QWAor CSAgICAgICB8fCBjb2RlID09IEFBUkNINjRfVU9QX1NBVkVfTFJQQUlSCisJICAgICAgIHx8IGNv ZGUgPT0gQUFSQ0g2NF9VT1BfU0FWRV9GUkVHCisJICAgICAgIHx8IGNvZGUgPT0gQUFSQ0g2NF9V T1BfU0FWRV9GUkVHX1gKKwkgICAgICAgfHwgY29kZSA9PSBBQVJDSDY0X1VPUF9TQVZFX0ZSRUdf UAorCSAgICAgICB8fCBjb2RlID09IEFBUkNINjRfVU9QX1NBVkVfRlJFR19QWAorCSAgICAgICB8 fCBjb2RlID09IEFBUkNINjRfVU9QX0FERF9GUCkKIAlyZXQgKz0gMjsKLQlicmVhazsKLQotICAg ICAgY2FzZSBVV09QX1NBVkVfTk9OVk9MX0ZBUjoKLSAgICAgIGNhc2UgVVdPUF9TQVZFX1hNTTEy OF9GQVI6CisgICAgICBlbHNlIGlmIChjb2RlID09IEFBUkNINjRfVU9QX0FMTE9DX0xBUkdFCisJ ICAgICAgIHx8IGNvZGUgPT0gQUFSQ0g2NF9VT1BfU0FWRV9BTllfUkVHX0kKKwkgICAgICAgfHwg Y29kZSA9PSBBQVJDSDY0X1VPUF9TQVZFX0FOWV9SRUdfSVAKKwkgICAgICAgfHwgY29kZSA9PSBB QVJDSDY0X1VPUF9TQVZFX0FOWV9SRUdfRAorCSAgICAgICB8fCBjb2RlID09IEFBUkNINjRfVU9Q X1NBVkVfQU5ZX1JFR19EUAorCSAgICAgICB8fCBjb2RlID09IEFBUkNINjRfVU9QX1NBVkVfQU5Z X1JFR19RCisJICAgICAgIHx8IGNvZGUgPT0gQUFSQ0g2NF9VT1BfU0FWRV9BTllfUkVHX1FQKQog CXJldCArPSAzOwotCWJyZWFrOwotCi0gICAgICBjYXNlIFVXT1BfQUxMT0NfTEFSR0U6Ci0JcmV0 ICs9IChjLT5lbGVtc1tpXS5pbmZvID8gMyA6IDIpOwotCWJyZWFrOwotCi0gICAgICBkZWZhdWx0 OgorICAgICAgZWxzZQogCWFib3J0ICgpOwotICAgICAgfQorICAgIH0KIAogICByZXR1cm4gcmV0 OwogfQogCi0vKiBXcml0ZSBvdXQgdGhlIHhkYXRhIGluZm9ybWF0aW9uIGZvciBvbmUgZnVuY3Rp b24gKHg2NCkuICAqLworLyogV3JpdGUgb3V0IEFBcmNoNjQgcHJvbG9ndWUgdW53aW5kIGNvZGVz LiAgKi8KK3N0YXRpYyB2b2lkCitzZWhfYWFyY2g2NF93cml0ZV9wcm9sb2d1ZV9kYXRhIChjb25z dCBzZWhfY29udGV4dCAqYykKK3sKKyAgaW50IGk7CisKKyAgLyogV2UgaGF2ZSB0byBzdG9yZSBp biByZXZlcnNlIG9yZGVyLiAgKi8KKyAgZm9yIChpID0gYy0+ZWxlbXNfY291bnQgLSAxOyBpID49 IDA7IC0taSkKKyAgICB7CisgICAgICBjb25zdCBzZWhfcHJvbG9ndWVfZWxlbWVudCAqZSA9IGMt PmVsZW1zICsgaTsKKworICAgICAgc3dpdGNoIChlLT5jb2RlKQorCXsKKwljYXNlIEFBUkNINjRf VU9QX0FMTE9DX1NNQUxMOgorCSAgb3V0X29uZSAoQUFSQ0g2NF9VT1BfQUxMT0NfU01BTEwgfCAo ZS0+aW5mbyAmIDB4MWYpKTsKKwkgIGJyZWFrOworCisJY2FzZSBBQVJDSDY0X1VPUF9BTExPQ19N RURJVU06CisJICBvdXRfb25lIChBQVJDSDY0X1VPUF9BTExPQ19NRURJVU0gfCAoKGUtPmluZm8g Pj4gOCkgJiAzKSk7CisJICBvdXRfb25lIChlLT5pbmZvICYgMHhmZik7CisJICBicmVhazsKKwor CWNhc2UgQUFSQ0g2NF9VT1BfQUxMT0NfTEFSR0U6CisJICBvdXRfb25lIChBQVJDSDY0X1VPUF9B TExPQ19MQVJHRSk7CisJICBvdXRfdHdvIChlLT5vZmYpOworCSAgYnJlYWs7CisKKwljYXNlIEFB UkNINjRfVU9QX1NBVkVfUjE5UjIwWDoKKwkgIG91dF9vbmUgKEFBUkNINjRfVU9QX1NBVkVfUjE5 UjIwWCB8IChlLT5pbmZvICYgMHgxZikpOworCSAgYnJlYWs7CisKKwljYXNlIEFBUkNINjRfVU9Q X1NBVkVfRlBMUlg6CisJICBvdXRfb25lIChBQVJDSDY0X1VPUF9TQVZFX0ZQTFJYIHwgKGUtPmlu Zm8gJiAweDNmKSk7CisJICBicmVhazsKKworCWNhc2UgQUFSQ0g2NF9VT1BfU0FWRV9GUExSOgor CSAgb3V0X29uZSAoQUFSQ0g2NF9VT1BfU0FWRV9GUExSIHwgKGUtPmluZm8gJiAweDNmKSk7CisJ ICBicmVhazsKKworCWNhc2UgQUFSQ0g2NF9VT1BfU0FWRV9SRUc6CisJICB7CisJICAgIGludCBy ID0gZS0+aW5mbyAtIDE5OworCSAgICBvdXRfb25lIChBQVJDSDY0X1VPUF9TQVZFX1JFRyB8ICgo ciAmIDB4QykgPj4gMikpOworCSAgICBvdXRfb25lICgoKHIgJiAweDMpIDw8IDYpIHwgKChlLT5v ZmYgPj4gMykgJiAweDNmKSk7CisJICB9CisJICBicmVhazsKKworCWNhc2UgQUFSQ0g2NF9VT1Bf U0FWRV9SRUdfWDoKKwkgIHsKKwkgICAgaW50IHIgPSBlLT5pbmZvIC0gMTk7CisJICAgIG91dF9v bmUgKEFBUkNINjRfVU9QX1NBVkVfUkVHX1ggfCAoKHIgJiAweDgpID4+IDMpKTsKKwkgICAgb3V0 X29uZSAoKChyICYgMHg3KSA8PCA1KSB8ICgoKGUtPm9mZiA+PiAzKSAtIDEpICYgMHgxZikpOwor CSAgfQorCSAgYnJlYWs7CisKKwljYXNlIEFBUkNINjRfVU9QX1NBVkVfUkVHX1A6CisJICB7CisJ ICAgIGludCByID0gZS0+aW5mbyAtIDE5OworCSAgICBvdXRfb25lIChBQVJDSDY0X1VPUF9TQVZF X1JFR19QIHwgKChyICYgMHhDKSA+PiAyKSk7CisJICAgIG91dF9vbmUgKCgociAmIDB4MykgPDwg NikgfCAoKGUtPm9mZiA+PiAzKSAmIDB4M2YpKTsKKwkgIH0KKwkgIGJyZWFrOworCisJY2FzZSBB QVJDSDY0X1VPUF9TQVZFX1JFR19QWDoKKwkgIHsKKwkgICAgaW50IHIgPSBlLT5pbmZvIC0gMTk7 CisJICAgIG91dF9vbmUgKEFBUkNINjRfVU9QX1NBVkVfUkVHX1BYIHwgKChyICYgMHhDKSA+PiAy KSk7CisJICAgIG91dF9vbmUgKCgociAmIDB4MykgPDwgNikgfCAoKChlLT5vZmYgPj4gMykgLSAx KSAmIDB4M2YpKTsKKwkgIH0KKwkgIGJyZWFrOworCisJY2FzZSBBQVJDSDY0X1VPUF9TQVZFX0xS UEFJUjoKKwkgIHsKKwkgICAgaW50IHIgPSBlLT5pbmZvIC0gMTk7CisJICAgIG91dF9vbmUgKEFB UkNINjRfVU9QX1NBVkVfTFJQQUlSIHwgKChyICYgMHhDKSA+PiAyKSk7CisJICAgIG91dF9vbmUg KCgociAmIDB4MykgPDwgNikgfCAoKGUtPm9mZiA+PiAzKSAmIDB4M2YpKTsKKwkgIH0KKwkgIGJy ZWFrOworCisJY2FzZSBBQVJDSDY0X1VPUF9TQVZFX0ZSRUc6CisJICB7CisJICAgIGludCByID0g ZS0+aW5mbyAtIDg7CisJICAgIG91dF9vbmUgKEFBUkNINjRfVU9QX1NBVkVfRlJFRyB8ICgociAm IDB4NCkgPj4gMikpOworCSAgICBvdXRfb25lICgoKHIgJiAweDMpIDw8IDYpIHwgKChlLT5vZmYg Pj4gMykgJiAweDNmKSk7CisJICB9CisJICBicmVhazsKKworCWNhc2UgQUFSQ0g2NF9VT1BfU0FW RV9GUkVHX1g6CisJICB7CisJICAgIGludCByID0gZS0+aW5mbyAtIDg7CisJICAgIG91dF9vbmUg KEFBUkNINjRfVU9QX1NBVkVfRlJFR19YKTsKKwkgICAgb3V0X29uZSAoKChyICYgMHg3KSA8PCA1 KSB8ICgoKGUtPm9mZiA+PiAzKSAtIDEpICYgMHgxZikpOworCSAgfQorCSAgYnJlYWs7CisKKwlj YXNlIEFBUkNINjRfVU9QX1NBVkVfRlJFR19QOgorCSAgeworCSAgICBpbnQgciA9IGUtPmluZm8g LSA4OworCSAgICBvdXRfb25lIChBQVJDSDY0X1VPUF9TQVZFX0ZSRUdfUCB8ICgociAmIDB4NCkg Pj4gMikpOworCSAgICBvdXRfb25lICgoKHIgJiAweDMpIDw8IDYpIHwgKChlLT5vZmYgPj4gMykg JiAweDNmKSk7CisJICB9CisJICBicmVhazsKKworCWNhc2UgQUFSQ0g2NF9VT1BfU0FWRV9GUkVH X1BYOgorCSAgeworCSAgICBpbnQgciA9IGUtPmluZm8gLSA4OworCSAgICBvdXRfb25lIChBQVJD SDY0X1VPUF9TQVZFX0ZSRUdfUFggfCAoKHIgJiAweDQpID4+IDIpKTsKKwkgICAgb3V0X29uZSAo KChyICYgMHgzKSA8PCA2KSB8ICgoKGUtPm9mZiA+PiAzKSAtIDEpICYgMHgzZikpOworCSAgfQor CSAgYnJlYWs7CisKKwljYXNlIEFBUkNINjRfVU9QX1NFVF9GUDoKKwljYXNlIEFBUkNINjRfVU9Q X05PUDoKKwljYXNlIEFBUkNINjRfVU9QX0VORDoKKwljYXNlIEFBUkNINjRfVU9QX1NBVkVfTkVY VDoKKwljYXNlIEFBUkNINjRfVU9QX1RSQVBfRlJBTUU6CisJY2FzZSBBQVJDSDY0X1VPUF9QVVNI X01BQ0g6CisJY2FzZSBBQVJDSDY0X1VPUF9DT05URVhUOgorCWNhc2UgQUFSQ0g2NF9VT1BfRUNf Q09OVEVYVDoKKwljYXNlIEFBUkNINjRfVU9QX0NMRUFSX1VOV09VTkRfVE9fQ0FMTDoKKwljYXNl IEFBUkNINjRfVU9QX1BBQ19TSUdOX0xSOgorCSAgb3V0X29uZSAoZS0+Y29kZSk7CisJICBicmVh azsKKworCWNhc2UgQUFSQ0g2NF9VT1BfQUREX0ZQOgorCSAgb3V0X29uZSAoQUFSQ0g2NF9VT1Bf QUREX0ZQKTsKKwkgIG91dF9vbmUgKGUtPmluZm8gJiAweGZmKTsKKwkgIGJyZWFrOworCisJZGVm YXVsdDoKKwkgIGFib3J0ICgpOworCX0KKyAgICB9CisKKyAgLyogVGVybWluYXRlIHdpdGggRU5E IG9wY29kZS4gICovCisgIG91dF9vbmUgKEFBUkNINjRfVU9QX0VORCk7Cit9CiAKKy8qIFdyaXRl IHRoZSB4ZGF0YSBmb3Igb25lIEFBcmNoNjQgZnVuY3Rpb24uICAqLwogc3RhdGljIHZvaWQKLXNl aF94NjRfd3JpdGVfZnVuY3Rpb25feGRhdGEgKHNlaF9jb250ZXh0ICpjKQorc2VoX2FhcmNoNjRf d3JpdGVfZnVuY3Rpb25feGRhdGEgKHNlaF9jb250ZXh0ICpjKQogewotICBpbnQgZmxhZ3MsIGNv dW50X3Vud2luZF9jb2RlczsKLSAgZXhwcmVzc2lvblMgZXhwOworICBpbnQgY29kZV93b3Jkcywg ZXBpbG9nX2NvdW50OworICB1bnNpZ25lZCBpbnQgZnVuY19sZW5ndGg7CiAKLSAgLyogU2V0IDQt Ynl0ZSBhbGlnbm1lbnQuICAqLworICAvKiA0LWJ5dGUgYWxpZ25tZW50LiAgKi8KICAgZnJhZ19h bGlnbiAoMiwgMCwgMCk7CiAKICAgYy0+eGRhdGFfYWRkciA9IHN5bWJvbF90ZW1wX25ld19ub3cg KCk7Ci0gIGZsYWdzID0gYy0+aGFuZGxlcl9mbGFnczsKLSAgY291bnRfdW53aW5kX2NvZGVzID0g c2VoX3g2NF9zaXplX3Byb2xvZ3VlX2RhdGEgKGMpOwogCi0gIC8qIHVieXRlOjMgdmVyc2lvbiwg dWJ5dGU6NSBmbGFncy4gICovCi0gIG91dF9vbmUgKChmbGFncyA8PCAzKSB8IDEpOwotCi0gIC8q IFNpemUgb2YgcHJvbG9ndWUuICAqLwotICBpZiAoYy0+ZW5kcHJvbG9ndWVfYWRkcikKKyAgLyog Q2FsY3VsYXRlIGZ1bmN0aW9uIGxlbmd0aCBpbiA0LWJ5dGUgdW5pdHMuICBDb21wdXRlIGl0IGZy b20gdGhlCisgICAgIHN5bWJvbHMnIGZyYWdtZW50IHBvc2l0aW9ucyByYXRoZXIgdGhhbiByZXNv bHZlX2V4cHJlc3Npb24sIHdoaWNoCisgICAgIGNhbiBmYWlsIHdoZW4gdGhlIHN5bWJvbHMgc3Bh biBtdWx0aXBsZSBmcmFnbWVudHMuICAqLworICB7CisgICAgYWRkcmVzc1Qgb2ZmMSwgb2ZmMjsK KyAgICBmcmFnUyAqZjEgPSBzeW1ib2xfZ2V0X2ZyYWdfYW5kX3ZhbHVlIChjLT5zdGFydF9hZGRy LCAmb2ZmMSk7CisgICAgZnJhZ1MgKmYyID0gc3ltYm9sX2dldF9mcmFnX2FuZF92YWx1ZSAoYy0+ ZW5kX2FkZHIsICZvZmYyKTsKKyAgICBsb25nIGJ5dGVzID0gMDsKKworICAgIGlmIChmMSA9PSBm MikKKyAgICAgIGJ5dGVzID0gb2ZmMiAtIG9mZjE7CisgICAgZWxzZQorICAgICAgeworCS8qIFN1 bSBmcmFnbWVudCBzaXplcyBmcm9tIGYxIHRvIGYyLiAgKi8KKwlieXRlcyA9IG9mZjI7CisJZm9y IChmcmFnUyAqZiA9IGYxOyBmICYmIGYgIT0gZjI7IGYgPSBmLT5mcl9uZXh0KQorCSAgeworCSAg ICBpZiAoIWYtPmZyX25leHQpCisJICAgICAgYnJlYWs7CisJICAgIGJ5dGVzICs9IGYtPmZyX2Zp eDsKKwkgICAgaWYgKGYtPmZyX3ZhciA+IDApCisJICAgICAgYnl0ZXMgKz0gZi0+ZnJfdmFyICog Zi0+ZnJfc3VidHlwZTsKKwkgIH0KKwlieXRlcyAtPSBvZmYxOworICAgICAgfQorICAgIGZ1bmNf bGVuZ3RoID0gYnl0ZXMgPCAwID8gMCA6IGJ5dGVzID4+IDI7CisgIH0KKworICAvKiBDb3VudCB1 bndpbmQgY29kZSBieXRlcywgaW5jbHVkaW5nIHRoZSB0ZXJtaW5hdGluZyBFTkQuICAqLworICBp bnQgY29kZV9ieXRlcyA9IHNlaF9hYXJjaDY0X3NpemVfcHJvbG9ndWVfZGF0YSAoYykgKyAxOwor ICBjb2RlX3dvcmRzID0gKGNvZGVfYnl0ZXMgKyAzKSAvIDQ7CisKKyAgLyogQSBmdW5jdGlvbiB3 aXRoIG5vIHByb2xvZ3VlIGNvZGVzIG9ubHkgbmVlZHMgdGhlIEVORCBtYXJrZXIuCisgICAgIElu IHRoYXQgY2FzZSwgY29kZV93b3JkcyBpcyAwIGFuZCBubyB1bndpbmQgY29kZSBieXRlcyBhcmUg ZW1pdHRlZC4gICovCisgIGJvb2wgbm9fdW53aW5kX2NvZGVzID0gKGNvZGVfYnl0ZXMgPT0gMSk7 CisgIGlmIChub191bndpbmRfY29kZXMpCisgICAgY29kZV93b3JkcyA9IDA7CisKKyAgLyogSGVh ZGVyIHdvcmQgKE1pY3Jvc29mdCBBUk02NCBTRUggeGRhdGEgZm9ybWF0LCBtYXRjaGluZyBMTFZN IE1DV2luNjRFSCk6CisgICAgIGJpdHMgWzA6MTddICA9IEZ1bmN0aW9uIExlbmd0aCAvIDQgKDE4 IGJpdHMpCisgICAgIGJpdCAgWzIwXSAgICA9IFggKEV4Y2VwdGlvbiBIYW5kbGVyIFByZXNlbnQp CisgICAgIGJpdCAgWzIxXSAgICA9IEUgKFBhY2tlZCBFcGlsb2cgUHJlc2VudCkKKyAgICAgYml0 cyBbMjY6MjJdID0gRXBpbG9nIENvdW50ICg1IGJpdHMpCisgICAgIGJpdHMgWzMxOjI3XSA9IENv ZGUgV29yZHMgKDUgYml0cykgKi8KKyAgZXBpbG9nX2NvdW50ID0gMDsKKyAgdW5zaWduZWQgaW50 IGhlYWRlciA9IGZ1bmNfbGVuZ3RoICYgMHgzZmZmZjsKKyAgaWYgKGNvZGVfd29yZHMgPiAweDFm KQogICAgIHsKLSAgICAgIGV4cC5YX29wID0gT19zdWJ0cmFjdDsKLSAgICAgIGV4cC5YX2FkZF9z eW1ib2wgPSBjLT5lbmRwcm9sb2d1ZV9hZGRyOwotICAgICAgZXhwLlhfb3Bfc3ltYm9sID0gYy0+ c3RhcnRfYWRkcjsKLSAgICAgIGV4cC5YX2FkZF9udW1iZXIgPSAwOwotICAgICAgZW1pdF9leHBy ICgmZXhwLCAxKTsKKyAgICAgIGhlYWRlciB8PSAoMCA8PCAyNyk7CisgICAgICBoZWFkZXIgfD0g KChlcGlsb2dfY291bnQgJiAweDFmKSA8PCAyMik7CiAgICAgfQogICBlbHNlCi0gICAgb3V0X29u ZSAoMCk7CisgICAgeworICAgICAgaGVhZGVyIHw9ICgoY29kZV93b3JkcyAmIDB4MWYpIDw8IDI3 KTsKKyAgICAgIGhlYWRlciB8PSAoKGVwaWxvZ19jb3VudCAmIDB4MWYpIDw8IDIyKTsKKyAgICB9 CisgIGlmIChjLT5oYW5kbGVyX2ZsYWdzICYgKFVOV19GTEFHX0VIQU5ETEVSIHwgVU5XX0ZMQUdf VUhBTkRMRVIpKQorICAgIGhlYWRlciB8PSAoMSA8PCAyMCk7CiAKLSAgLyogTnVtYmVyIG9mIHNs b3RzIChpLmUuIHNob3J0cykgaW4gdGhlIHVud2luZCBjb2RlcyBhcnJheS4gICovCi0gIGlmIChj b3VudF91bndpbmRfY29kZXMgPiAyNTUpCi0gICAgYXNfZmF0YWwgKF8oInRvbyBtdWNoIHVud2lu ZCBkYXRhIGluIHRoaXMgLnNlaF9wcm9jIikpOwotICBvdXRfb25lIChjb3VudF91bndpbmRfY29k ZXMpOworICBvdXRfZm91ciAoaGVhZGVyKTsKIAotICAvKiB1Ynl0ZTo0IGZyYW1lLXJlZywgdWJ5 dGU6NCBmcmFtZS1yZWctb2Zmc2V0LiAgKi8KLSAgLyogTm90ZSB0aGF0IGZyYW1lb2ZmIGlzIGFs cmVhZHkgYSBtdWx0aXBsZSBvZiAxNiwgYW5kIHRoZXJlZm9yZQotICAgICB0aGUgb2Zmc2V0IGlz IGFscmVhZHkgYm90aCBzY2FsZWQgYW5kIHNoaWZ0ZWQgaW50byBwbGFjZS4gICovCi0gIG91dF9v bmUgKGMtPmZyYW1lb2ZmIHwgYy0+ZnJhbWVyZWcpOworICAvKiBJZiBleHRlbmRlZCBjb2RlIHdv cmRzIG5lZWRlZCwgZW1pdCBleHRlbnNpb24gd29yZC4KKyAgICAgYml0cyBbMTU6MF0gPSBFcGls b2cgQ291bnQsIGJpdHMgWzIzOjE2XSA9IENvZGUgV29yZHMuCisgICAgIEFsc28gZW1pdCBpdCB3 aGVuIGJvdGggdGhlIGNvZGUgd29yZHMgYW5kIGVwaWxvZyBjb3VudCBhcmUgemVybzoKKyAgICAg aW4gdGhhdCBjYXNlIFdpbmRvd3MgKGFuZCBXaW5lKSB0cmVhdCB0aGUgcGFja2VkIGZpZWxkcyBh cyB6ZXJvIGFuZAorICAgICByZWFkIHRoZSBhY3R1YWwgdmFsdWVzIGZyb20gdGhlIGV4dGVuc2lv biB3b3JkLiAgKi8KKyAgaWYgKGNvZGVfd29yZHMgPiAweDFmIHx8IG5vX3Vud2luZF9jb2RlcykK KyAgICB7CisgICAgICB1bnNpZ25lZCBpbnQgZXh0ID0gKChjb2RlX3dvcmRzICYgMHhmZikgPDwg MTYpCisgICAgICAgICAgICAgICAgICAgICAgICAgfCAoZXBpbG9nX2NvdW50ICYgMHhmZmZmKTsK KyAgICAgIG91dF9mb3VyIChleHQpOworICAgIH0KIAotICBzZWhfeDY0X3dyaXRlX3Byb2xvZ3Vl X2RhdGEgKGMpOworICAvKiBXcml0ZSBwcm9sb2d1ZSB1bndpbmQgY29kZXMgKHNraXBwZWQgd2hl biBub191bndpbmRfY29kZXMpLiAgKi8KKyAgaWYgKCFub191bndpbmRfY29kZXMpCisgICAgc2Vo X2FhcmNoNjRfd3JpdGVfcHJvbG9ndWVfZGF0YSAoYyk7CiAKLSAgLyogV2UgbmVlZCB0byBhbGln biBwcm9sb2d1ZSBkYXRhLiAgKi8KLSAgaWYgKGNvdW50X3Vud2luZF9jb2RlcyAmIDEpCi0gICAg b3V0X3R3byAoMCk7CisgIC8qIFBhZCB0byA0LWJ5dGUgYWxpZ25tZW50LiAgT25seSBuZWVkZWQg d2hlbiB1bndpbmQgY29kZXMgYXJlIHByZXNlbnQuICAqLworICBpZiAoIW5vX3Vud2luZF9jb2Rl cykKKyAgICB7CisgICAgICBpbnQgcmVtYWluZGVyID0gKGNvZGVfYnl0ZXMpICYgMzsKKyAgICAg IGlmIChyZW1haW5kZXIpCisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgNCAtIHJlbWFpbmRl cjsgaSsrKQorICAgICAgICAgIG91dF9vbmUgKEFBUkNINjRfVU9QX05PUCk7CisgICAgfQogCi0g IGlmIChmbGFncyAmIChVTldfRkxBR19FSEFORExFUiB8IFVOV19GTEFHX1VIQU5ETEVSKSkKKyAg LyogSWYgZXhjZXB0aW9uIGhhbmRsZXIgcHJlc2VudCwgZW1pdCBpdC4gICovCisgIGlmIChjLT5o YW5kbGVyX2ZsYWdzICYgKFVOV19GTEFHX0VIQU5ETEVSIHwgVU5XX0ZMQUdfVUhBTkRMRVIpKQog ICAgIHsKLSAgICAgIC8qIEZvcmNlIHRoZSB1c2Ugb2Ygc2VnbWVudC1yZWxhdGl2ZSByZWxvY2F0 aW9ucyBpbnN0ZWFkIG9mIGFic29sdXRlCi0gICAgICAgICB2YWx1ZWQgZXhwcmVzc2lvbnMuICBE b24ndCBhZGp1c3QgZm9yIGNvbnN0YW50cyAoZS5nLiBOVUxMKS4gICovCiAgICAgICBpZiAoYy0+ aGFuZGxlci5YX29wID09IE9fc3ltYm9sKQotICAgICAgICBjLT5oYW5kbGVyLlhfb3AgPSBPX3N5 bWJvbF9ydmE7CisJYy0+aGFuZGxlci5YX29wID0gT19zeW1ib2xfcnZhOwogICAgICAgZW1pdF9l eHByICgmYy0+aGFuZGxlciwgNCk7CiAgICAgfQogCi0gIC8qIEhhbmRsZXIgZGF0YSB3aWxsIGJl IHRhY2tlZCBpbiBoZXJlIGJ5IHN1YnNlY3Rpb25zLiAgKi8KKyAgLyogSGFuZGxlciBkYXRhIGZv bGxvd3MgaW4gc3Vic2VjdGlvbnMuICAqLwogfQogCiAvKiBXcml0ZSBvdXQgeGRhdGEgZm9yIG9u ZSBmdW5jdGlvbi4gICovCkBAIC03NDUsNjcgKzEzMjQsMjEgQEAgd3JpdGVfZnVuY3Rpb25feGRh dGEgKHNlaF9jb250ZXh0ICpjKQogICBzZWdUIHNhdmVfc2VnID0gbm93X3NlZzsKICAgaW50IHNh dmVfc3Vic2VnID0gbm93X3N1YnNlZzsKIAotICAvKiBNSVBTLCBTSCwgQVJNIGRvbid0IGhhdmUg eGRhdGEuICAqLwotICBpZiAoc2VoX2dldF90YXJnZXRfa2luZCAoKSAhPSBzZWhfa2luZF94NjQp Ci0gICAgcmV0dXJuOwotCi0gIHN3aXRjaF94ZGF0YSAoYy0+c3Vic2VjdGlvbiwgYy0+Y29kZV9z ZWcpOwotCi0gIHNlaF94NjRfd3JpdGVfZnVuY3Rpb25feGRhdGEgKGMpOworICBpZiAoc2VoX2dl dF90YXJnZXRfa2luZCAoKSA9PSBzZWhfa2luZF94NjQpCisgICAgeworICAgICAgc3dpdGNoX3hk YXRhIChjLT5zdWJzZWN0aW9uLCBjLT5jb2RlX3NlZyk7CisgICAgICBzZWhfeDY0X3dyaXRlX2Z1 bmN0aW9uX3hkYXRhIChjKTsKKyAgICB9CisgIGVsc2UgaWYgKHNlaF9nZXRfdGFyZ2V0X2tpbmQg KCkgPT0gc2VoX2tpbmRfYWFyY2g2NCkKKyAgICB7CisgICAgICBzd2l0Y2hfeGRhdGEgKGMtPnN1 YnNlY3Rpb24sIGMtPmNvZGVfc2VnKTsKKyAgICAgIHNlaF9hYXJjaDY0X3dyaXRlX2Z1bmN0aW9u X3hkYXRhIChjKTsKKyAgICB9CiAKICAgc3Vic2VnX3NldCAoc2F2ZV9zZWcsIHNhdmVfc3Vic2Vn KTsKIH0KIAotLyogV3JpdGUgcGRhdGEgc2VjdGlvbiBkYXRhIGZvciBvbmUgZnVuY3Rpb24gKGFy bSkuICAqLwotCi1zdGF0aWMgdm9pZAotc2VoX2FybV93cml0ZV9mdW5jdGlvbl9wZGF0YSAoc2Vo X2NvbnRleHQgKmMpCi17Ci0gIGV4cHJlc3Npb25TIGV4cDsKLSAgdW5zaWduZWQgaW50IHByb2xf bGVuID0gMCwgZnVuY19sZW4gPSAwOwotICB1bnNpZ25lZCBpbnQgdmFsOwotCi0gIC8qIFN0YXJ0 IGFkZHJlc3Mgb2YgdGhlIGZ1bmN0aW9uLiAgKi8KLSAgZXhwLlhfb3AgPSBPX3N5bWJvbDsKLSAg ZXhwLlhfYWRkX3N5bWJvbCA9IGMtPnN0YXJ0X2FkZHI7Ci0gIGV4cC5YX2FkZF9udW1iZXIgPSAw OwotICBlbWl0X2V4cHIgKCZleHAsIDQpOwotCi0gIGV4cC5YX29wID0gT19zdWJ0cmFjdDsKLSAg ZXhwLlhfYWRkX3N5bWJvbCA9IGMtPmVuZF9hZGRyOwotICBleHAuWF9vcF9zeW1ib2wgPSBjLT5z dGFydF9hZGRyOwotICBleHAuWF9hZGRfbnVtYmVyID0gMDsKLSAgaWYgKHJlc29sdmVfZXhwcmVz c2lvbiAoJmV4cCkgJiYgZXhwLlhfb3AgPT0gT19jb25zdGFudCkKLSAgICBmdW5jX2xlbiA9IGV4 cC5YX2FkZF9udW1iZXI7Ci0gIGVsc2UKLSAgICBhc19iYWQgKF8oIi5zZWhfZW5kcHJvYyBpbiBh IGRpZmZlcmVudCBzZWN0aW9uIGZyb20gLnNlaF9wcm9jIikpOwotCi0gIGlmIChjLT5lbmRwcm9s b2d1ZV9hZGRyKQotICAgIHsKLSAgICAgIGV4cC5YX29wID0gT19zdWJ0cmFjdDsKLSAgICAgIGV4 cC5YX2FkZF9zeW1ib2wgPSBjLT5lbmRwcm9sb2d1ZV9hZGRyOwotICAgICAgZXhwLlhfb3Bfc3lt Ym9sID0gYy0+c3RhcnRfYWRkcjsKLSAgICAgIGV4cC5YX2FkZF9udW1iZXIgPSAwOwotCi0gICAg ICBpZiAocmVzb2x2ZV9leHByZXNzaW9uICgmZXhwKSAmJiBleHAuWF9vcCA9PSBPX2NvbnN0YW50 KQotCXByb2xfbGVuID0gZXhwLlhfYWRkX251bWJlcjsKLSAgICAgIGVsc2UKLQlhc19iYWQgKF8o Ii5zZWhfZW5kcHJvbG9ndWUgaW4gYSBkaWZmZXJlbnQgc2VjdGlvbiBmcm9tIC5zZWhfcHJvYyIp KTsKLSAgICB9Ci0KLSAgLyogQm90aCBmdW5jdGlvbiBhbmQgcHJvbG9ndWUgYXJlIGluIHVuaXRz IG9mIGluc3RydWN0aW9ucy4gICovCi0gIGZ1bmNfbGVuID4+PSAoYy0+dXNlX2luc3RydWN0aW9u XzMyID8gMiA6IDEpOwotICBwcm9sX2xlbiA+Pj0gKGMtPnVzZV9pbnN0cnVjdGlvbl8zMiA/IDIg OiAxKTsKIAotICAvKiBBc3NlbWJsZSB0aGUgc2Vjb25kIHdvcmQgb2YgdGhlIHBkYXRhLiAgKi8K LSAgdmFsICA9IHByb2xfbGVuICYgMHhmZjsKLSAgdmFsIHw9IChmdW5jX2xlbiAmIDB4M2ZmZmZm KSA8PCA4OwotICBpZiAoYy0+dXNlX2luc3RydWN0aW9uXzMyKQotICAgIHZhbCB8PSAweDQwMDAw MDAwVTsKLSAgaWYgKGMtPmhhbmRsZXJfd3JpdHRlbikKLSAgICB2YWwgfD0gMHg4MDAwMDAwMFU7 Ci0gIG91dF9mb3VyICh2YWwpOwotfQogCiAvKiBXcml0ZSBvdXQgcGRhdGEgZm9yIG9uZSBmdW5j dGlvbi4gICovCiAKQEAgLTg1OCw2ICsxMzkxLDE3IEBAIHdyaXRlX2Z1bmN0aW9uX3BkYXRhIChz ZWhfY29udGV4dCAqYykKICAgICAgIHNlaF9hcm1fd3JpdGVfZnVuY3Rpb25fcGRhdGEgKGMpOwog ICAgICAgYnJlYWs7CiAKKyAgICBjYXNlIHNlaF9raW5kX2FhcmNoNjQ6CisgICAgICBleHAuWF9v cCA9IE9fc3ltYm9sX3J2YTsKKyAgICAgIGV4cC5YX2FkZF9udW1iZXIgPSAwOworICAgICAgZXhw LlhfYWRkX3N5bWJvbCA9IGMtPnN0YXJ0X2FkZHI7CisgICAgICBlbWl0X2V4cHIgKCZleHAsIDQp OworICAgICAgZXhwLlhfb3AgPSBPX3N5bWJvbF9ydmE7CisgICAgICBleHAuWF9hZGRfbnVtYmVy ID0gMDsKKyAgICAgIGV4cC5YX2FkZF9zeW1ib2wgPSBjLT54ZGF0YV9hZGRyOworICAgICAgZW1p dF9leHByICgmZXhwLCA0KTsKKyAgICAgIGJyZWFrOworCiAgICAgZGVmYXVsdDoKICAgICAgIGFi b3J0ICgpOwogICAgIH0KZGlmZiAtLWdpdCBhL2dhcy9jb25maWcvb2JqLWNvZmYtc2VoLmggYi9n YXMvY29uZmlnL29iai1jb2ZmLXNlaC5oCmluZGV4IDhhM2UxZDYwMmFhLi5mMWIzNTM1ZDEzOCAx MDA2NDQKLS0tIGEvZ2FzL2NvbmZpZy9vYmotY29mZi1zZWguaAorKysgYi9nYXMvY29uZmlnL29i ai1jb2ZmLXNlaC5oCkBAIC0yNSw2ICsyNSw4IEBACiAgIFRoZSB0aGlyZCBpcyB0aGUgSUE2NCBh bmQgeDY0IHZlcnNpb24uIE5vdGUsIHRoZSBJQTY0IGlzbid0IGltcGxlbWVudGVkIHlldCwKICAg YnV0IHRvIGZpbmQgaW5mb3JtYXRpb24gYWJvdXQgaXQsIHBsZWFzZSBzZWUgc3BlY2lmaWNhdGlv biBhYm91dCBJQTY0IG9uCiAgIGh0dHA6Ly9kb3dubG9hZC5pbnRlbC5jb20vZGVzaWduL0l0YW5p dW0vRG93bmxvYWRzLzI0NTM1OC5wZGYgZmlsZS4KKyAgVGhlIGZvdXJ0aCBpcyBmb3IgQUFyY2g2 NCAoQVJNNjQpIFdpbmRvd3MsIHdoaWNoIHVzZXMgdGhlIHNhbWUgcGRhdGEveGRhdGEKKyAgbW9k ZWwgYXMgeDY0IGJ1dCB3aXRoIGRpZmZlcmVudCB1bndpbmQgY29kZXMgYW5kIGEgMi13b3JkIHBk YXRhIGVudHJ5LgogCiAgIFRoZSBmaXJzdCB2ZXJzaW9uIGhhcyBqdXN0IGVudHJpZXMgaW4gdGhl IHBkYXRhIHNlY3Rpb246IEJlZ2luQWRkcmVzcywKICAgRW5kQWRkcmVzcywgRXhjZXB0aW9uSGFu ZGxlciwgSGFuZGxlckRhdGEsIGFuZCBQcm9sb2d1ZUVuZEFkZHJlc3MuIEVhY2gKQEAgLTQxLDEw ICs0MywxNCBAQAogICBwcm9sb2d1ZSwgZXhjZXB0aW9uLWhhbmRsZXIsIGFuZCBhZGRpdGlvbmFs IFNFSCBkYXRhIGlzIHN0b3JlZAogICB3aXRoaW4gdGhlIFVOV0lORF9EQVRBIGZpZWxkIGluIHRo ZSB4ZGF0YSBzZWN0aW9uLgogCisgIFRoZSBmb3VydGggKEFBcmNoNjQvQVJNNjQpIHZlcnNpb24g aGFzIGEgMi13b3JkIHBkYXRhIGVudHJ5OgorICBCZWdpbkFkZHJlc3MgKFJWQSkgYW5kIFVud2lu ZERhdGEgKFJWQSksIHdpdGggeGRhdGEgdXNpbmcgQVJNNjQtc3BlY2lmaWMKKyAgdW53aW5kIGNv ZGVzLgorCiAgIFRoZSBwc2V1ZG9zOgogICAuc2VoX3Byb2MgPGZjdF9uYW1lPgogICAuc2VoX2Vu ZHByb2xvZ3VlCi0gIC5zZWhfaGFuZGxlciA8aGFuZGxlcj5bLEB1bndpbmRdWyxAZXhjZXB0XQko eDY0KQorICAuc2VoX2hhbmRsZXIgPGhhbmRsZXI+WyxAdW53aW5kXVssQGV4Y2VwdF0JKHg2NCwg YWFyY2g2NCkKICAgLnNlaF9oYW5kbGVyIDxoYW5kbGVyPlssPGhhbmRsZXJfZGF0YT5dCShvdGhl cnMpCiAgIC5zZWhfaGFuZGxlcmRhdGEKICAgLnNlaF9laApAQCAtNTcsNiArNjMsMTcgQEAKICAg LnNlaF9zYXZleG1tCiAgIC5zZWhfcHVzaGZyYW1lCiAgIC5zZWhfY29kZQorICAuc2VoX3NhdmVf cmVncCA8cmVnMT4sPHJlZzI+LDxvZmZzZXQ+CQkoYWFyY2g2NCkKKyAgLnNlaF9zYXZlX2ZyZWdw IDxyZWcxPiw8cmVnMj4sPG9mZnNldD4JKGFhcmNoNjQpCisgIC5zZWhfc2F2ZV9yZWcgPHJlZz4s PG9mZnNldD4JCQkoYWFyY2g2NCkKKyAgLnNlaF9zYXZlX2ZyZWcgPHJlZz4sPG9mZnNldD4JCQko YWFyY2g2NCkKKyAgLnNlaF9zYXZlX2ZwbHIgPG9mZnNldD4JCQkoYWFyY2g2NCkKKyAgLnNlaF9z YXZlX2ZwbHJfeCA8b2Zmc2V0PgkJCShhYXJjaDY0KQorICAuc2VoX3NhdmVfbHJwYWlyIDxyZWc+ LDxvZmZzZXQ+CQkoYWFyY2g2NCkKKyAgLnNlaF9zZXRfZnAJCQkJCShhYXJjaDY0KQorICAuc2Vo X2FkZF9mcCA8b2Zmc2V0PgkJCQkoYWFyY2g2NCkKKyAgLnNlaF9ub3AJCQkJCShhYXJjaDY0KQor ICAuc2VoX2FsbG9jX3N0YWNrIDxzaXplPgkJCShhYXJjaDY0KQogKi8KIAogI2lmbmRlZiBPQkpf Q09GRl9TRUhfSApAQCAtNzgsNyArOTUsMTggQEAKIAl7InNlaF9ubzMyIiwgb2JqX2NvZmZfc2Vo XzMyLCAwfSwgXAogCXsic2VoX2hhbmRsZXIiLCBvYmpfY29mZl9zZWhfaGFuZGxlciwgMH0sIFwK IAl7InNlaF9jb2RlIiwgb2JqX2NvZmZfc2VoX2NvZGUsIDB9LCBcCi0JeyJzZWhfaGFuZGxlcmRh dGEiLCBvYmpfY29mZl9zZWhfaGFuZGxlcmRhdGEsIDB9LAorCXsic2VoX2hhbmRsZXJkYXRhIiwg b2JqX2NvZmZfc2VoX2hhbmRsZXJkYXRhLCAwfSwgXAorCXsic2VoX3NhdmVfcmVncCIsIG9ial9j b2ZmX3NlaF9hYXJjaDY0X3NhdmVfcmVncCwgMH0sIFwKKwl7InNlaF9zYXZlX2ZyZWdwIiwgb2Jq X2NvZmZfc2VoX2FhcmNoNjRfc2F2ZV9mcmVncCwgMH0sIFwKKwl7InNlaF9zYXZlX3JlZyIsIG9i al9jb2ZmX3NlaF9hYXJjaDY0X3NhdmVfcmVnLCAwfSwgXAorCXsic2VoX3NhdmVfZnJlZyIsIG9i al9jb2ZmX3NlaF9hYXJjaDY0X3NhdmVfZnJlZywgMH0sIFwKKwl7InNlaF9zYXZlX2ZwbHIiLCBv YmpfY29mZl9zZWhfYWFyY2g2NF9zYXZlX2ZwbHIsIDB9LCBcCisJeyJzZWhfc2F2ZV9mcGxyX3gi LCBvYmpfY29mZl9zZWhfYWFyY2g2NF9zYXZlX2ZwbHJfeCwgMH0sIFwKKwl7InNlaF9zYXZlX2xy cGFpciIsIG9ial9jb2ZmX3NlaF9hYXJjaDY0X3NhdmVfbHJwYWlyLCAwfSwgXAorCXsic2VoX3Nl dF9mcCIsIG9ial9jb2ZmX3NlaF9hYXJjaDY0X3NldF9mcCwgMH0sIFwKKwl7InNlaF9hZGRfZnAi LCBvYmpfY29mZl9zZWhfYWFyY2g2NF9hZGRfZnAsIDB9LCBcCisJeyJzZWhfbm9wIiwgb2JqX2Nv ZmZfc2VoX2FhcmNoNjRfbm9wLCAwfSwgXAorCXsic2VoX2FsbG9jX3N0YWNrIiwgb2JqX2NvZmZf c2VoX2FhcmNoNjRfYWxsb2Nfc3RhY2ssIDB9LAogCiAvKiBUeXBlIGRlZmluaXRpb25zLiAgKi8K IApAQCAtMTM1LDkgKzE2Myw0NCBAQCB0eXBlZGVmIGVudW0gc2VoX2tpbmQgewogICBzZWhfa2lu ZF91bmtub3duID0gMCwKICAgc2VoX2tpbmRfbWlwcyA9IDEsICAvKiBVc2VkIGZvciBNSVBTIGFu ZCB4ODYgcGRhdGEgZ2VuZXJhdGlvbi4gICovCiAgIHNlaF9raW5kX2FybSA9IDIsICAgLyogVXNl ZCBmb3IgQVJNLCBQUEMsIFNIMywgYW5kIFNINCBwZGF0YSAoUERBVEFfRUgpIGdlbmVyYXRpb24u ICAqLwotICBzZWhfa2luZF94NjQgPSAzICAgIC8qIFVzZWQgZm9yIElBNjQgYW5kIHg2NCBwZGF0 YS94ZGF0YSBnZW5lcmF0aW9uLiAgKi8KKyAgc2VoX2tpbmRfeDY0ID0gMywgICAvKiBVc2VkIGZv ciBJQTY0IGFuZCB4NjQgcGRhdGEveGRhdGEgZ2VuZXJhdGlvbi4gICovCisgIHNlaF9raW5kX2Fh cmNoNjQgPSA0IC8qIFVzZWQgZm9yIEFBcmNoNjQgKEFSTTY0KSBXaW5kb3dzIHBkYXRhL3hkYXRh IGdlbmVyYXRpb24uICAqLwogfSBzZWhfa2luZDsKIAorLyogQUFyY2g2NCB1bndpbmQgb3Bjb2Rl cy4gICovCisjZGVmaW5lIEFBUkNINjRfVU9QX0FMTE9DX1NNQUxMICAweDAwCisjZGVmaW5lIEFB UkNINjRfVU9QX0FMTE9DX01FRElVTSAweEMwCisjZGVmaW5lIEFBUkNINjRfVU9QX0FMTE9DX0xB UkdFICAweEUwCisjZGVmaW5lIEFBUkNINjRfVU9QX1NBVkVfUjE5UjIwWCAweDIwCisjZGVmaW5l IEFBUkNINjRfVU9QX1NBVkVfRlBMUlggICAweDgwCisjZGVmaW5lIEFBUkNINjRfVU9QX1NBVkVf RlBMUiAgICAweDQwCisjZGVmaW5lIEFBUkNINjRfVU9QX1NBVkVfUkVHICAgICAweEQwCisjZGVm aW5lIEFBUkNINjRfVU9QX1NBVkVfUkVHX1ggICAweEQ0CisjZGVmaW5lIEFBUkNINjRfVU9QX1NB VkVfUkVHX1AgICAweEM4CisjZGVmaW5lIEFBUkNINjRfVU9QX1NBVkVfUkVHX1BYICAweENDCisj ZGVmaW5lIEFBUkNINjRfVU9QX1NBVkVfTFJQQUlSICAweEQ2CisjZGVmaW5lIEFBUkNINjRfVU9Q X1NBVkVfRlJFRyAgICAweERDCisjZGVmaW5lIEFBUkNINjRfVU9QX1NBVkVfRlJFR19YICAweERF CisjZGVmaW5lIEFBUkNINjRfVU9QX1NBVkVfRlJFR19QICAweEQ4CisjZGVmaW5lIEFBUkNINjRf VU9QX1NBVkVfRlJFR19QWCAweERBCisjZGVmaW5lIEFBUkNINjRfVU9QX1NFVF9GUCAgICAgICAw eEUxCisjZGVmaW5lIEFBUkNINjRfVU9QX0FERF9GUCAgICAgICAweEUyCisjZGVmaW5lIEFBUkNI NjRfVU9QX05PUCAgICAgICAgICAweEUzCisjZGVmaW5lIEFBUkNINjRfVU9QX0VORCAgICAgICAg ICAweEU0CisjZGVmaW5lIEFBUkNINjRfVU9QX1NBVkVfTkVYVCAgICAweEU2CisjZGVmaW5lIEFB UkNINjRfVU9QX1RSQVBfRlJBTUUgICAweEU4CisjZGVmaW5lIEFBUkNINjRfVU9QX1BVU0hfTUFD SCAgICAweEU5CisjZGVmaW5lIEFBUkNINjRfVU9QX0NPTlRFWFQgICAgICAweEVBCisjZGVmaW5l IEFBUkNINjRfVU9QX0VDX0NPTlRFWFQgICAweEVCCisjZGVmaW5lIEFBUkNINjRfVU9QX0NMRUFS X1VOV09VTkRfVE9fQ0FMTCAweEVDCisjZGVmaW5lIEFBUkNINjRfVU9QX1BBQ19TSUdOX0xSICAw eEZDCisjZGVmaW5lIEFBUkNINjRfVU9QX1NBVkVfQU5ZX1JFR19JICAgMHhFNworI2RlZmluZSBB QVJDSDY0X1VPUF9TQVZFX0FOWV9SRUdfSVAgIDB4RTcKKyNkZWZpbmUgQUFSQ0g2NF9VT1BfU0FW RV9BTllfUkVHX0QgICAweEU3CisjZGVmaW5lIEFBUkNINjRfVU9QX1NBVkVfQU5ZX1JFR19EUCAg MHhFNworI2RlZmluZSBBQVJDSDY0X1VPUF9TQVZFX0FOWV9SRUdfUSAgIDB4RTcKKyNkZWZpbmUg QUFSQ0g2NF9VT1BfU0FWRV9BTllfUkVHX1FQICAweEU3CisKIC8qIEZvcndhcmQgZGVjbGFyYXRp b25zLiAgKi8KIHN0YXRpYyB2b2lkIG9ial9jb2ZmX3NlaF9zdGFja2FsbG9jIChpbnQpOwogc3Rh dGljIHZvaWQgb2JqX2NvZmZfc2VoX3NldGZyYW1lIChpbnQpOwpAQCAtMTUyLDYgKzIxNSwxNyBA QCBzdGF0aWMgdm9pZCBvYmpfY29mZl9zZWhfcHJvYyAgKGludCk7CiBzdGF0aWMgdm9pZCBvYmpf Y29mZl9zZWhfaGFuZGxlciAoaW50KTsKIHN0YXRpYyB2b2lkIG9ial9jb2ZmX3NlaF9oYW5kbGVy ZGF0YSAoaW50KTsKIHN0YXRpYyB2b2lkIG9ial9jb2ZmX3NlaF9jb2RlIChpbnQpOworc3RhdGlj IHZvaWQgb2JqX2NvZmZfc2VoX2FhcmNoNjRfc2F2ZV9yZWdwIChpbnQpOworc3RhdGljIHZvaWQg b2JqX2NvZmZfc2VoX2FhcmNoNjRfc2F2ZV9mcmVncCAoaW50KTsKK3N0YXRpYyB2b2lkIG9ial9j b2ZmX3NlaF9hYXJjaDY0X3NhdmVfcmVnIChpbnQpOworc3RhdGljIHZvaWQgb2JqX2NvZmZfc2Vo X2FhcmNoNjRfc2F2ZV9mcmVnIChpbnQpOworc3RhdGljIHZvaWQgb2JqX2NvZmZfc2VoX2FhcmNo NjRfc2F2ZV9mcGxyIChpbnQpOworc3RhdGljIHZvaWQgb2JqX2NvZmZfc2VoX2FhcmNoNjRfc2F2 ZV9mcGxyX3ggKGludCk7CitzdGF0aWMgdm9pZCBvYmpfY29mZl9zZWhfYWFyY2g2NF9zYXZlX2xy cGFpciAoaW50KTsKK3N0YXRpYyB2b2lkIG9ial9jb2ZmX3NlaF9hYXJjaDY0X3NldF9mcCAoaW50 KTsKK3N0YXRpYyB2b2lkIG9ial9jb2ZmX3NlaF9hYXJjaDY0X2FkZF9mcCAoaW50KTsKK3N0YXRp YyB2b2lkIG9ial9jb2ZmX3NlaF9hYXJjaDY0X25vcCAoaW50KTsKK3N0YXRpYyB2b2lkIG9ial9j b2ZmX3NlaF9hYXJjaDY0X2FsbG9jX3N0YWNrIChpbnQpOwogCiAjZGVmaW5lIFVORFNFQyBiZmRf dW5kX3NlY3Rpb25fcHRyCiAKLS0gCjIuNTUuMAoK --000000000000038c3b06580f7f8d--