Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 8 Oct 2020 15:31:29 -0300
From:      Mitchell Horne <mhorne@freebsd.org>
To:        Ravi Pokala <rpokala@freebsd.org>
Cc:        src-committers@freebsd.org, svn-src-all@freebsd.org,  svn-src-head@freebsd.org
Subject:   Re: svn commit: r366542 - in head/sys: amd64/amd64 arm/arm arm64/arm64 kern riscv/riscv sys
Message-ID:  <CADeAsy1dykboVfBaGq3Br5bGNP2hzRaq71V7Wh9evg7=m8Y0iQ@mail.gmail.com>
In-Reply-To: <3173155C-6862-4DC6-964E-4F1B1FA941E9@panasas.com>
References:  <202010081802.098I26Rq052294@repo.freebsd.org> <3173155C-6862-4DC6-964E-4F1B1FA941E9@panasas.com>

next in thread | previous in thread | raw e-mail | index | archive | help
On Thu, Oct 8, 2020 at 3:19 PM Ravi Pokala <rpokala@freebsd.org> wrote:
>
> Hi Mitchell,
>
>     +static void
>     +preload_dump_internal(struct sbuf *sbp)
>     +{
>     +   uint32_t *bptr, type, len;
>     +
>     +   KASSERT(preload_metadata !=3D NULL,
>     +       ("%s called without setting up preload_metadata", __func__));
>     +
>     +   /*
>     +    * Iterate through the TLV-encoded sections.
>     +    */
>     +   bptr =3D (uint32_t *)preload_metadata;
>     +   sbuf_putc(sbp, '\n');
>     +   while (bptr[0] !=3D MODINFO_END || bptr[0] !=3D MODINFO_END) {
>
> The same expression is on both sides of the "||" ...?
>
> Thanks,
>
> Ravi (rpokala@)

Thank you for catching this --- it should be checking bptr[0] and
bptr[1]. Fixed in r366543.

Mitchell


>
>     +           sbuf_printf(sbp, " %p:\n", bptr);
>     +           type =3D *bptr++;
>     +           len =3D *bptr++;
>     +
>     +           sbuf_printf(sbp, "\ttype:\t(%#04x) ", type);
>     +           preload_modinfo_type(sbp, type);
>     +           sbuf_putc(sbp, '\n');
>     +           sbuf_printf(sbp, "\tlen:\t%u\n", len);
>     +           sbuf_cat(sbp, "\tvalue:\t");
>     +           preload_modinfo_value(sbp, bptr, type, len);
>     +           sbuf_putc(sbp, '\n');
>     +
>     +           bptr +=3D roundup(len, sizeof(u_long)) / sizeof(uint32_t)=
;
>     +   }
>     +}
>
>
>
>
> =EF=BB=BF-----Original Message-----
> From: <owner-src-committers@freebsd.org> on behalf of Mitchell Horne <mho=
rne@FreeBSD.org>
> Date: 2020-10-08, Thursday at 11:02
> To: <src-committers@freebsd.org>, <svn-src-all@freebsd.org>, <svn-src-hea=
d@freebsd.org>
> Subject: svn commit: r366542 - in head/sys: amd64/amd64 arm/arm arm64/arm=
64 kern riscv/riscv sys
>
>     Author: mhorne
>     Date: Thu Oct  8 18:02:05 2020
>     New Revision: 366542
>     URL: https://svnweb.freebsd.org/changeset/base/366542
>
>     Log:
>       Add a routine to dump boot metadata
>
>       The boot metadata (also referred to as modinfo, or preload metadata=
)
>       provides information about the size and location of the kernel,
>       pre-loaded modules, and other metadata (e.g. the EFI framebuffer) t=
o be
>       consumed during by the kernel during early boot. It is encoded as a
>       series of type-length-value entries and is usually constructed by
>       loader(8) and passed to the kernel. It is also faked on some
>       architectures when booted by other means.
>
>       Although much of the module information is available via kldstat(8)=
,
>       there is no easy way to debug the metadata in its entirety. Add som=
e
>       routines to parse this data and allow it to be printed to the conso=
le
>       during early boot or output via a sysctl.
>
>       Since the output can be lengthly, printing to the console is gated
>       behind the debug.dump_modinfo_at_boot kenv variable as well as the
>       BOOTVERBOSE flag. The sysctl to print the metadata is named
>       debug.dump_modinfo.
>
>       Reviewed by:      tsoome
>       Sponsored by:     NetApp, Inc.
>       Sponsored by:     Klara, Inc.
>       Differential Revision:    https://reviews.freebsd.org/D26687
>
>     Modified:
>       head/sys/amd64/amd64/machdep.c
>       head/sys/arm/arm/machdep.c
>       head/sys/arm64/arm64/machdep.c
>       head/sys/kern/subr_module.c
>       head/sys/riscv/riscv/machdep.c
>       head/sys/sys/linker.h
>
>     Modified: head/sys/amd64/amd64/machdep.c
>     =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D
>     --- head/sys/amd64/amd64/machdep.c  Thu Oct  8 17:30:05 2020        (=
r366541)
>     +++ head/sys/amd64/amd64/machdep.c  Thu Oct  8 18:02:05 2020        (=
r366542)
>     @@ -1853,6 +1853,15 @@ hammer_time(u_int64_t modulep, u_int64_t physf=
ree)
>         if (late_console)
>                 cninit();
>
>     +   /*
>     +    * Dump the boot metadata. We have to wait for cninit() since con=
sole
>     +    * output is required. If it's grossly incorrect the kernel will =
never
>     +    * make it this far.
>     +    */
>     +   if ((boothowto & RB_VERBOSE) &&
>     +       getenv_is_true("debug.dump_modinfo_at_boot"))
>     +           preload_dump();
>     +
>      #ifdef DEV_ISA
>      #ifdef DEV_ATPIC
>         elcr_probe();
>
>     Modified: head/sys/arm/arm/machdep.c
>     =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D
>     --- head/sys/arm/arm/machdep.c      Thu Oct  8 17:30:05 2020        (=
r366541)
>     +++ head/sys/arm/arm/machdep.c      Thu Oct  8 18:02:05 2020        (=
r366542)
>     @@ -1027,6 +1027,15 @@ initarm(struct arm_boot_params *abp)
>         debugf(" dtbp =3D 0x%08x\n", (uint32_t)dtbp);
>         arm_print_kenv();
>
>     +   /*
>     +    * Dump the boot metadata. We have to wait for cninit() since con=
sole
>     +    * output is required. If it's grossly incorrect the kernel will =
never
>     +    * make it this far.
>     +    */
>     +   if ((boothowto & RB_VERBOSE) &&
>     +       getenv_is_true("debug.dump_modinfo_at_boot"))
>     +           preload_dump();
>     +
>         env =3D kern_getenv("kernelname");
>         if (env !=3D NULL) {
>                 strlcpy(kernelname, env, sizeof(kernelname));
>
>     Modified: head/sys/arm64/arm64/machdep.c
>     =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D
>     --- head/sys/arm64/arm64/machdep.c  Thu Oct  8 17:30:05 2020        (=
r366541)
>     +++ head/sys/arm64/arm64/machdep.c  Thu Oct  8 18:02:05 2020        (=
r366542)
>     @@ -1242,6 +1242,15 @@ initarm(struct arm64_bootparams *abp)
>                 panic("Invalid bus configuration: %s",
>                     kern_getenv("kern.cfg.order"));
>
>     +   /*
>     +    * Dump the boot metadata. We have to wait for cninit() since con=
sole
>     +    * output is required. If it's grossly incorrect the kernel will =
never
>     +    * make it this far.
>     +    */
>     +   if ((boothowto & RB_VERBOSE) &&
>     +       getenv_is_true("debug.dump_modinfo_at_boot"))
>     +           preload_dump();
>     +
>         init_proc0(abp->kern_stack);
>         msgbufinit(msgbufp, msgbufsize);
>         mutex_init();
>
>     Modified: head/sys/kern/subr_module.c
>     =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D
>     --- head/sys/kern/subr_module.c     Thu Oct  8 17:30:05 2020        (=
r366541)
>     +++ head/sys/kern/subr_module.c     Thu Oct  8 18:02:05 2020        (=
r366542)
>     @@ -3,6 +3,8 @@
>       *
>       * Copyright (c) 1998 Michael Smith
>       * All rights reserved.
>     + * Copyright (c) 2020 NetApp Inc.
>     + * Copyright (c) 2020 Klara Inc.
>       *
>       * Redistribution and use in source and binary forms, with or withou=
t
>       * modification, are permitted provided that the following condition=
s
>     @@ -32,7 +34,11 @@ __FBSDID("$FreeBSD$");
>      #include <sys/param.h>
>      #include <sys/systm.h>
>      #include <sys/linker.h>
>     +#include <sys/sbuf.h>
>     +#include <sys/sysctl.h>
>
>     +#include <machine/metadata.h>
>     +
>      #include <vm/vm.h>
>      #include <vm/vm_extern.h>
>
>     @@ -304,3 +310,249 @@ preload_bootstrap_relocate(vm_offset_t offset)
>         }
>          }
>      }
>     +
>     +/*
>     + * Parse the modinfo type and append to the provided sbuf.
>     + */
>     +static void
>     +preload_modinfo_type(struct sbuf *sbp, int type)
>     +{
>     +
>     +   if ((type & MODINFO_METADATA) =3D=3D 0) {
>     +           switch (type) {
>     +           case MODINFO_END:
>     +                   sbuf_cat(sbp, "MODINFO_END");
>     +                   break;
>     +           case MODINFO_NAME:
>     +                   sbuf_cat(sbp, "MODINFO_NAME");
>     +                   break;
>     +           case MODINFO_TYPE:
>     +                   sbuf_cat(sbp, "MODINFO_TYPE");
>     +                   break;
>     +           case MODINFO_ADDR:
>     +                   sbuf_cat(sbp, "MODINFO_ADDR");
>     +                   break;
>     +           case MODINFO_SIZE:
>     +                   sbuf_cat(sbp, "MODINFO_SIZE");
>     +                   break;
>     +           case MODINFO_EMPTY:
>     +                   sbuf_cat(sbp, "MODINFO_EMPTY");
>     +                   break;
>     +           case MODINFO_ARGS:
>     +                   sbuf_cat(sbp, "MODINFO_ARGS");
>     +                   break;
>     +           default:
>     +                   sbuf_cat(sbp, "unrecognized modinfo attribute");
>     +           }
>     +
>     +           return;
>     +   }
>     +
>     +   sbuf_cat(sbp, "MODINFO_METADATA | ");
>     +   switch (type & ~MODINFO_METADATA) {
>     +   case MODINFOMD_ELFHDR:
>     +           sbuf_cat(sbp, "MODINFOMD_ELFHDR");
>     +           break;
>     +   case MODINFOMD_SSYM:
>     +           sbuf_cat(sbp, "MODINFOMD_SSYM");
>     +           break;
>     +   case MODINFOMD_ESYM:
>     +           sbuf_cat(sbp, "MODINFOMD_ESYM");
>     +           break;
>     +   case MODINFOMD_DYNAMIC:
>     +           sbuf_cat(sbp, "MODINFOMD_DYNAMIC");
>     +           break;
>     +   case MODINFOMD_ENVP:
>     +           sbuf_cat(sbp, "MODINFOMD_ENVP");
>     +           break;
>     +   case MODINFOMD_HOWTO:
>     +           sbuf_cat(sbp, "MODINFOMD_HOWTO");
>     +           break;
>     +   case MODINFOMD_KERNEND:
>     +           sbuf_cat(sbp, "MODINFOMD_KERNEND");
>     +           break;
>     +   case MODINFOMD_SHDR:
>     +           sbuf_cat(sbp, "MODINFOMD_SHDR");
>     +           break;
>     +   case MODINFOMD_CTORS_ADDR:
>     +           sbuf_cat(sbp, "MODINFOMD_CTORS_ADDR");
>     +           break;
>     +   case MODINFOMD_CTORS_SIZE:
>     +           sbuf_cat(sbp, "MODINFOMD_CTORS_SIZE");
>     +           break;
>     +   case MODINFOMD_FW_HANDLE:
>     +           sbuf_cat(sbp, "MODINFOMD_FW_HANDLE");
>     +           break;
>     +   case MODINFOMD_KEYBUF:
>     +           sbuf_cat(sbp, "MODINFOMD_KEYBUF");
>     +           break;
>     +#ifdef MODINFOMD_SMAP
>     +   case MODINFOMD_SMAP:
>     +           sbuf_cat(sbp, "MODINFOMD_SMAP");
>     +           break;
>     +#endif
>     +#ifdef MODINFOMD_SMAP_XATTR
>     +   case MODINFOMD_SMAP_XATTR:
>     +           sbuf_cat(sbp, "MODINFOMD_SMAP_XATTR");
>     +           break;
>     +#endif
>     +#ifdef MODINFOMD_DTBP
>     +   case MODINFOMD_DTBP:
>     +           sbuf_cat(sbp, "MODINFOMD_DTBP");
>     +           break;
>     +#endif
>     +#ifdef MODINFOMD_EFI_MAP
>     +   case MODINFOMD_EFI_MAP:
>     +           sbuf_cat(sbp, "MODINFOMD_EFI_MAP");
>     +           break;
>     +#endif
>     +#ifdef MODINFOMD_EFI_FB
>     +   case MODINFOMD_EFI_FB:
>     +           sbuf_cat(sbp, "MODINFOMD_EFI_FB");
>     +           break;
>     +#endif
>     +#ifdef MODINFOMD_MODULEP
>     +   case MODINFOMD_MODULEP:
>     +           sbuf_cat(sbp, "MODINFOMD_MODULEP");
>     +           break;
>     +#endif
>     +   default:
>     +           sbuf_cat(sbp, "unrecognized metadata type");
>     +   }
>     +}
>     +
>     +/*
>     + * Print the modinfo value, depending on type.
>     + */
>     +static void
>     +preload_modinfo_value(struct sbuf *sbp, uint32_t *bptr, int type, in=
t len)
>     +{
>     +#ifdef __LP64__
>     +#define sbuf_print_vmoffset(sb, o) sbuf_printf(sb, "0x%016lx", o);
>     +#else
>     +#define sbuf_print_vmoffset(sb, o) sbuf_printf(sb, "0x%08x", o);
>     +#endif
>     +
>     +   switch (type) {
>     +   case MODINFO_NAME:
>     +   case MODINFO_TYPE:
>     +   case MODINFO_ARGS:
>     +           sbuf_printf(sbp, "%s", (char *)bptr);
>     +           break;
>     +   case MODINFO_SIZE:
>     +   case MODINFO_METADATA | MODINFOMD_CTORS_SIZE:
>     +           sbuf_printf(sbp, "%lu", *(u_long *)bptr);
>     +           break;
>     +   case MODINFO_ADDR:
>     +   case MODINFO_METADATA | MODINFOMD_SSYM:
>     +   case MODINFO_METADATA | MODINFOMD_ESYM:
>     +   case MODINFO_METADATA | MODINFOMD_DYNAMIC:
>     +   case MODINFO_METADATA | MODINFOMD_KERNEND:
>     +   case MODINFO_METADATA | MODINFOMD_ENVP:
>     +   case MODINFO_METADATA | MODINFOMD_CTORS_ADDR:
>     +#ifdef MODINFOMD_SMAP
>     +   case MODINFO_METADATA | MODINFOMD_SMAP:
>     +#endif
>     +#ifdef MODINFOMD_SMAP_XATTR
>     +   case MODINFO_METADATA | MODINFOMD_SMAP_XATTR:
>     +#endif
>     +#ifdef MODINFOMD_DTBP
>     +   case MODINFO_METADATA | MODINFOMD_DTBP:
>     +#endif
>     +#ifdef MODINFOMD_EFI_FB
>     +   case MODINFO_METADATA | MODINFOMD_EFI_FB:
>     +#endif
>     +           sbuf_print_vmoffset(sbp, *(vm_offset_t *)bptr);
>     +           break;
>     +   case MODINFO_METADATA | MODINFOMD_HOWTO:
>     +           sbuf_printf(sbp, "0x%08x", *bptr);
>     +           break;
>     +   case MODINFO_METADATA | MODINFOMD_SHDR:
>     +   case MODINFO_METADATA | MODINFOMD_ELFHDR:
>     +   case MODINFO_METADATA | MODINFOMD_FW_HANDLE:
>     +   case MODINFO_METADATA | MODINFOMD_KEYBUF:
>     +#ifdef MODINFOMD_EFI_MAP
>     +   case MODINFO_METADATA | MODINFOMD_EFI_MAP:
>     +#endif
>     +           /* Don't print data buffers. */
>     +           sbuf_cat(sbp, "buffer contents omitted");
>     +           break;
>     +   default:
>     +           break;
>     +   }
>     +#undef sbuf_print_vmoffset
>     +}
>     +
>     +static void
>     +preload_dump_internal(struct sbuf *sbp)
>     +{
>     +   uint32_t *bptr, type, len;
>     +
>     +   KASSERT(preload_metadata !=3D NULL,
>     +       ("%s called without setting up preload_metadata", __func__));
>     +
>     +   /*
>     +    * Iterate through the TLV-encoded sections.
>     +    */
>     +   bptr =3D (uint32_t *)preload_metadata;
>     +   sbuf_putc(sbp, '\n');
>     +   while (bptr[0] !=3D MODINFO_END || bptr[0] !=3D MODINFO_END) {
>     +           sbuf_printf(sbp, " %p:\n", bptr);
>     +           type =3D *bptr++;
>     +           len =3D *bptr++;
>     +
>     +           sbuf_printf(sbp, "\ttype:\t(%#04x) ", type);
>     +           preload_modinfo_type(sbp, type);
>     +           sbuf_putc(sbp, '\n');
>     +           sbuf_printf(sbp, "\tlen:\t%u\n", len);
>     +           sbuf_cat(sbp, "\tvalue:\t");
>     +           preload_modinfo_value(sbp, bptr, type, len);
>     +           sbuf_putc(sbp, '\n');
>     +
>     +           bptr +=3D roundup(len, sizeof(u_long)) / sizeof(uint32_t)=
;
>     +   }
>     +}
>     +
>     +/*
>     + * Print the preloaded data to the console. Called from the machine-=
dependent
>     + * initialization routines, e.g. hammer_time().
>     + */
>     +void
>     +preload_dump(void)
>     +{
>     +   char buf[512];
>     +   struct sbuf sb;
>     +
>     +   /*
>     +    * This function is expected to be called before malloc is availa=
ble,
>     +    * so use a static buffer and struct sbuf.
>     +    */
>     +   sbuf_new(&sb, buf, sizeof(buf), SBUF_FIXEDLEN);
>     +   sbuf_set_drain(&sb, sbuf_printf_drain, NULL);
>     +   preload_dump_internal(&sb);
>     +
>     +   sbuf_finish(&sb);
>     +   sbuf_delete(&sb);
>     +}
>     +
>     +static int
>     +sysctl_preload_dump(SYSCTL_HANDLER_ARGS)
>     +{
>     +   struct sbuf sb;
>     +   int error;
>     +
>     +   if (preload_metadata =3D=3D NULL)
>     +           return (EINVAL);
>     +
>     +   sbuf_new_for_sysctl(&sb, NULL, 512, req);
>     +   preload_dump_internal(&sb);
>     +
>     +   error =3D sbuf_finish(&sb);
>     +   sbuf_delete(&sb);
>     +
>     +   return (error);
>     +}
>     +SYSCTL_PROC(_debug, OID_AUTO, dump_modinfo,
>     +    CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_MPSAFE,
>     +    NULL, 0, sysctl_preload_dump, "A",
>     +    "pretty-print the bootloader metadata");
>
>     Modified: head/sys/riscv/riscv/machdep.c
>     =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D
>     --- head/sys/riscv/riscv/machdep.c  Thu Oct  8 17:30:05 2020        (=
r366541)
>     +++ head/sys/riscv/riscv/machdep.c  Thu Oct  8 18:02:05 2020        (=
r366542)
>     @@ -949,6 +949,15 @@ initriscv(struct riscv_bootparams *rvbp)
>
>         cninit();
>
>     +   /*
>     +    * Dump the boot metadata. We have to wait for cninit() since con=
sole
>     +    * output is required. If it's grossly incorrect the kernel will =
never
>     +    * make it this far.
>     +    */
>     +   if ((boothowto & RB_VERBOSE) &&
>     +       getenv_is_true("debug.dump_modinfo_at_boot"))
>     +           preload_dump();
>     +
>         init_proc0(rvbp->kern_stack);
>
>         msgbufinit(msgbufp, msgbufsize);
>
>     Modified: head/sys/sys/linker.h
>     =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D
>     --- head/sys/sys/linker.h   Thu Oct  8 17:30:05 2020        (r366541)
>     +++ head/sys/sys/linker.h   Thu Oct  8 18:02:05 2020        (r366542)
>     @@ -257,6 +257,7 @@ extern caddr_t          preload_search_next_name(=
caddr_t _base
>      extern caddr_t             preload_search_info(caddr_t _mod, int _in=
f);
>      extern void                preload_delete_name(const char *_name);
>      extern void                preload_bootstrap_relocate(vm_offset_t _o=
ffset);
>     +extern void                preload_dump(void);
>
>      #ifdef KLD_DEBUG
>
>
>



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?CADeAsy1dykboVfBaGq3Br5bGNP2hzRaq71V7Wh9evg7=m8Y0iQ>