qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: imp@bsdimp.com
To: qemu-devel@nongnu.org
Cc: kevans@freebsd.org,
	Richard Henderson <richard.henderson@linaro.org>,
	Warner Losh <imp@FreeBSD.org>, Warner Losh <imp@bsdimp.com>
Subject: [PATCH v3 38/43] bsd-user: elfload.c style catch up patch
Date: Thu,  2 Sep 2021 17:47:24 -0600	[thread overview]
Message-ID: <20210902234729.76141-39-imp@bsdimp.com> (raw)
In-Reply-To: <20210902234729.76141-1-imp@bsdimp.com>

From: Warner Losh <imp@FreeBSD.org>

Various style fixes to elfload.c that were too painful to make earlier
in this series.

Signed-off-by: Warner Losh <imp@bsdimp.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
---
 bsd-user/elfload.c | 208 ++++++++++++++++++++++-----------------------
 1 file changed, 104 insertions(+), 104 deletions(-)

diff --git a/bsd-user/elfload.c b/bsd-user/elfload.c
index 05751f3ce7..3660961582 100644
--- a/bsd-user/elfload.c
+++ b/bsd-user/elfload.c
@@ -143,10 +143,12 @@ static abi_ulong copy_elf_strings(int argc, char **argv, void **page,
             exit(-1);
         }
         tmp1 = tmp;
