All of lore.kernel.org
 help / color / mirror / Atom feed
From: Pawel Wieczorkiewicz <wipawel@amazon.de>
To: <xen-devel@lists.xen.org>, <xen-devel@lists.xenproject.org>
Cc: wipawel@amazon.com, Stefano Stabellini <sstabellini@kernel.org>,
	Ross Lagerwall <ross.lagerwall@citrix.com>,
	Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>,
	Pawel Wieczorkiewicz <wipawel@amazon.de>,
	Julien Grall <julien.grall@arm.com>,
	Volodymyr Babchuk <Volodymyr_Babchuk@epam.com>
Subject: [Xen-devel] [PATCH] livepatch: always print XENLOG_ERR information (ARM, ELF)
Date: Wed, 21 Aug 2019 10:04:30 +0000	[thread overview]
Message-ID: <20190821100430.89909-1-wipawel@amazon.de> (raw)

This complements [1] commit for ARM and livepatch_elf files.

[1] 4470efeae4 livepatch: always print XENLOG_ERR information

Signed-off-by: Pawel Wieczorkiewicz <wipawel@amazon.de>
---
 xen/arch/arm/arm32/livepatch.c |  28 +++++------
 xen/arch/arm/arm64/livepatch.c |  28 +++++------
 xen/common/livepatch_elf.c     | 104 ++++++++++++++++++++---------------------
 3 files changed, 80 insertions(+), 80 deletions(-)

diff --git a/xen/arch/arm/arm32/livepatch.c b/xen/arch/arm/arm32/livepatch.c
index 41378a54ae..5a06467008 100644
--- a/xen/arch/arm/arm32/livepatch.c
+++ b/xen/arch/arm/arm32/livepatch.c
@@ -84,15 +84,15 @@ int arch_livepatch_verify_elf(const struct livepatch_elf *elf)
     if ( hdr->e_machine != EM_ARM ||
          hdr->e_ident[EI_CLASS] != ELFCLASS32 )
     {
-        dprintk(XENLOG_ERR, LIVEPATCH "%s: Unsupported ELF Machine type!\n",
-                elf->name);
+        printk(XENLOG_ERR LIVEPATCH "%s: Unsupported ELF Machine type\n",
+               elf->name);
         return -EOPNOTSUPP;
     }
 
     if ( (hdr->e_flags & EF_ARM_EABI_MASK) != EF_ARM_EABI_VER5 )
     {
-        dprintk(XENLOG_ERR, LIVEPATCH "%s: Unsupported ELF EABI(%x)!\n",
-                elf->name, hdr->e_flags);
+        printk(XENLOG_ERR LIVEPATCH "%s: Unsupported ELF EABI(%x)\n",
+               elf->name, hdr->e_flags);
         return -EOPNOTSUPP;
     }
 
