public inbox for frysk-cvs@sourceware.org
help / color / mirror / Atom feed
From: mark@sourceware.org
To: frysk-cvs@sourceware.org
Subject: [SCM]  master: Add debug_frame parsing.
Date: Thu, 17 Jan 2008 11:11:00 -0000	[thread overview]
Message-ID: <20080117111121.22937.qmail@sourceware.org> (raw)

The branch, master has been updated
       via  00b9fa35668c84c9899076d86c7e3a2ff7c6347e (commit)
      from  882c8ebdcc825139e58e50982810a0f00f1a229b (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email.

- Log -----------------------------------------------------------------
commit 00b9fa35668c84c9899076d86c7e3a2ff7c6347e
Author: Mark Wielaard <mwielaard@redhat.com>
Date:   Thu Jan 17 12:02:50 2008 +0100

    Add debug_frame parsing.
    
    frysk-imports/libunwind/ChangeLog
    2008-01-17  Mark Wielaard  <mwielaard@redhat.com>
    
        * include/dwarf.h (dwarf_extract_proc_info_from_fde): Pass
        table_start.
        * src/dwarf/Gfde.c (is_cie_id): Removed.
        (parse_cie): Accept debug and eh cie ids.
        (dwarf_extract_proc_info_from_fde): Accept table_start. Calculate
        correct cie_addr. Fix error reporting.
        * src/dwarf/Gfind_proc_info-lsb.c (linear_search): Don't depend
        on local address space. Pass table start for fde parsing.
        (dwarf_search_unwind_table): Handle debug_frame by linear search.
        * src/mi/Gget_unwind_table.c (get_frame_table, get_debug_table):
        new functions.
        (unw_get_unwind_table): Call either get_frame_table or
        get_debug_table depending on format.
    
    frysk-sys/lib/unwind/ChangeLog
    2008-01-17  Mark Wielaard  <mwielaard@redhat.com>
    
        * cni/UnwindH.hxx (get_eh_frame_hdr_addr): Find and return
        debug_frame address and set pi->format.
        (createProcInfoFromElfImage): Handle either debug_frame or
        eh_frame addresses.

-----------------------------------------------------------------------

Summary of changes:
 frysk-imports/libunwind/ChangeLog                  |   16 +++++
 frysk-imports/libunwind/include/dwarf.h            |    1 +
 frysk-imports/libunwind/src/dwarf/Gfde.c           |   47 ++++++++-----
 .../libunwind/src/dwarf/Gfind_proc_info-lsb.c      |   25 ++++++-
 frysk-imports/libunwind/src/mi/Gget_unwind_table.c |   58 +++++++++++++++--
 frysk-sys/lib/unwind/ChangeLog                     |    7 ++
 frysk-sys/lib/unwind/cni/UnwindH.hxx               |   69 ++++++++++++++++---
 7 files changed, 184 insertions(+), 39 deletions(-)

First 500 lines of diff:
diff --git a/frysk-imports/libunwind/ChangeLog b/frysk-imports/libunwind/ChangeLog
index 184c9e5..44d3d68 100644
--- a/frysk-imports/libunwind/ChangeLog
+++ b/frysk-imports/libunwind/ChangeLog
@@ -1,3 +1,19 @@
+2008-01-17  Mark Wielaard  <mwielaard@redhat.com>
+
+	* include/dwarf.h (dwarf_extract_proc_info_from_fde): Pass
+	table_start.
+	* src/dwarf/Gfde.c (is_cie_id): Removed.
+	(parse_cie): Accept debug and eh cie ids.
+	(dwarf_extract_proc_info_from_fde): Accept table_start. Calculate
+	correct cie_addr. Fix error reporting.
+	* src/dwarf/Gfind_proc_info-lsb.c (linear_search): Don't depend
+	on local address space. Pass table start for fde parsing.
+	(dwarf_search_unwind_table): Handle debug_frame by linear search.
+	* src/mi/Gget_unwind_table.c (get_frame_table, get_debug_table):
+	new functions.
+	(unw_get_unwind_table): Call either get_frame_table or
+	get_debug_table depending on format.
+	
 2007-12-22  Mark Wielaard  <mwielaard@redhat.com>
 
 	* include/libunwind-common.h.in (unw_get_unwind_table):
diff --git a/frysk-imports/libunwind/include/dwarf.h b/frysk-imports/libunwind/include/dwarf.h
index 47896f6..cf8a74a 100644
--- a/frysk-imports/libunwind/include/dwarf.h
+++ b/frysk-imports/libunwind/include/dwarf.h
@@ -362,6 +362,7 @@ extern int dwarf_eval_expr (struct dwarf_cursor *c, unw_word_t *addr,
 			    int *is_register);
 extern int dwarf_extract_proc_info_from_fde (unw_addr_space_t as,
 					     unw_accessors_t *a,
+					     unw_word_t table_start,
 					     unw_word_t *fde_addr,
 					     unw_proc_info_t *pi,
 					     int need_unwind_info,
diff --git a/frysk-imports/libunwind/src/dwarf/Gfde.c b/frysk-imports/libunwind/src/dwarf/Gfde.c
index 11a6433..de2b193 100644
--- a/frysk-imports/libunwind/src/dwarf/Gfde.c
+++ b/frysk-imports/libunwind/src/dwarf/Gfde.c
@@ -1,6 +1,8 @@
 /* libunwind - a platform-independent unwind library
    Copyright (c) 2003-2005 Hewlett-Packard Development Company, L.P.
 	Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
+   Copyright (c) 2008 Red Hat, Inc.
+	Contributed by Mark Wielaard <mwielaard@redhat.com>
 
 This file is part of libunwind.
 
@@ -25,15 +27,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.  */
 
 #include "dwarf_i.h"
 
-static inline int
-is_cie_id (unw_word_t val)
-{
-  /* DWARF spec says CIE_id is 0xffffffff (for 32-bit ELF) or
-     0xffffffffffffffff (for 64-bit ELF).  However, the GNU toolchain
-     uses 0.  */
-  return (val == 0 || val == - (unw_word_t) 1);
-}
-
 /* Note: we don't need to keep track of more than the first four
    characters of the augmentation string, because we (a) ignore any
    augmentation string contents once we find an unrecognized character
@@ -80,7 +73,7 @@ parse_cie (unw_addr_space_t as, unw_accessors_t *a, unw_word_t addr,
       if ((ret = dwarf_readu32 (as, a, &addr, &cie_id, arg)) < 0)
 	return ret;
       /* DWARF says CIE id should be 0xffffffff, but in .eh_frame, it's 0 */
-      if (cie_id != 0)
+      if (cie_id != 0 && cie_id != 0xffffffff)
 	{
 	  Debug (1, "Unexpected CIE id %x\n", cie_id);
 	  return -UNW_EINVAL;
@@ -99,7 +92,7 @@ parse_cie (unw_addr_space_t as, unw_accessors_t *a, unw_word_t addr,
 	return ret;
       /* DWARF says CIE id should be 0xffffffffffffffff, but in
 	 .eh_frame, it's 0 */
-      if (cie_id != 0)
+      if (cie_id != 0 && cie_id != 0xffffffffffffffff)
 	{
 	  Debug (1, "Unexpected CIE id %llx\n", (long long) cie_id);
 	  return -UNW_EINVAL;
@@ -217,7 +210,8 @@ parse_cie (unw_addr_space_t as, unw_accessors_t *a, unw_word_t addr,
 
 HIDDEN int
 dwarf_extract_proc_info_from_fde (unw_addr_space_t as, unw_accessors_t *a,
-				  unw_word_t *addrp, unw_proc_info_t *pi,
+				  unw_word_t table_start, unw_word_t *addrp,
+				  unw_proc_info_t *pi,
 				  int need_unwind_info,
 				  void *arg)
 {
@@ -252,7 +246,12 @@ dwarf_extract_proc_info_from_fde (unw_addr_space_t as, unw_accessors_t *a,
       if ((ret = dwarf_reads32 (as, a, &addr, &cie_offset, arg)) < 0)
 	return ret;
 
-      if (is_cie_id (cie_offset))
+      /* DWARF spec says CIE_id is 0xffffffff (for 32-bit ELF) or
+	 0xffffffffffffffff (for 64-bit ELF).  However, the GNU toolchain
+	 uses 0.  */
+      if ((pi->format != UNW_INFO_FORMAT_TABLE && cie_offset == 0)
+	  || (pi->format == UNW_INFO_FORMAT_TABLE
+	      && cie_offset == 0xffffffff))
 	/* ignore CIEs (happens during linear searches) */
 	return 0;
 
@@ -260,7 +259,10 @@ dwarf_extract_proc_info_from_fde (unw_addr_space_t as, unw_accessors_t *a,
 	 .debug_frame-relative offset, but the GCC-generated .eh_frame
 	 sections instead store a "pcrelative" offset, which is just
 	 as fine as it's self-contained.  */
-      cie_addr = cie_offset_addr - cie_offset;
+      if (pi->format == UNW_INFO_FORMAT_TABLE)
+	cie_addr = table_start + cie_offset;
+      else
+	cie_addr = cie_offset_addr - cie_offset;
     }
   else
     {
@@ -277,7 +279,12 @@ dwarf_extract_proc_info_from_fde (unw_addr_space_t as, unw_accessors_t *a,
       if ((ret = dwarf_reads64 (as, a, &addr, &cie_offset, arg)) < 0)
 	return ret;
 
-      if (is_cie_id (cie_offset))
+      /* DWARF spec says CIE_id is 0xffffffff (for 32-bit ELF) or
+	 0xffffffffffffffff (for 64-bit ELF).  However, the GNU toolchain
+	 uses 0.  */
+      if ((pi->format != UNW_INFO_FORMAT_TABLE && cie_offset == 0)
+          || (pi->format == UNW_INFO_FORMAT_TABLE
+              && cie_offset == 0xffffffffffffffff))
 	/* ignore CIEs (happens during linear searches) */
 	return 0;
 
@@ -285,7 +292,10 @@ dwarf_extract_proc_info_from_fde (unw_addr_space_t as, unw_accessors_t *a,
 	 .debug_frame-relative offset, but the GCC-generated .eh_frame
 	 sections instead store a "pcrelative" offset, which is just
 	 as fine as it's self-contained.  */
-      cie_addr = (unw_word_t) ((uint64_t) cie_offset_addr - cie_offset);
+      if (pi->format == UNW_INFO_FORMAT_TABLE)
+	cie_addr = (unw_word_t) ((uint64_t) table_start + cie_offset);
+      else
+	cie_addr = (unw_word_t) ((uint64_t) cie_offset_addr - cie_offset);
     }
 
   if ((ret = parse_cie (as, a, cie_addr, pi, &dci, arg)) < 0)
@@ -320,11 +330,12 @@ dwarf_extract_proc_info_from_fde (unw_addr_space_t as, unw_accessors_t *a,
 
   if (need_unwind_info)
     {
-      pi->format = UNW_INFO_FORMAT_TABLE;
+      // FRYSK LOCAL - we already set this.
+      // pi->format = UNW_INFO_FORMAT_TABLE;
       pi->unwind_info_size = sizeof (dci);
       pi->unwind_info = mempool_alloc (&dwarf_cie_info_pool);
       if (!pi->unwind_info)
-	return UNW_ENOMEM;
+	return -UNW_ENOMEM;
 
       if (dci.have_abi_marker)
 	{
diff --git a/frysk-imports/libunwind/src/dwarf/Gfind_proc_info-lsb.c b/frysk-imports/libunwind/src/dwarf/Gfind_proc_info-lsb.c
index a8a3b69..be22e3e 100644
--- a/frysk-imports/libunwind/src/dwarf/Gfind_proc_info-lsb.c
+++ b/frysk-imports/libunwind/src/dwarf/Gfind_proc_info-lsb.c
@@ -1,6 +1,8 @@
 /* libunwind - a platform-independent unwind library
    Copyright (c) 2003-2005 Hewlett-Packard Development Company, L.P.
 	Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
+   Copyright (c) 2008, Red Hat, Inc.
+	Contributed by Mark Wielaard <mwielaard@redhat.com>
 
 This file is part of libunwind.
 
@@ -52,20 +54,23 @@ struct callback_data
     unw_dyn_info_t di;		/* table info (if single_fde is false) */
   };
 
+#endif /* !UNW_REMOTE_ONLY */
+
 static int
 linear_search (unw_addr_space_t as, unw_word_t ip,
 	       unw_word_t eh_frame_start, unw_word_t eh_frame_end,
 	       unw_word_t fde_count,
 	       unw_proc_info_t *pi, int need_unwind_info, void *arg)
 {
-  unw_accessors_t *a = unw_get_accessors (unw_local_addr_space);
+  unw_accessors_t *a = unw_get_accessors (as);
   unw_word_t i = 0, fde_addr, addr = eh_frame_start;
   int ret;
 
   while (i++ < fde_count && addr < eh_frame_end)
     {
       fde_addr = addr;
-      if ((ret = dwarf_extract_proc_info_from_fde (as, a, &addr, pi, 0, arg))
+      if ((ret = dwarf_extract_proc_info_from_fde (as, a, eh_frame_start,
+						   &addr, pi, 0, arg))
 	  < 0)
 	return ret;
 
@@ -74,7 +79,8 @@ linear_search (unw_addr_space_t as, unw_word_t ip,
 	  if (!need_unwind_info)
 	    return 1;
 	  addr = fde_addr;
-	  if ((ret = dwarf_extract_proc_info_from_fde (as, a, &addr, pi,
+	  if ((ret = dwarf_extract_proc_info_from_fde (as, a, eh_frame_start,
+						       &addr, pi,
 						       need_unwind_info, arg))
 	      < 0)
 	    return ret;
@@ -84,6 +90,8 @@ linear_search (unw_addr_space_t as, unw_word_t ip,
   return -UNW_ENOINFO;
 }
 
+#ifndef UNW_REMOTE_ONLY
+
 /* Info is a pointer to a unw_dyn_info_t structure and, on entry,
    member u.rti.segbase contains the instruction-pointer we're looking
    for.  */
@@ -361,6 +369,15 @@ dwarf_search_unwind_table (unw_addr_space_t as, unw_word_t ip,
 #endif
   int ret;
 
+  if (di->format == UNW_INFO_FORMAT_TABLE)
+    {
+      ret = linear_search (as, ip, di->u.rti.table_data,
+			   di->u.rti.table_data
+			   + di->u.rti.table_len * sizeof (unw_word_t),
+			   ~0UL, pi, need_unwind_info, arg);
+      return ret;
+    }
+
   assert (di->format == UNW_INFO_FORMAT_REMOTE_TABLE
 	  && (ip >= di->start_ip && ip < di->end_ip));
 
@@ -397,7 +414,7 @@ dwarf_search_unwind_table (unw_addr_space_t as, unw_word_t ip,
   Debug (15, "ip=0x%lx, start_ip=0x%lx\n",
 	 (long) ip, (long) (e->start_ip_offset + segbase));
   fde_addr = e->fde_offset + segbase;
-  if ((ret = dwarf_extract_proc_info_from_fde (as, a, &fde_addr, pi,
+  if ((ret = dwarf_extract_proc_info_from_fde (as, a, segbase, &fde_addr, pi,
 					       need_unwind_info, arg)) < 0)
     return ret;
 
diff --git a/frysk-imports/libunwind/src/mi/Gget_unwind_table.c b/frysk-imports/libunwind/src/mi/Gget_unwind_table.c
index fc46269..0223013 100644
--- a/frysk-imports/libunwind/src/mi/Gget_unwind_table.c
+++ b/frysk-imports/libunwind/src/mi/Gget_unwind_table.c
@@ -1,4 +1,4 @@
-// Copyright 2007, Red Hat Inc.
+// Copyright 2007, 2008, Red Hat Inc.
 
 /* This file is part of libunwind.
 
@@ -25,11 +25,13 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.  */
 #include "dwarf_i.h"
 #include "dwarf-eh.h"
 
-int
-unw_get_unwind_table(unw_word_t ip, unw_proc_info_t *pi, int need_unwind_info,
-		     unw_accessors_t *eh_frame_accessors,
-		     unw_word_t eh_frame_hdr_address,
-		     void *eh_frame_arg)
+#include <stdio.h>
+
+static int
+get_frame_table(unw_word_t ip, unw_proc_info_t *pi, int need_unwind_info,
+		unw_accessors_t *eh_frame_accessors,
+		unw_word_t eh_frame_hdr_address,
+		void *eh_frame_arg)
 {
   int ret;
   unw_addr_space_t as = unw_create_addr_space (eh_frame_accessors, 0);
@@ -87,7 +89,51 @@ unw_get_unwind_table(unw_word_t ip, unw_proc_info_t *pi, int need_unwind_info,
   di.u.rti.table_data = eh_frame_hdr_address + 12;
   di.u.rti.segbase = eh_frame_hdr_address;
 
+  pi->start_ip = 0;
+  pi->end_ip = 0;
   ret = tdep_search_unwind_table (as, ip, &di, pi, need_unwind_info,
 				  eh_frame_arg);
   return ret;
 }
+
+static int
+get_debug_table(unw_word_t ip, unw_proc_info_t *pi, int need_unwind_info,
+                unw_accessors_t *accessors,
+                unw_word_t address,
+                void *arg)
+{
+  unw_addr_space_t as = unw_create_addr_space (accessors, 0);
+
+  unw_dyn_info_t di;
+  di.start_ip = pi->start_ip;
+  di.end_ip = pi->end_ip;
+  di.format = UNW_INFO_FORMAT_TABLE;
+  di.gp = pi->gp;
+
+  // XXX Should we use the ti struct of the union?
+  di.u.rti.name_ptr = 0;
+  di.u.rti.segbase = address;
+  di.u.rti.table_data = address;
+  di.u.rti.table_len = pi->unwind_info_size;
+  
+  pi->start_ip = 0;
+  pi->end_ip = 0;
+  return tdep_search_unwind_table (as, ip, &di, pi, need_unwind_info, arg);
+}
+
+int
+unw_get_unwind_table(unw_word_t ip, unw_proc_info_t *pi, int need_unwind_info,
+		     unw_accessors_t *accessors,
+		     unw_word_t address,
+		     void *arg)
+{
+  if (pi->format == UNW_INFO_FORMAT_TABLE)
+    return get_debug_table(ip, pi, need_unwind_info, accessors,
+			   address, arg);
+
+  if (pi->format == UNW_INFO_FORMAT_REMOTE_TABLE)
+    return get_frame_table(ip, pi, need_unwind_info, accessors,
+			   address, arg);
+
+  return -UNW_EINVAL;
+}
diff --git a/frysk-sys/lib/unwind/ChangeLog b/frysk-sys/lib/unwind/ChangeLog
index 28fa70b..4677847 100644
--- a/frysk-sys/lib/unwind/ChangeLog
+++ b/frysk-sys/lib/unwind/ChangeLog
@@ -1,3 +1,10 @@
+2008-01-17  Mark Wielaard  <mwielaard@redhat.com>
+
+	* cni/UnwindH.hxx (get_eh_frame_hdr_addr): Find and return
+	debug_frame address and set pi->format.
+	(createProcInfoFromElfImage): Handle either debug_frame or
+	eh_frame addresses.
+	
 2007-12-22  Mark Wielaard  <mwielaard@redhat.com>
 
 	* cni/UnwindH.hxx (get_eh_frame_hdr_addr): Return char*.
diff --git a/frysk-sys/lib/unwind/cni/UnwindH.hxx b/frysk-sys/lib/unwind/cni/UnwindH.hxx
index e69e031..08c8ce1 100644
--- a/frysk-sys/lib/unwind/cni/UnwindH.hxx
+++ b/frysk-sys/lib/unwind/cni/UnwindH.hxx
@@ -1,6 +1,6 @@
 // This file is part of the program FRYSK.
 //
-// Copyright 2007, Red Hat Inc.
+// Copyright 2007, 2008, Red Hat Inc.
 //
 // FRYSK is free software; you can redistribute it and/or modify it
 // under the terms of the GNU General Public License as published by
@@ -488,7 +488,26 @@ get_eh_frame_hdr_addr(unw_proc_info_t *pi, char *image, size_t size,
         }
     }
 
-  if (ptxt_ndx == -1 || peh_hdr_ndx == -1)
+  Elf_Data *debug_frame_data = NULL;
+  size_t shstrndx;
+  if (elf_getshstrndx (elf, &shstrndx) >= 0)
+    {
+      Elf_Scn *scn = NULL;
+      while ((scn = elf_nextscn (elf, scn)) != NULL
+	     && debug_frame_data == NULL)
+	{
+	  GElf_Shdr shdr;
+	  if (gelf_getshdr (scn, &shdr) != NULL
+	      && shdr.sh_type == SHT_PROGBITS)
+	    {
+	      const char *name = elf_strptr (elf, shstrndx, shdr.sh_name);
+	      if (strcmp (name, ".debug_frame") == 0)
+		debug_frame_data = elf_getdata (scn, NULL);
+	    }
+	}
+    }
+
+  if (ptxt_ndx == -1 || (peh_hdr_ndx == -1 && debug_frame_data == NULL))
     return NULL;
 
   GElf_Phdr ptxt, peh_hdr;
@@ -547,7 +566,23 @@ get_eh_frame_hdr_addr(unw_proc_info_t *pi, char *image, size_t size,
 
   *peh_vaddr = peh_hdr.p_vaddr;
 
-  char *hdr = image + peh_hdr.p_offset;
+  char *hdr;
+  // FIXME. Currently we prefer eh_frame, but we should switch to
+  // prefer debug_frame when all bugs have been squashed out of that
+  // in libunwind.
+  if (peh_hdr_ndx == -1
+      && debug_frame_data != NULL && debug_frame_data->d_buf != NULL
+      && debug_frame_data->d_size != 0)
+    {
+      pi->format = UNW_INFO_FORMAT_TABLE;
+      pi->unwind_info_size = debug_frame_data->d_size / sizeof (unw_word_t);
+      hdr = (char *) debug_frame_data->d_buf;
+    }
+  else
+    {
+      pi->format = UNW_INFO_FORMAT_REMOTE_TABLE;
+      hdr = image + peh_hdr.p_offset;
+    }
   return hdr;
 }
 
@@ -600,14 +635,26 @@ lib::unwind::TARGET::createProcInfoFromElfImage(lib::unwind::AddressSpace* addre
   if (eh_table_hdr == NULL)
     return new lib::unwind::ProcInfo(-UNW_ENOINFO);
 
-  int ret = unw_get_unwind_table((unw_word_t) ip,
-				 procInfo,
-				 (int) needUnwindInfo,
-				 &local_accessors,
-				 // virtual address
-				 peh_vaddr,
-				 // address adjustment
-				 eh_table_hdr - peh_vaddr);
+  int ret;
+  if (procInfo->format == UNW_INFO_FORMAT_REMOTE_TABLE)
+    ret = unw_get_unwind_table((unw_word_t) ip,
+			       procInfo,
+			       (int) needUnwindInfo,
+			       &local_accessors,
+			       // virtual address
+			       peh_vaddr,
+			       // address adjustment
+			       eh_table_hdr - peh_vaddr);
+  else
+    ret = unw_get_unwind_table((unw_word_t) ip,
+                               procInfo,
+                               (int) needUnwindInfo,
+                               &local_accessors,
+                               // virtual address
+                               0,
+                               // address adjustment
+                               eh_table_hdr);
+  
   
   logFine(this, logger, "Post unw_get_unwind_table");
   lib::unwind::ProcInfo *myInfo;


hooks/post-receive
--
frysk system monitor/debugger


                 reply	other threads:[~2008-01-17 11:11 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

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=20080117111121.22937.qmail@sourceware.org \
    --to=mark@sourceware.org \
    --cc=frysk-cvs@sourceware.org \
    --cc=frysk@sourceware.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 read-only IMAP folder(s) and NNTP newsgroup(s).