-        while (*tmp++);
+        while (*tmp++) {
+            continue;
+        }
         len = tmp - tmp1;
         if (p < len) {  /* this shouldn't happen - 128kB */
-                return 0;
+            return 0;
         }
         while (len) {
             --p; --tmp; --len;
@@ -156,14 +158,14 @@ static abi_ulong copy_elf_strings(int argc, char **argv, void **page,
                 if (!pag) {
                     pag = g_try_malloc0(TARGET_PAGE_SIZE);
                     page[p / TARGET_PAGE_SIZE] = pag;
-                    if (!pag)
+                    if (!pag) {
                         return 0;
+                    }
                 }
             }
             if (len == 0 || offset == 0) {
                 *(pag + offset) = *tmp;
-            }
-            else {
+            } else {
               int bytes_to_copy = (len > offset) ? offset : len;
               tmp -= bytes_to_copy;
               p -= bytes_to_copy;
@@ -182,16 +184,14 @@ static void setup_arg_pages(struct bsd_binprm *bprm, struct image_info *info,
     abi_ulong stack_base, size;
     abi_long addr;
 
-    /* Create enough stack to hold everything.  If we don't use
-     * it for args, we'll use it for something else...
+    /*
+     * Create enough stack to hold everything.  If we don't use it for args,
+     * we'll use it for something else...
      */
     size = target_dflssiz;
     stack_base = TARGET_USRSTACK - size;
-    addr = target_mmap(stack_base,
-                        size + qemu_host_page_size,
-                        PROT_READ | PROT_WRITE,
-                        MAP_PRIVATE | MAP_ANON,
-                        -1, 0);
+    addr = target_mmap(stack_base , size + qemu_host_page_size,
+            PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0);
     if (addr == -1) {
         perror("stk mmap");
         exit(-1);
@@ -210,55 +210,60 @@ static void setup_arg_pages(struct bsd_binprm *bprm, struct image_info *info,
 
 static void set_brk(abi_ulong start, abi_ulong end)
 {
-        /* page-align the start and end addresses... */
-        start = HOST_PAGE_ALIGN(start);
-        end = HOST_PAGE_ALIGN(end);
-        if (end <= start)
-                return;
-        if (target_mmap(start, end - start,
-                       PROT_READ | PROT_WRITE | PROT_EXEC,
-                       MAP_FIXED | MAP_PRIVATE | MAP_ANON, -1, 0) == -1) {
-            perror("cannot mmap brk");
-            exit(-1);
-        }
+    /* page-align the start and end addresses... */
+    start = HOST_PAGE_ALIGN(start);
+    end = HOST_PAGE_ALIGN(end);
+    if (end <= start) {
+        return;
+    }
+    if (target_mmap(start, end - start, PROT_READ | PROT_WRITE | PROT_EXEC,
+        MAP_FIXED | MAP_PRIVATE | MAP_ANON, -1, 0) == -1) {
+        perror("cannot mmap brk");
+        exit(-1);
+    }
 }
 
 
-/* We need to explicitly zero any fractional pages after the data
-   section (i.e. bss).  This would contain the junk from the file that
-   should not be in memory. */
+/*
+ * We need to explicitly zero any fractional pages after the data
+ * section (i.e. bss).  This would contain the junk from the file that
+ * should not be in memory.
+ */
 static void padzero(abi_ulong elf_bss, abi_ulong last_bss)
 {
-        abi_ulong nbyte;
+    abi_ulong nbyte;
 
-        if (elf_bss >= last_bss)
-                return;
+    if (elf_bss >= last_bss) {
+        return;
+    }
 
-        /* XXX: this is really a hack : if the real host page size is
-           smaller than the target page size, some pages after the end
-           of the file may not be mapped. A better fix would be to
-           patch target_mmap(), but it is more complicated as the file
-           size must be known */
-        if (qemu_real_host_page_size < qemu_host_page_size) {
-            abi_ulong end_addr, end_addr1;
-            end_addr1 = REAL_HOST_PAGE_ALIGN(elf_bss);
-            end_addr = HOST_PAGE_ALIGN(elf_bss);
-            if (end_addr1 < end_addr) {
-                mmap((void *)g2h_untagged(end_addr1), end_addr - end_addr1,
-                     PROT_READ | PROT_WRITE | PROT_EXEC,
-                     MAP_FIXED | MAP_PRIVATE | MAP_ANON, -1, 0);
-            }
+    /*
+     * XXX: this is really a hack : if the real host page size is
+     * smaller than the target page size, some pages after the end
+     * of the file may not be mapped. A better fix would be to
+     * patch target_mmap(), but it is more complicated as the file
+     * size must be known.
+     */
+    if (qemu_real_host_page_size < qemu_host_page_size) {
+        abi_ulong end_addr, end_addr1;
+        end_addr1 = REAL_HOST_PAGE_ALIGN(elf_bss);
+        end_addr = HOST_PAGE_ALIGN(elf_bss);
+        if (end_addr1 < end_addr) {
+            mmap((void *)g2h_untagged(end_addr1), end_addr - end_addr1,
+                 PROT_READ | PROT_WRITE | PROT_EXEC,
+                 MAP_FIXED | MAP_PRIVATE | MAP_ANON, -1, 0);
         }
+    }
 
-        nbyte = elf_bss & (qemu_host_page_size - 1);
-        if (nbyte) {
-            nbyte = qemu_host_page_size - nbyte;
-            do {
-                /* FIXME - what to do if put_user() fails? */
-                put_user_u8(0, elf_bss);
-                elf_bss++;
-            } while (--nbyte);
-        }
+    nbyte = elf_bss & (qemu_host_page_size - 1);
+    if (nbyte) {
+        nbyte = qemu_host_page_size - nbyte;
+        do {
+            /* FIXME - what to do if put_user() fails? */
+            put_user_u8(0, elf_bss);
+            elf_bss++;
+        } while (--nbyte);
+    }
 }
 
 static abi_ulong load_elf_interp(struct elfhdr *interp_elf_ex,
@@ -280,23 +285,23 @@ static abi_ulong load_elf_interp(struct elfhdr *interp_elf_ex,
 
     bswap_ehdr(interp_elf_ex);
     /* First of all, some simple consistency checks */
-    if ((interp_elf_ex->e_type != ET_EXEC &&
-         interp_elf_ex->e_type != ET_DYN) ||
-        !elf_check_arch(interp_elf_ex->e_machine)) {
+    if ((interp_elf_ex->e_type != ET_EXEC && interp_elf_ex->e_type != ET_DYN) ||
+          !elf_check_arch(interp_elf_ex->e_machine)) {
         return ~((abi_ulong)0UL);
     }
 
 
     /* Now read in all of the header information */
-
-    if (sizeof(struct elf_phdr) * interp_elf_ex->e_phnum > TARGET_PAGE_SIZE)
+    if (sizeof(struct elf_phdr) * interp_elf_ex->e_phnum > TARGET_PAGE_SIZE) {
         return ~(abi_ulong)0UL;
+    }
 
-    elf_phdata =  (struct elf_phdr *)
-        malloc(sizeof(struct elf_phdr) * interp_elf_ex->e_phnum);
+    elf_phdata =  (struct elf_phdr *) malloc(sizeof(struct elf_phdr) *
+            interp_elf_ex->e_phnum);
 
-    if (!elf_phdata)
+    if (!elf_phdata) {
         return ~((abi_ulong)0UL);
+    }
 
     /*
      * If the size of this structure has changed, then punt, since
@@ -309,9 +314,8 @@ static abi_ulong load_elf_interp(struct elfhdr *interp_elf_ex,
 
     retval = lseek(interpreter_fd, interp_elf_ex->e_phoff, SEEK_SET);
     if (retval >= 0) {
-        retval = read(interpreter_fd,
-                      (char *) elf_phdata,
-                      sizeof(struct elf_phdr) * interp_elf_ex->e_phnum);
+        retval = read(interpreter_fd, (char *) elf_phdata,
+                sizeof(struct elf_phdr) * interp_elf_ex->e_phnum);
     }
     if (retval < 0) {
         perror("load_elf_interp");
@@ -322,11 +326,12 @@ static abi_ulong load_elf_interp(struct elfhdr *interp_elf_ex,
     bswap_phdr(elf_phdata, interp_elf_ex->e_phnum);
 
     if (interp_elf_ex->e_type == ET_DYN) {
-        /* in order to avoid hardcoding the interpreter load
-           address in qemu, we allocate a big enough memory zone */
-        error = target_mmap(0, INTERP_MAP_SIZE,
-                            PROT_NONE, MAP_PRIVATE | MAP_ANON,
-                            -1, 0);
+        /*
+         * In order to avoid hardcoding the interpreter load
+         * address in qemu, we allocate a big enough memory zone.
+         */
+        error = target_mmap(0, INTERP_MAP_SIZE, PROT_NONE,
+                MAP_PRIVATE | MAP_ANON, -1, 0);
         if (error == -1) {
             perror("mmap");
             exit(-1);
@@ -430,7 +435,7 @@ static const char *lookup_symbolxx(struct syminfo *s, target_ulong orig_addr)
     struct elf_sym *syms = s->disas_symtab.elf64;
 #endif
 
-    // binary search
+    /* binary search */
     struct elf_sym *sym;
 
     sym = bsearch(&orig_addr, syms, s->disas_num_syms, sizeof(*syms), symfind);
@@ -446,9 +451,8 @@ static int symcmp(const void *s0, const void *s1)
 {
     struct elf_sym *sym0 = (struct elf_sym *)s0;
     struct elf_sym *sym1 = (struct elf_sym *)s1;
-    return (sym0->st_value < sym1->st_value)
-        ? -1
-        : ((sym0->st_value > sym1->st_value) ? 1 : 0);
+    return (sym0->st_value < sym1->st_value) ? -1 :
+        ((sym0->st_value > sym1->st_value) ? 1 : 0);
 }
 
 /* Best attempt to load symbols from this ELF object. */
@@ -462,23 +466,24 @@ static void load_symbols(struct elfhdr *hdr, int fd)
 
     lseek(fd, hdr->e_shoff, SEEK_SET);
     for (i = 0; i < hdr->e_shnum; i++) {
-        if (read(fd, &sechdr, sizeof(sechdr)) != sizeof(sechdr))
+        if (read(fd, &sechdr, sizeof(sechdr)) != sizeof(sechdr)) {
             return;
+        }
         bswap_shdr(&sechdr, 1);
         if (sechdr.sh_type == SHT_SYMTAB) {
             symtab = sechdr;
-            lseek(fd, hdr->e_shoff
-                  + sizeof(sechdr) * sechdr.sh_link, SEEK_SET);
-            if (read(fd, &strtab, sizeof(strtab))
-                != sizeof(strtab))
+            lseek(fd, hdr->e_shoff + sizeof(sechdr) * sechdr.sh_link,
+                  SEEK_SET);
+            if (read(fd, &strtab, sizeof(strtab)) != sizeof(strtab)) {
                 return;
+            }
             bswap_shdr(&strtab, 1);
             goto found;
         }
     }
     return; /* Shouldn't happen... */
 
- found:
+found:
     /* Now know where the strtab and symtab are.  Snarf them. */
     s = malloc(sizeof(*s));
     syms = malloc(symtab.sh_size);
@@ -506,7 +511,7 @@ static void load_symbols(struct elfhdr *hdr, int fd)
     i = 0;
     while (i < nsyms) {
         bswap_sym(syms + i);
-        // Throw away entries which we do not need.
+        /* Throw away entries which we do not need. */
         if (syms[i].st_shndx == SHN_UNDEF ||
                 syms[i].st_shndx >= SHN_LORESERVE ||
                 ELF_ST_TYPE(syms[i].st_info) != STT_FUNC) {
@@ -519,10 +524,12 @@ static void load_symbols(struct elfhdr *hdr, int fd)
         i++;
     }
 
-     /* Attempt to free the storage associated with the local symbols
-        that we threw away.  Whether or not this has any effect on the
-        memory allocation depends on the malloc implementation and how
-        many symbols we managed to discard. */
+     /*
+      * Attempt to free the storage associated with the local symbols
+      * that we threw away.  Whether or not this has any effect on the
+      * memory allocation depends on the malloc implementation and how
+      * many symbols we managed to discard.
+      */
     new_syms = realloc(syms, nsyms * sizeof(*syms));
     if (new_syms == NULL) {
         free(s);
@@ -578,19 +585,19 @@ int load_elf_binary(struct bsd_binprm *bprm, struct target_pt_regs *regs,
 
     /* First of all, some simple consistency checks */
     if ((elf_ex.e_type != ET_EXEC && elf_ex.e_type != ET_DYN) ||
-                                (!elf_check_arch(elf_ex.e_machine))) {
+        (!elf_check_arch(elf_ex.e_machine))) {
             return -ENOEXEC;
     }
 
     bprm->p = copy_elf_strings(1, &bprm->filename, bprm->page, bprm->p);
-    bprm->p = copy_elf_strings(bprm->envc, bprm->envp, bprm->page,bprm->p);
-    bprm->p = copy_elf_strings(bprm->argc, bprm->argv, bprm->page,bprm->p);
+    bprm->p = copy_elf_strings(bprm->envc, bprm->envp, bprm->page, bprm->p);
+    bprm->p = copy_elf_strings(bprm->argc, bprm->argv, bprm->page, bprm->p);
     if (!bprm->p) {
         retval = -E2BIG;
     }
 
     /* Now read in all of the header information */
-    elf_phdata = (struct elf_phdr *)malloc(elf_ex.e_phentsize*elf_ex.e_phnum);
+    elf_phdata = (struct elf_phdr *)malloc(elf_ex.e_phentsize * elf_ex.e_phnum);
     if (elf_phdata == NULL) {
         return -ENOMEM;
     }
@@ -609,7 +616,6 @@ int load_elf_binary(struct bsd_binprm *bprm, struct target_pt_regs *regs,
     }
 
     bswap_phdr(elf_phdata, elf_ex.e_phnum);
-
     elf_ppnt = elf_phdata;
 
     elf_bss = 0;
@@ -622,23 +628,16 @@ int load_elf_binary(struct bsd_binprm *bprm, struct target_pt_regs *regs,
     start_data = 0;
     end_data = 0;
 
-    for (i = 0;i < elf_ex.e_phnum; i++) {
+    for (i = 0; i < elf_ex.e_phnum; i++) {
         if (elf_ppnt->p_type == PT_INTERP) {
-            if (elf_interpreter != NULL)
-            {
+            if (elf_interpreter != NULL) {
                 free(elf_phdata);
                 free(elf_interpreter);
                 close(bprm->fd);
                 return -EINVAL;
             }
 
-            /* This is the program interpreter used for
-             * shared libraries - for now assume that this
-             * is an a.out format binary
-             */
-
             elf_interpreter = (char *)malloc(elf_ppnt->p_filesz);
-
             if (elf_interpreter == NULL) {
                 free(elf_phdata);
                 close(bprm->fd);
@@ -658,8 +657,7 @@ int load_elf_binary(struct bsd_binprm *bprm, struct target_pt_regs *regs,
                 retval = open(path(elf_interpreter), O_RDONLY);
                 if (retval >= 0) {
                     interpreter_fd = retval;
-                }
-                else {
+                } else {
                     perror(elf_interpreter);
                     exit(-1);
                     /* retval = -errno; */
@@ -673,7 +671,7 @@ int load_elf_binary(struct bsd_binprm *bprm, struct target_pt_regs *regs,
                 }
             }
             if (retval >= 0) {
-                interp_elf_ex = *((struct elfhdr *) bprm->buf); /* elf exec-header */
+                interp_elf_ex = *((struct elfhdr *) bprm->buf);
             }
             if (retval < 0) {
                 perror("load_elf_binary3");
@@ -698,9 +696,10 @@ int load_elf_binary(struct bsd_binprm *bprm, struct target_pt_regs *regs,
         }
     }
 
-    /* OK, we are done with that, now set up the arg stuff,
-       and then start this sucker up */
-
+    /*
+     * OK, we are done with that, now set up the arg stuff, and then start this
+     * sucker up
+     */
     if (!bprm->p) {
         free(elf_interpreter);
         free(elf_phdata);
@@ -822,8 +821,9 @@ int load_elf_binary(struct bsd_binprm *bprm, struct target_pt_regs *regs,
 
     free(elf_phdata);
 
-    if (qemu_log_enabled())
+    if (qemu_log_enabled()) {
         load_symbols(&elf_ex, bprm->fd);
+    }
 
     close(bprm->fd);
 
-- 
2.32.0



  parent reply	other threads:[~2021-09-03  0:19 UTC|newest]

Thread overview: 64+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-09-02 23:46 [PATCH v3 00/43] bsd-user updates to run hello world imp
2021-09-02 23:46 ` [PATCH v3 01/43] bsd-user: remove sparc and sparc64 imp
2021-09-02 23:46 ` [PATCH v3 02/43] bsd-user: add copyright header to elfload.c imp
2021-09-02 23:46 ` [PATCH v3 03/43] bsd-user: Add Stacey's copyright to main.c imp
2021-09-02 23:46 ` [PATCH v3 04/43] bsd-user: add license to bsdload.c imp
2021-09-02 23:46 ` [PATCH v3 05/43] bsd-user: style nits: bsdload.c whitespace to qemu standard imp
2021-09-02 23:46 ` [PATCH v3 06/43] bsd-user: Remove all non-x86 code from elfload.c imp
2021-09-02 23:46 ` [PATCH v3 07/43] bsd-user: move arch specific defines out of elfload.c imp
2021-09-02 23:46 ` [PATCH v3 08/43] bsd-user: pass the bsd_param into loader_exec imp
2021-09-02 23:46 ` [PATCH v3 09/43] bsd-user: Fix calculation of size to allocate imp
2021-09-02 23:46 ` [PATCH v3 10/43] bsd-user: implement path searching imp
2021-09-05 10:11   ` Richard Henderson
2021-09-02 23:46 ` [PATCH v3 11/43] bsd-user: Eliminate elf personality imp
2021-09-02 23:46 ` [PATCH v3 12/43] bsd-user: remove a.out support imp
2021-09-02 23:46 ` [PATCH v3 13/43] bsd-user: TARGET_NGROUPS unused in this file, remove imp
2021-09-02 23:47 ` [PATCH v3 14/43] bsd-user: elfload: simplify bswap a bit imp
2021-09-02 23:47 ` [PATCH v3 15/43] bsd-user: assume pthreads and support of __thread imp
2021-09-02 23:47 ` [PATCH v3 16/43] bsd-user: add host-os.h imp
2021-09-02 23:47 ` [PATCH v3 17/43] bsd-user: Include host-os.h from main imp
2021-09-02 23:47 ` [PATCH v3 18/43] bsd-user: save the path to the qemu emulator imp
2021-09-05 19:04   ` Kyle Evans
2021-09-02 23:47 ` [PATCH v3 19/43] bsd-user: start to move target CPU functions to target_arch* imp
2021-09-02 23:47 ` [PATCH v3 20/43] bsd-user: Move per-cpu code into target_arch_cpu.h imp
2021-09-05 10:13   ` Richard Henderson
2021-09-02 23:47 ` [PATCH v3 21/43] bsd-user: pull in target_arch_thread.h update target_arch_elf.h imp
2021-09-05 19:03   ` Kyle Evans
2021-09-02 23:47 ` [PATCH v3 22/43] bsd-user: Include more things in qemu.h imp
2021-09-05 10:14   ` Richard Henderson
2021-09-02 23:47 ` [PATCH v3 23/43] bsd-user: define max args in terms of pages imp
2021-09-02 23:47 ` [PATCH v3 24/43] bsd-user: Create target specific vmparam.h imp
2021-09-02 23:47 ` [PATCH v3 25/43] bsd-user: Add system independent stack, data and text limiting imp
2021-09-02 23:47 ` [PATCH v3 26/43] bsd-user: *BSD specific siginfo defintions imp
2021-09-05 19:01   ` Kyle Evans
2021-09-02 23:47 ` [PATCH v3 27/43] bsd-user: Implement --seed and initialize random state imp
2021-09-05 10:32   ` Richard Henderson
2021-09-05 14:34     ` Warner Losh
2021-09-02 23:47 ` [PATCH v3 28/43] bsd-user: Move stack initializtion into a per-os file imp
2021-09-02 23:47 ` [PATCH v3 29/43] bsd-user: Add architecture specific signal tramp code imp
2021-09-02 23:47 ` [PATCH v3 30/43] bsd-user: elf cleanup imp
2021-09-05 19:00   ` Kyle Evans
2021-09-02 23:47 ` [PATCH v3 31/43] bsd-user: Remove dead #ifdefs from elfload.c imp
2021-09-02 23:47 ` [PATCH v3 32/43] bsd-user: Rewrite target system call definintion glue imp
2021-09-05 10:33   ` Richard Henderson
2021-09-05 14:38     ` Warner Losh
2021-09-05 18:58   ` Kyle Evans
2021-09-02 23:47 ` [PATCH v3 33/43] bsd-user: Make cpu_model and cpu_type visible to all of main.c imp
2021-09-05 18:57   ` Kyle Evans
2021-09-05 22:44     ` Warner Losh
2021-09-02 23:47 ` [PATCH v3 34/43] bsd-user: update debugging in mmap.c imp
2021-09-05 18:53   ` Kyle Evans
2021-09-02 23:47 ` [PATCH v3 35/43] bsd-user: Add target_arch_reg to describe a target's register set imp
2021-09-02 23:47 ` [PATCH v3 36/43] bsd-user: Add target_os_user.h to capture the user/kernel structures imp
2021-09-05 18:52   ` Kyle Evans
2021-09-02 23:47 ` [PATCH v3 37/43] bsd-user: add stubbed out core dump support imp
2021-09-05 10:34   ` Richard Henderson
2021-09-02 23:47 ` imp [this message]
2021-09-02 23:47 ` [PATCH v3 39/43] bsd-user: Refactor load_elf_sections and is_target_elf_binary imp
2021-09-05 18:50   ` Kyle Evans
2021-09-02 23:47 ` [PATCH v3 40/43] bsd-user: move qemu_log to later in the file imp
2021-09-05 18:42   ` Kyle Evans
2021-09-02 23:47 ` [PATCH v3 41/43] bsd-user: Implement interlock for atomic operations imp
2021-09-02 23:47 ` [PATCH v3 42/43] bsd-user: Add '-0 argv0' option to bsd-user/main.c imp
2021-09-02 23:47 ` [PATCH v3 43/43] bsd-user: Update mapping to handle reserved and starting conditions imp
2021-09-05 18:39   ` Kyle Evans

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=20210902234729.76141-39-imp@bsdimp.com \
    --to=imp@bsdimp.com \
    --cc=imp@FreeBSD.org \
    --cc=kevans@freebsd.org \
    --cc=qemu-devel@nongnu.org \
    --cc=richard.henderson@linaro.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).