@@ -256,20 +256,20 @@ int arch_livepatch_perform(struct livepatch_elf *elf,
 
         if ( symndx == STN_UNDEF )
         {
-            dprintk(XENLOG_ERR, LIVEPATCH "%s: Encountered STN_UNDEF\n",
-                    elf->name);
+            printk(XENLOG_ERR LIVEPATCH "%s: Encountered STN_UNDEF\n",
+                   elf->name);
             return -EOPNOTSUPP;
         }
         else if ( symndx >= elf->nsym )
         {
-            dprintk(XENLOG_ERR, LIVEPATCH "%s: Relative symbol wants symbol@%u which is past end!\n",
-                    elf->name, symndx);
+            printk(XENLOG_ERR LIVEPATCH "%s: Relative symbol wants symbol@%u which is past end\n",
+                   elf->name, symndx);
             return -EINVAL;
         }
         else if ( !elf->sym[symndx].sym )
         {
-            dprintk(XENLOG_ERR, LIVEPATCH "%s: No relative symbol@%u\n",
-                    elf->name, symndx);
+            printk(XENLOG_ERR LIVEPATCH "%s: No relative symbol@%u\n",
+                   elf->name, symndx);
             return -EINVAL;
         }
 
@@ -279,13 +279,13 @@ int arch_livepatch_perform(struct livepatch_elf *elf,
         switch ( rc )
         {
         case -EOVERFLOW:
-            dprintk(XENLOG_ERR, LIVEPATCH "%s: Overflow in relocation %u in %s for %s!\n",
-                    elf->name, i, rela->name, base->name);
+            printk(XENLOG_ERR LIVEPATCH "%s: Overflow in relocation %u in %s for %s\n",
+                   elf->name, i, rela->name, base->name);
             break;
 
         case -EOPNOTSUPP:
-            dprintk(XENLOG_ERR, LIVEPATCH "%s: Unhandled relocation #%x\n",
-                    elf->name, type);
+            printk(XENLOG_ERR LIVEPATCH "%s: Unhandled relocation #%x\n",
+                   elf->name, type);
             break;
         }
 
diff --git a/xen/arch/arm/arm64/livepatch.c b/xen/arch/arm/arm64/livepatch.c
index 5c75779284..6ec8dc60f0 100644
--- a/xen/arch/arm/arm64/livepatch.c
+++ b/xen/arch/arm/arm64/livepatch.c
@@ -71,8 +71,8 @@ int arch_livepatch_verify_elf(const struct livepatch_elf *elf)
     if ( hdr->e_machine != EM_AARCH64 ||
          hdr->e_ident[EI_CLASS] != ELFCLASS64 )
     {
-        dprintk(XENLOG_ERR, LIVEPATCH "%s: Unsupported ELF Machine type!\n",
-                elf->name);
+        printk(XENLOG_ERR LIVEPATCH "%s: Unsupported ELF Machine type\n",
+               elf->name);
         return -EOPNOTSUPP;
     }
 
@@ -254,20 +254,20 @@ int arch_livepatch_perform_rela(struct livepatch_elf *elf,
 
         if ( symndx == STN_UNDEF )
         {
-            dprintk(XENLOG_ERR, LIVEPATCH "%s: Encountered STN_UNDEF\n",
-                    elf->name);
+            printk(XENLOG_ERR LIVEPATCH "%s: Encountered STN_UNDEF\n",
+                   elf->name);
             return -EOPNOTSUPP;
         }
         else if ( symndx >= elf->nsym )
         {
-            dprintk(XENLOG_ERR, LIVEPATCH "%s: Relative relocation wants symbol@%u which is past end!\n",
-                    elf->name, symndx);
+            printk(XENLOG_ERR LIVEPATCH "%s: Relative relocation wants symbol@%u which is past end\n",
+                   elf->name, symndx);
             return -EINVAL;
         }
         else if ( !elf->sym[symndx].sym )
         {
-            dprintk(XENLOG_ERR, LIVEPATCH "%s: No relative symbol@%u\n",
-                    elf->name, symndx);
+            printk(XENLOG_ERR LIVEPATCH "%s: No relative symbol@%u\n",
+                   elf->name, symndx);
             return -EINVAL;
         }
 
@@ -465,23 +465,23 @@ int arch_livepatch_perform_rela(struct livepatch_elf *elf,
             break;
 
         default:
-            dprintk(XENLOG_ERR, LIVEPATCH "%s: Unhandled relocation %lu\n",
-                    elf->name, ELF64_R_TYPE(r->r_info));
+            printk(XENLOG_ERR LIVEPATCH "%s: Unhandled relocation %lu\n",
+                   elf->name, ELF64_R_TYPE(r->r_info));
             return -EOPNOTSUPP;
         }
 
         if ( overflow_check && ovf == -EOVERFLOW )
         {
-            dprintk(XENLOG_ERR, LIVEPATCH "%s: Overflow in relocation %u in %s for %s!\n",
-                    elf->name, i, rela->name, base->name);
+            printk(XENLOG_ERR LIVEPATCH "%s: Overflow in relocation %u in %s for %s\n",
+                   elf->name, i, rela->name, base->name);
             return ovf;
         }
     }
     return 0;
 
  bad_offset:
-    dprintk(XENLOG_ERR, LIVEPATCH "%s: Relative relocation offset is past %s section!\n",
-            elf->name, base->name);
+    printk(XENLOG_ERR LIVEPATCH "%s: Relative relocation offset is past %s section\n",
+           elf->name, base->name);
     return -EINVAL;
 }
 
diff --git a/xen/common/livepatch_elf.c b/xen/common/livepatch_elf.c
index dd8b47a1fa..18b9684aeb 100644
--- a/xen/common/livepatch_elf.c
+++ b/xen/common/livepatch_elf.c
@@ -55,7 +55,7 @@ static int elf_resolve_sections(struct livepatch_elf *elf, const void *data)
     sec = xzalloc_array(struct livepatch_elf_sec, elf->hdr->e_shnum);
     if ( !sec )
     {
-        dprintk(XENLOG_ERR, LIVEPATCH"%s: Could not allocate memory for section table!\n",
+        printk(XENLOG_ERR LIVEPATCH"%s: Could not allocate memory for section table\n",
                elf->name);
         return -ENOMEM;
     }
@@ -81,22 +81,22 @@ static int elf_resolve_sections(struct livepatch_elf *elf, const void *data)
              (sec[i].sec->sh_type != SHT_NOBITS && /* Skip SHT_NOBITS */
               (delta > elf->len || (delta + sec[i].sec->sh_size > elf->len))) )
         {
-            dprintk(XENLOG_ERR, LIVEPATCH "%s: Section [%u] data %s of payload!\n",
-                    elf->name, i,
+            printk(XENLOG_ERR LIVEPATCH "%s: Section [%u] data %s of payload\n",
+                   elf->name, i,
                     delta < sizeof(Elf_Ehdr) ? "at ELF header" : "is past end");
             return -EINVAL;
         }
         else if ( sec[i].sec->sh_addralign & (sec[i].sec->sh_addralign - 1) )
         {
-            dprintk(XENLOG_ERR, LIVEPATCH "%s: Section [%u] alignment (%#"PRIxElfAddr") is not supported\n",
-                    elf->name, i, sec[i].sec->sh_addralign);
+            printk(XENLOG_ERR LIVEPATCH "%s: Section [%u] alignment (%#"PRIxElfAddr") is not supported\n",
+                   elf->name, i, sec[i].sec->sh_addralign);
             return -EOPNOTSUPP;
         }
         else if ( sec[i].sec->sh_addralign &&
                   sec[i].sec->sh_addr % sec[i].sec->sh_addralign )
         {
-            dprintk(XENLOG_ERR, LIVEPATCH "%s: Section [%u] addr (%#"PRIxElfAddr") is not aligned properly (%#"PRIxElfAddr")\n",
-                    elf->name, i, sec[i].sec->sh_addr, sec[i].sec->sh_addralign);
+            printk(XENLOG_ERR LIVEPATCH "%s: Section [%u] addr (%#"PRIxElfAddr") is not aligned properly (%#"PRIxElfAddr")\n",
+                   elf->name, i, sec[i].sec->sh_addr, sec[i].sec->sh_addralign);
             return -EINVAL;
         }
         else if ( (sec[i].sec->sh_flags & (SHF_WRITE | SHF_ALLOC)) &&
@@ -112,8 +112,8 @@ static int elf_resolve_sections(struct livepatch_elf *elf, const void *data)
         {
             if ( elf->symtab )
             {
-                dprintk(XENLOG_ERR, LIVEPATCH "%s: Unsupported multiple symbol tables!\n",
-                        elf->name);
+                printk(XENLOG_ERR LIVEPATCH "%s: Unsupported multiple symbol tables\n",
+                       elf->name);
                 return -EOPNOTSUPP;
             }
 
@@ -126,10 +126,10 @@ static int elf_resolve_sections(struct livepatch_elf *elf, const void *data)
              */
             if ( elf->symtab->sec->sh_link >= elf->hdr->e_shnum )
             {
-                dprintk(XENLOG_ERR, LIVEPATCH
-                        "%s: Symbol table idx (%u) to strtab past end (%u)\n",
-                        elf->name, elf->symtab->sec->sh_link,
-                        elf->hdr->e_shnum);
+                printk(XENLOG_ERR LIVEPATCH
+                       "%s: Symbol table idx (%u) to strtab past end (%u)\n",
+                       elf->name, elf->symtab->sec->sh_link,
+                       elf->hdr->e_shnum);
                 return -EINVAL;
             }
         }
@@ -137,8 +137,8 @@ static int elf_resolve_sections(struct livepatch_elf *elf, const void *data)
 
     if ( !elf->symtab )
     {
-        dprintk(XENLOG_ERR, LIVEPATCH "%s: No symbol table found!\n",
-                elf->name);
+        printk(XENLOG_ERR LIVEPATCH "%s: No symbol table found\n",
+               elf->name);
         return -EINVAL;
     }
 
@@ -146,8 +146,8 @@ static int elf_resolve_sections(struct livepatch_elf *elf, const void *data)
          elf->symtab->sec->sh_entsize < sizeof(Elf_Sym) ||
          elf->symtab->sec->sh_size % elf->symtab->sec->sh_entsize )
     {
-        dprintk(XENLOG_ERR, LIVEPATCH "%s: Symbol table header is corrupted!\n",
-                elf->name);
+        printk(XENLOG_ERR LIVEPATCH "%s: Symbol table header is corrupted\n",
+               elf->name);
         return -EINVAL;
     }
 
@@ -160,8 +160,8 @@ static int elf_resolve_sections(struct livepatch_elf *elf, const void *data)
     rc = elf_verify_strtab(elf->strtab);
     if ( rc )
     {
-        dprintk(XENLOG_ERR, LIVEPATCH "%s: String table section is corrupted\n",
-                elf->name);
+        printk(XENLOG_ERR LIVEPATCH "%s: String table section is corrupted\n",
+               elf->name);
     }
 
     return rc;
@@ -185,8 +185,8 @@ static int elf_resolve_section_names(struct livepatch_elf *elf, const void *data
     rc = elf_verify_strtab(sec);
     if ( rc )
     {
-        dprintk(XENLOG_ERR, LIVEPATCH "%s: Section string table is corrupted\n",
-                elf->name);
+        printk(XENLOG_ERR LIVEPATCH "%s: Section string table is corrupted\n",
+               elf->name);
         return rc;
     }
 
@@ -203,8 +203,8 @@ static int elf_resolve_section_names(struct livepatch_elf *elf, const void *data
         /* Boundary check on offset of name within the .shstrtab. */
         if ( delta >= sec->sec->sh_size )
         {
-            dprintk(XENLOG_ERR, LIVEPATCH "%s: Section %u name is not within .shstrtab!\n",
-                    elf->name, i);
+            printk(XENLOG_ERR LIVEPATCH "%s: Section %u name is not within .shstrtab\n",
+                   elf->name, i);
             return -EINVAL;
         }
 
@@ -241,7 +241,7 @@ static int elf_get_sym(struct livepatch_elf *elf, const void *data)
     sym = xzalloc_array(struct livepatch_elf_sym, nsym);
     if ( !sym )
     {
-        dprintk(XENLOG_ERR, LIVEPATCH "%s: Could not allocate memory for symbols\n",
+        printk(XENLOG_ERR LIVEPATCH "%s: Could not allocate memory for symbols\n",
                elf->name);
         return -ENOMEM;
     }
@@ -257,8 +257,8 @@ static int elf_get_sym(struct livepatch_elf *elf, const void *data)
         /* Boundary check within the .strtab. */
         if ( delta >= strtab_sec->sec->sh_size )
         {
-            dprintk(XENLOG_ERR, LIVEPATCH "%s: Symbol [%u] name is not within .strtab!\n",
-                    elf->name, i);
+            printk(XENLOG_ERR LIVEPATCH "%s: Symbol [%u] name is not within .strtab\n",
+                   elf->name, i);
             return -EINVAL;
         }
 
@@ -266,8 +266,8 @@ static int elf_get_sym(struct livepatch_elf *elf, const void *data)
         sym[i].name = strtab_sec->data + delta;
         if ( arch_livepatch_symbol_deny(elf, &sym[i]) )
         {
-            dprintk(XENLOG_ERR, LIVEPATCH "%s: Symbol '%s' should not be in payload!\n",
-                    elf->name, sym[i].name);
+            printk(XENLOG_ERR LIVEPATCH "%s: Symbol '%s' should not be in payload\n",
+                   elf->name, sym[i].name);
             return -EINVAL;
         }
     }
@@ -292,8 +292,8 @@ int livepatch_elf_resolve_symbols(struct livepatch_elf *elf)
         switch ( idx )
         {
         case SHN_COMMON:
-            dprintk(XENLOG_ERR, LIVEPATCH "%s: Unexpected common symbol: %s\n",
-                    elf->name, elf->sym[i].name);
+            printk(XENLOG_ERR LIVEPATCH "%s: Unexpected common symbol: %s\n",
+                   elf->name, elf->sym[i].name);
             rc = -EINVAL;
             break;
 
@@ -304,8 +304,8 @@ int livepatch_elf_resolve_symbols(struct livepatch_elf *elf)
                 st_value = livepatch_symbols_lookup_by_name(elf->sym[i].name);
                 if ( !st_value )
                 {
-                    dprintk(XENLOG_ERR, LIVEPATCH "%s: Unknown symbol: %s\n",
-                            elf->name, elf->sym[i].name);
+                    printk(XENLOG_ERR LIVEPATCH "%s: Unknown symbol: %s\n",
+                           elf->name, elf->sym[i].name);
                     rc = -ENOENT;
                     break;
                 }
@@ -328,7 +328,7 @@ int livepatch_elf_resolve_symbols(struct livepatch_elf *elf)
 
             if ( rc )
             {
-                dprintk(XENLOG_ERR, LIVEPATCH "%s: Out of bounds symbol section %#x\n",
+                printk(XENLOG_ERR LIVEPATCH "%s: Out of bounds symbol section %#x\n",
                         elf->name, idx);
                 break;
             }
@@ -381,8 +381,8 @@ int livepatch_elf_perform_relocs(struct livepatch_elf *elf)
 
         if ( r->sec->sh_link != elf->symtab_idx )
         {
-            dprintk(XENLOG_ERR, LIVEPATCH "%s: Relative link of %s is incorrect (%d, expected=%d)\n",
-                    elf->name, r->name, r->sec->sh_link, elf->symtab_idx);
+            printk(XENLOG_ERR LIVEPATCH "%s: Relative link of %s is incorrect (%d, expected=%d)\n",
+                   elf->name, r->name, r->sec->sh_link, elf->symtab_idx);
             rc = -EINVAL;
             break;
         }
@@ -397,8 +397,8 @@ int livepatch_elf_perform_relocs(struct livepatch_elf *elf)
 
         if ( r->sec->sh_entsize < sz || r->sec->sh_size % r->sec->sh_entsize )
         {
-            dprintk(XENLOG_ERR, LIVEPATCH "%s: Section relative header is corrupted!\n",
-                    elf->name);
+            printk(XENLOG_ERR LIVEPATCH "%s: Section relative header is corrupted\n",
+                   elf->name);
             rc = -EINVAL;
             break;
         }
@@ -422,14 +422,14 @@ static int livepatch_header_check(const struct livepatch_elf *elf)
 
     if ( sizeof(*elf->hdr) > elf->len )
     {
-        dprintk(XENLOG_ERR, LIVEPATCH "%s: Section header is bigger than payload!\n",
-                elf->name);
+        printk(XENLOG_ERR LIVEPATCH "%s: Section header is bigger than payload\n",
+               elf->name);
         return -EINVAL;
     }
 
     if ( !IS_ELF(*hdr) )
     {
-        dprintk(XENLOG_ERR, LIVEPATCH "%s: Not an ELF payload!\n", elf->name);
+        printk(XENLOG_ERR LIVEPATCH "%s: Not an ELF payload\n", elf->name);
         return -EINVAL;
     }
 
@@ -442,7 +442,7 @@ static int livepatch_header_check(const struct livepatch_elf *elf)
          hdr->e_type != ET_REL ||
          hdr->e_phnum != 0 )
     {
-        dprintk(XENLOG_ERR, LIVEPATCH "%s: Invalid ELF payload!\n", elf->name);
+        printk(XENLOG_ERR LIVEPATCH "%s: Invalid ELF payload\n", elf->name);
         return -EOPNOTSUPP;
     }
 
@@ -452,45 +452,45 @@ static int livepatch_header_check(const struct livepatch_elf *elf)
 
     if ( elf->hdr->e_shstrndx == SHN_UNDEF )
     {
-        dprintk(XENLOG_ERR, LIVEPATCH "%s: Section name idx is undefined!?\n",
-                elf->name);
+        printk(XENLOG_ERR LIVEPATCH "%s: Section name idx is undefined\n",
+               elf->name);
         return -EINVAL;
     }
 
     /* Arbitrary boundary limit. */
     if ( elf->hdr->e_shnum >= 1024 )
     {
-        dprintk(XENLOG_ERR, LIVEPATCH "%s: Too many (%u) sections!\n",
-                elf->name, elf->hdr->e_shnum);
+        printk(XENLOG_ERR LIVEPATCH "%s: Too many (%u) sections\n",
+               elf->name, elf->hdr->e_shnum);
         return -EOPNOTSUPP;
     }
 
     /* Check that section name index is within the sections. */
     if ( elf->hdr->e_shstrndx >= elf->hdr->e_shnum )
     {
-        dprintk(XENLOG_ERR, LIVEPATCH "%s: Section name idx (%u) is past end of sections (%u)!\n",
-                elf->name, elf->hdr->e_shstrndx, elf->hdr->e_shnum);
+        printk(XENLOG_ERR LIVEPATCH "%s: Section name idx (%u) is past end of sections (%u)\n",
+               elf->name, elf->hdr->e_shstrndx, elf->hdr->e_shnum);
         return -EINVAL;
     }
 
     if ( elf->hdr->e_shoff >= elf->len )
     {
-        dprintk(XENLOG_ERR, LIVEPATCH "%s: Bogus e_shoff!\n", elf->name);
+        printk(XENLOG_ERR LIVEPATCH "%s: Bogus e_shoff\n", elf->name);
         return -EINVAL;
     }
 
     if ( elf->hdr->e_shentsize < sizeof(Elf_Shdr) )
     {
-        dprintk(XENLOG_ERR, LIVEPATCH "%s: Section header size is %u! Expected %zu!?\n",
-                elf->name, elf->hdr->e_shentsize, sizeof(Elf_Shdr));
+        printk(XENLOG_ERR LIVEPATCH "%s: Section header size is %u! Expected %zu.\n",
+               elf->name, elf->hdr->e_shentsize, sizeof(Elf_Shdr));
         return -EINVAL;
     }
 
     if ( ((elf->len - elf->hdr->e_shoff) / elf->hdr->e_shentsize) <
          elf->hdr->e_shnum )
     {
-        dprintk(XENLOG_ERR, LIVEPATCH "%s: Section header size is corrupted!\n",
-                elf->name);
+        printk(XENLOG_ERR LIVEPATCH "%s: Section header size is corrupted\n",
+               elf->name);
         return -EINVAL;
     }
 
-- 
2.16.5




Amazon Development Center Germany GmbH
Krausenstr. 38
10117 Berlin
Geschaeftsfuehrung: Christian Schlaeger, Ralf Herbrich
Eingetragen am Amtsgericht Charlottenburg unter HRB 149173 B
Sitz: Berlin
Ust-ID: DE 289 237 879




_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

             reply	other threads:[~2019-08-21 10:05 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-08-21 10:04 Pawel Wieczorkiewicz [this message]
2019-08-21 10:20 ` [Xen-devel] [PATCH] livepatch: always print XENLOG_ERR information (ARM, ELF) Andrew Cooper
2019-08-21 21:16   ` Julien Grall
2019-09-13 10:01 ` Ross Lagerwall

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20190821100430.89909-1-wipawel@amazon.de \
    --to=wipawel@amazon.de \
    --cc=Volodymyr_Babchuk@epam.com \
    --cc=julien.grall@arm.com \
    --cc=konrad.wilk@oracle.com \
    --cc=ross.lagerwall@citrix.com \
    --cc=sstabellini@kernel.org \
    --cc=wipawel@amazon.com \
    --cc=xen-devel@lists.xen.org \
    --cc=xen-devel@lists.xenproject.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.