* [PATCH kvm-unit-tests] libcflat: provide long division routines @ 2021-05-05 13:14 Paolo Bonzini 2021-05-05 13:16 ` Paolo Bonzini 0 siblings, 1 reply; 3+ messages in thread From: Paolo Bonzini @ 2021-05-05 13:14 UTC (permalink / raw) To: kvm; +Cc: Bill Wendling The -nostdlib flag disables the driver from adding libclang_rt.*.a during linking. Adding a specific library to the command line such as libgcc then causes the linker to report unresolved symbols, because the libraries that resolve those symbols aren't automatically added. libgcc however is only needed for long division (64-bit by 64-bit). Instead of linking the whole of it, implement the routines that are needed. Reported-by: Bill Wendling <morbo@google.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> --- arm/Makefile.arm | 1 + lib/ldiv32.c | 105 ++++++++++++++++++++++++++++++++++++++++++++++ x86/Makefile.i386 | 2 +- 3 files changed, 107 insertions(+), 1 deletion(-) create mode 100644 lib/ldiv32.c diff --git a/arm/Makefile.arm b/arm/Makefile.arm index d379a28..687a8ed 100644 --- a/arm/Makefile.arm +++ b/arm/Makefile.arm @@ -23,6 +23,7 @@ cstart.o = $(TEST_DIR)/cstart.o cflatobjs += lib/arm/spinlock.o cflatobjs += lib/arm/processor.o cflatobjs += lib/arm/stack.o +cflatobjs += lib/ldiv32.o # arm specific tests tests = diff --git a/lib/ldiv32.c b/lib/ldiv32.c new file mode 100644 index 0000000..e9d434f --- /dev/null +++ b/lib/ldiv32.c @@ -0,0 +1,105 @@ +#include <inttypes.h> + +extern uint64_t __udivmoddi4(uint64_t num, uint64_t den, uint64_t *p_rem); +extern int64_t __moddi3(int64_t num, int64_t den); +extern int64_t __divdi3(int64_t num, int64_t den); +extern uint64_t __udivdi3(uint64_t num, uint64_t den); +extern uint64_t __umoddi3(uint64_t num, uint64_t den); + +uint64_t __udivmoddi4(uint64_t num, uint64_t den, uint64_t *p_rem) +{ + uint64_t quot = 0; + + /* Trigger a division by zero at run time (trick taken from iPXE). */ + if (den == 0) + return 1/((unsigned)den); + + if (num >= den) { + /* Align den to num to avoid wasting time on leftmost zero bits. */ + int n = __builtin_clzll(den) - __builtin_clzll(num); + den <<= n; + + do { + quot <<= 1; + if (num >= den) { + num -= den; + quot |= 1; + } + den >>= 1; + } while (n--); + } + + if (p_rem) + *p_rem = num; + + return quot; +} + +int64_t __moddi3(int64_t num, int64_t den) +{ + uint64_t mask = num < 0 ? -1 : 0; + + /* Compute absolute values and do an unsigned division. */ + num = (num + mask) ^ mask; + if (den < 0) + den = -den; + + /* Copy sign of num into result. */ + return (__umoddi3(num, den) + mask) ^ mask; +} + +int64_t __divdi3(int64_t num, int64_t den) +{ + uint64_t mask = (num ^ den) < 0 ? -1 : 0; + + /* Compute absolute values and do an unsigned division. */ + if (num < 0) + num = -num; + if (den < 0) + den = -den; + + /* Copy sign of num^den into result. */ + return (__udivdi3(num, den) + mask) ^ mask; +} + +uint64_t __udivdi3(uint64_t num, uint64_t den) +{ + uint64_t rem; + return __udivmoddi4(num, den, &rem); +} + +uint64_t __umoddi3(uint64_t num, uint64_t den) +{ + uint64_t rem; + __udivmoddi4(num, den, &rem); + return rem; +} + +#ifdef TEST +#include <assert.h> +#define UTEST(a, b, q, r) assert(__udivdi3(a, b) == q && __umoddi3(a, b) == r) +#define STEST(a, b, q, r) assert(__divdi3(a, b) == q && __moddi3(a, b) == r) +int main() +{ + UTEST(1, 1, 1, 0); + UTEST(2, 2, 1, 0); + UTEST(5, 3, 1, 2); + UTEST(10, 3, 3, 1); + UTEST(120, 3, 40, 0); + UTEST(120, 1, 120, 0); + UTEST(0x7FFFFFFFFFFFFFFFULL, 17, 0x787878787878787, 8); + UTEST(0x7FFFFFFFFFFFFFFFULL, 0x787878787878787, 17, 8); + UTEST(0x8000000000000001ULL, 17, 0x787878787878787, 10); + UTEST(0x8000000000000001ULL, 0x787878787878787, 17, 10); + UTEST(0, 5, 0, 0); + + STEST(0x7FFFFFFFFFFFFFFFULL, 17, 0x787878787878787, 8); + STEST(0x7FFFFFFFFFFFFFFFULL, -17, -0x787878787878787, 8); + STEST(-0x7FFFFFFFFFFFFFFFULL, 17, -0x787878787878787, -8); + STEST(-0x7FFFFFFFFFFFFFFFULL, -17, 0x787878787878787, -8); + STEST(33, 5, 6, 3); + STEST(33, -5, -6, 3); + STEST(-33, 5, -6, -3); + STEST(-33, -5, 6, -3); +} +#endif diff --git a/x86/Makefile.i386 b/x86/Makefile.i386 index c04e5aa..960e274 100644 --- a/x86/Makefile.i386 +++ b/x86/Makefile.i386 @@ -3,7 +3,7 @@ bits = 32 ldarch = elf32-i386 COMMON_CFLAGS += -mno-sse -mno-sse2 -cflatobjs += lib/x86/setjmp32.o +cflatobjs += lib/x86/setjmp32.o lib/ldiv32.o tests = $(TEST_DIR)/taskswitch.flat $(TEST_DIR)/taskswitch2.flat \ $(TEST_DIR)/cmpxchg8b.flat $(TEST_DIR)/la57.flat -- 2.26.2 ^ permalink raw reply related [flat|nested] 3+ messages in thread
* Re: [PATCH kvm-unit-tests] libcflat: provide long division routines 2021-05-05 13:14 [PATCH kvm-unit-tests] libcflat: provide long division routines Paolo Bonzini @ 2021-05-05 13:16 ` Paolo Bonzini 2021-05-05 19:46 ` Bill Wendling 0 siblings, 1 reply; 3+ messages in thread From: Paolo Bonzini @ 2021-05-05 13:16 UTC (permalink / raw) To: kvm; +Cc: Bill Wendling On 05/05/21 15:14, Paolo Bonzini wrote: > The -nostdlib flag disables the driver from adding libclang_rt.*.a > during linking. Adding a specific library to the command line such as > libgcc then causes the linker to report unresolved symbols, because the > libraries that resolve those symbols aren't automatically added. > > libgcc however is only needed for long division (64-bit by 64-bit). > Instead of linking the whole of it, implement the routines that are > needed. > > Reported-by: Bill Wendling <morbo@google.com> > Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> Oops, I didn't actually remove libgcc! diff --git a/Makefile b/Makefile index 24b7917..ddebcae 100644 --- a/Makefile +++ b/Makefile @@ -25,8 +25,6 @@ cc-option = $(shell if $(CC) -Werror $(1) -S -o /dev/null -xc /dev/null \ #make sure env CFLAGS variable is not used CFLAGS = -libgcc := $(shell $(CC) --print-libgcc-file-name) - libcflat := lib/libcflat.a cflatobjs := \ lib/argv.o \ diff --git a/arm/Makefile.common b/arm/Makefile.common index 55478ec..38385e0 100644 --- a/arm/Makefile.common +++ b/arm/Makefile.common @@ -58,9 +58,7 @@ OBJDIRS += lib/arm libeabi = lib/arm/libeabi.a eabiobjs = lib/arm/eabi_compat.o -libgcc := $(shell $(CC) $(machine) --print-libgcc-file-name) - -FLATLIBS = $(libcflat) $(LIBFDT_archive) $(libgcc) $(libeabi) +FLATLIBS = $(libcflat) $(LIBFDT_archive) $(libeabi) %.elf: LDFLAGS = -nostdlib $(arch_LDFLAGS) %.elf: %.o $(FLATLIBS) $(SRCDIR)/arm/flat.lds $(cstart.o) $(CC) $(CFLAGS) -c -o $(@:.elf=.aux.o) $(SRCDIR)/lib/auxinfo.c \ diff --git a/x86/Makefile.common b/x86/Makefile.common index 55f7f28..52bb7aa 100644 --- a/x86/Makefile.common +++ b/x86/Makefile.common @@ -37,12 +37,10 @@ COMMON_CFLAGS += -O1 # stack.o relies on frame pointers. KEEP_FRAME_POINTER := y -libgcc := $(shell $(CC) -m$(bits) --print-libgcc-file-name) - # We want to keep intermediate file: %.elf and %.o .PRECIOUS: %.elf %.o -FLATLIBS = lib/libcflat.a $(libgcc) +FLATLIBS = lib/libcflat.a %.elf: %.o $(FLATLIBS) $(SRCDIR)/x86/flat.lds $(cstart.o) $(CC) $(CFLAGS) -nostdlib -o $@ -Wl,-T,$(SRCDIR)/x86/flat.lds \ $(filter %.o, $^) $(FLATLIBS) > --- > arm/Makefile.arm | 1 + > lib/ldiv32.c | 105 ++++++++++++++++++++++++++++++++++++++++++++++ > x86/Makefile.i386 | 2 +- > 3 files changed, 107 insertions(+), 1 deletion(-) > create mode 100644 lib/ldiv32.c > > diff --git a/arm/Makefile.arm b/arm/Makefile.arm > index d379a28..687a8ed 100644 > --- a/arm/Makefile.arm > +++ b/arm/Makefile.arm > @@ -23,6 +23,7 @@ cstart.o = $(TEST_DIR)/cstart.o > cflatobjs += lib/arm/spinlock.o > cflatobjs += lib/arm/processor.o > cflatobjs += lib/arm/stack.o > +cflatobjs += lib/ldiv32.o > > # arm specific tests > tests = > diff --git a/lib/ldiv32.c b/lib/ldiv32.c > new file mode 100644 > index 0000000..e9d434f > --- /dev/null > +++ b/lib/ldiv32.c > @@ -0,0 +1,105 @@ > +#include <inttypes.h> > + > +extern uint64_t __udivmoddi4(uint64_t num, uint64_t den, uint64_t *p_rem); > +extern int64_t __moddi3(int64_t num, int64_t den); > +extern int64_t __divdi3(int64_t num, int64_t den); > +extern uint64_t __udivdi3(uint64_t num, uint64_t den); > +extern uint64_t __umoddi3(uint64_t num, uint64_t den); > + > +uint64_t __udivmoddi4(uint64_t num, uint64_t den, uint64_t *p_rem) > +{ > + uint64_t quot = 0; > + > + /* Trigger a division by zero at run time (trick taken from iPXE). */ > + if (den == 0) > + return 1/((unsigned)den); > + > + if (num >= den) { > + /* Align den to num to avoid wasting time on leftmost zero bits. */ > + int n = __builtin_clzll(den) - __builtin_clzll(num); > + den <<= n; > + > + do { > + quot <<= 1; > + if (num >= den) { > + num -= den; > + quot |= 1; > + } > + den >>= 1; > + } while (n--); > + } > + > + if (p_rem) > + *p_rem = num; > + > + return quot; > +} > + > +int64_t __moddi3(int64_t num, int64_t den) > +{ > + uint64_t mask = num < 0 ? -1 : 0; > + > + /* Compute absolute values and do an unsigned division. */ > + num = (num + mask) ^ mask; > + if (den < 0) > + den = -den; > + > + /* Copy sign of num into result. */ > + return (__umoddi3(num, den) + mask) ^ mask; > +} > + > +int64_t __divdi3(int64_t num, int64_t den) > +{ > + uint64_t mask = (num ^ den) < 0 ? -1 : 0; > + > + /* Compute absolute values and do an unsigned division. */ > + if (num < 0) > + num = -num; > + if (den < 0) > + den = -den; > + > + /* Copy sign of num^den into result. */ > + return (__udivdi3(num, den) + mask) ^ mask; > +} > + > +uint64_t __udivdi3(uint64_t num, uint64_t den) > +{ > + uint64_t rem; > + return __udivmoddi4(num, den, &rem); > +} > + > +uint64_t __umoddi3(uint64_t num, uint64_t den) > +{ > + uint64_t rem; > + __udivmoddi4(num, den, &rem); > + return rem; > +} > + > +#ifdef TEST > +#include <assert.h> > +#define UTEST(a, b, q, r) assert(__udivdi3(a, b) == q && __umoddi3(a, b) == r) > +#define STEST(a, b, q, r) assert(__divdi3(a, b) == q && __moddi3(a, b) == r) > +int main() > +{ > + UTEST(1, 1, 1, 0); > + UTEST(2, 2, 1, 0); > + UTEST(5, 3, 1, 2); > + UTEST(10, 3, 3, 1); > + UTEST(120, 3, 40, 0); > + UTEST(120, 1, 120, 0); > + UTEST(0x7FFFFFFFFFFFFFFFULL, 17, 0x787878787878787, 8); > + UTEST(0x7FFFFFFFFFFFFFFFULL, 0x787878787878787, 17, 8); > + UTEST(0x8000000000000001ULL, 17, 0x787878787878787, 10); > + UTEST(0x8000000000000001ULL, 0x787878787878787, 17, 10); > + UTEST(0, 5, 0, 0); > + > + STEST(0x7FFFFFFFFFFFFFFFULL, 17, 0x787878787878787, 8); > + STEST(0x7FFFFFFFFFFFFFFFULL, -17, -0x787878787878787, 8); > + STEST(-0x7FFFFFFFFFFFFFFFULL, 17, -0x787878787878787, -8); > + STEST(-0x7FFFFFFFFFFFFFFFULL, -17, 0x787878787878787, -8); > + STEST(33, 5, 6, 3); > + STEST(33, -5, -6, 3); > + STEST(-33, 5, -6, -3); > + STEST(-33, -5, 6, -3); > +} > +#endif > diff --git a/x86/Makefile.i386 b/x86/Makefile.i386 > index c04e5aa..960e274 100644 > --- a/x86/Makefile.i386 > +++ b/x86/Makefile.i386 > @@ -3,7 +3,7 @@ bits = 32 > ldarch = elf32-i386 > COMMON_CFLAGS += -mno-sse -mno-sse2 > > -cflatobjs += lib/x86/setjmp32.o > +cflatobjs += lib/x86/setjmp32.o lib/ldiv32.o > > tests = $(TEST_DIR)/taskswitch.flat $(TEST_DIR)/taskswitch2.flat \ > $(TEST_DIR)/cmpxchg8b.flat $(TEST_DIR)/la57.flat > ^ permalink raw reply related [flat|nested] 3+ messages in thread
* Re: [PATCH kvm-unit-tests] libcflat: provide long division routines 2021-05-05 13:16 ` Paolo Bonzini @ 2021-05-05 19:46 ` Bill Wendling 0 siblings, 0 replies; 3+ messages in thread From: Bill Wendling @ 2021-05-05 19:46 UTC (permalink / raw) To: Paolo Bonzini; +Cc: kvm list On Wed, May 5, 2021 at 6:16 AM Paolo Bonzini <pbonzini@redhat.com> wrote: > > On 05/05/21 15:14, Paolo Bonzini wrote: > > The -nostdlib flag disables the driver from adding libclang_rt.*.a > > during linking. Adding a specific library to the command line such as > > libgcc then causes the linker to report unresolved symbols, because the > > libraries that resolve those symbols aren't automatically added. > > > > libgcc however is only needed for long division (64-bit by 64-bit). > > Instead of linking the whole of it, implement the routines that are > > needed. > > > > Reported-by: Bill Wendling <morbo@google.com> > > Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> > Thanks, Paolo! -bw > Oops, I didn't actually remove libgcc! > > diff --git a/Makefile b/Makefile > index 24b7917..ddebcae 100644 > --- a/Makefile > +++ b/Makefile > @@ -25,8 +25,6 @@ cc-option = $(shell if $(CC) -Werror $(1) -S -o /dev/null -xc /dev/null \ > #make sure env CFLAGS variable is not used > CFLAGS = > > -libgcc := $(shell $(CC) --print-libgcc-file-name) > - > libcflat := lib/libcflat.a > cflatobjs := \ > lib/argv.o \ > diff --git a/arm/Makefile.common b/arm/Makefile.common > index 55478ec..38385e0 100644 > --- a/arm/Makefile.common > +++ b/arm/Makefile.common > @@ -58,9 +58,7 @@ OBJDIRS += lib/arm > libeabi = lib/arm/libeabi.a > eabiobjs = lib/arm/eabi_compat.o > > -libgcc := $(shell $(CC) $(machine) --print-libgcc-file-name) > - > -FLATLIBS = $(libcflat) $(LIBFDT_archive) $(libgcc) $(libeabi) > +FLATLIBS = $(libcflat) $(LIBFDT_archive) $(libeabi) > %.elf: LDFLAGS = -nostdlib $(arch_LDFLAGS) > %.elf: %.o $(FLATLIBS) $(SRCDIR)/arm/flat.lds $(cstart.o) > $(CC) $(CFLAGS) -c -o $(@:.elf=.aux.o) $(SRCDIR)/lib/auxinfo.c \ > diff --git a/x86/Makefile.common b/x86/Makefile.common > index 55f7f28..52bb7aa 100644 > --- a/x86/Makefile.common > +++ b/x86/Makefile.common > @@ -37,12 +37,10 @@ COMMON_CFLAGS += -O1 > # stack.o relies on frame pointers. > KEEP_FRAME_POINTER := y > > -libgcc := $(shell $(CC) -m$(bits) --print-libgcc-file-name) > - > # We want to keep intermediate file: %.elf and %.o > .PRECIOUS: %.elf %.o > > -FLATLIBS = lib/libcflat.a $(libgcc) > +FLATLIBS = lib/libcflat.a > %.elf: %.o $(FLATLIBS) $(SRCDIR)/x86/flat.lds $(cstart.o) > $(CC) $(CFLAGS) -nostdlib -o $@ -Wl,-T,$(SRCDIR)/x86/flat.lds \ > $(filter %.o, $^) $(FLATLIBS) > > > > --- > > arm/Makefile.arm | 1 + > > lib/ldiv32.c | 105 ++++++++++++++++++++++++++++++++++++++++++++++ > > x86/Makefile.i386 | 2 +- > > 3 files changed, 107 insertions(+), 1 deletion(-) > > create mode 100644 lib/ldiv32.c > > > > diff --git a/arm/Makefile.arm b/arm/Makefile.arm > > index d379a28..687a8ed 100644 > > --- a/arm/Makefile.arm > > +++ b/arm/Makefile.arm > > @@ -23,6 +23,7 @@ cstart.o = $(TEST_DIR)/cstart.o > > cflatobjs += lib/arm/spinlock.o > > cflatobjs += lib/arm/processor.o > > cflatobjs += lib/arm/stack.o > > +cflatobjs += lib/ldiv32.o > > > > # arm specific tests > > tests = > > diff --git a/lib/ldiv32.c b/lib/ldiv32.c > > new file mode 100644 > > index 0000000..e9d434f > > --- /dev/null > > +++ b/lib/ldiv32.c > > @@ -0,0 +1,105 @@ > > +#include <inttypes.h> > > + > > +extern uint64_t __udivmoddi4(uint64_t num, uint64_t den, uint64_t *p_rem); > > +extern int64_t __moddi3(int64_t num, int64_t den); > > +extern int64_t __divdi3(int64_t num, int64_t den); > > +extern uint64_t __udivdi3(uint64_t num, uint64_t den); > > +extern uint64_t __umoddi3(uint64_t num, uint64_t den); > > + > > +uint64_t __udivmoddi4(uint64_t num, uint64_t den, uint64_t *p_rem) > > +{ > > + uint64_t quot = 0; > > + > > + /* Trigger a division by zero at run time (trick taken from iPXE). */ > > + if (den == 0) > > + return 1/((unsigned)den); > > + > > + if (num >= den) { > > + /* Align den to num to avoid wasting time on leftmost zero bits. */ > > + int n = __builtin_clzll(den) - __builtin_clzll(num); > > + den <<= n; > > + > > + do { > > + quot <<= 1; > > + if (num >= den) { > > + num -= den; > > + quot |= 1; > > + } > > + den >>= 1; > > + } while (n--); > > + } > > + > > + if (p_rem) > > + *p_rem = num; > > + > > + return quot; > > +} > > + > > +int64_t __moddi3(int64_t num, int64_t den) > > +{ > > + uint64_t mask = num < 0 ? -1 : 0; > > + > > + /* Compute absolute values and do an unsigned division. */ > > + num = (num + mask) ^ mask; > > + if (den < 0) > > + den = -den; > > + > > + /* Copy sign of num into result. */ > > + return (__umoddi3(num, den) + mask) ^ mask; > > +} > > + > > +int64_t __divdi3(int64_t num, int64_t den) > > +{ > > + uint64_t mask = (num ^ den) < 0 ? -1 : 0; > > + > > + /* Compute absolute values and do an unsigned division. */ > > + if (num < 0) > > + num = -num; > > + if (den < 0) > > + den = -den; > > + > > + /* Copy sign of num^den into result. */ > > + return (__udivdi3(num, den) + mask) ^ mask; > > +} > > + > > +uint64_t __udivdi3(uint64_t num, uint64_t den) > > +{ > > + uint64_t rem; > > + return __udivmoddi4(num, den, &rem); > > +} > > + > > +uint64_t __umoddi3(uint64_t num, uint64_t den) > > +{ > > + uint64_t rem; > > + __udivmoddi4(num, den, &rem); > > + return rem; > > +} > > + > > +#ifdef TEST > > +#include <assert.h> > > +#define UTEST(a, b, q, r) assert(__udivdi3(a, b) == q && __umoddi3(a, b) == r) > > +#define STEST(a, b, q, r) assert(__divdi3(a, b) == q && __moddi3(a, b) == r) > > +int main() > > +{ > > + UTEST(1, 1, 1, 0); > > + UTEST(2, 2, 1, 0); > > + UTEST(5, 3, 1, 2); > > + UTEST(10, 3, 3, 1); > > + UTEST(120, 3, 40, 0); > > + UTEST(120, 1, 120, 0); > > + UTEST(0x7FFFFFFFFFFFFFFFULL, 17, 0x787878787878787, 8); > > + UTEST(0x7FFFFFFFFFFFFFFFULL, 0x787878787878787, 17, 8); > > + UTEST(0x8000000000000001ULL, 17, 0x787878787878787, 10); > > + UTEST(0x8000000000000001ULL, 0x787878787878787, 17, 10); > > + UTEST(0, 5, 0, 0); > > + > > + STEST(0x7FFFFFFFFFFFFFFFULL, 17, 0x787878787878787, 8); > > + STEST(0x7FFFFFFFFFFFFFFFULL, -17, -0x787878787878787, 8); > > + STEST(-0x7FFFFFFFFFFFFFFFULL, 17, -0x787878787878787, -8); > > + STEST(-0x7FFFFFFFFFFFFFFFULL, -17, 0x787878787878787, -8); > > + STEST(33, 5, 6, 3); > > + STEST(33, -5, -6, 3); > > + STEST(-33, 5, -6, -3); > > + STEST(-33, -5, 6, -3); > > +} > > +#endif > > diff --git a/x86/Makefile.i386 b/x86/Makefile.i386 > > index c04e5aa..960e274 100644 > > --- a/x86/Makefile.i386 > > +++ b/x86/Makefile.i386 > > @@ -3,7 +3,7 @@ bits = 32 > > ldarch = elf32-i386 > > COMMON_CFLAGS += -mno-sse -mno-sse2 > > > > -cflatobjs += lib/x86/setjmp32.o > > +cflatobjs += lib/x86/setjmp32.o lib/ldiv32.o > > > > tests = $(TEST_DIR)/taskswitch.flat $(TEST_DIR)/taskswitch2.flat \ > > $(TEST_DIR)/cmpxchg8b.flat $(TEST_DIR)/la57.flat > > > ^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2021-05-05 19:46 UTC | newest] Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2021-05-05 13:14 [PATCH kvm-unit-tests] libcflat: provide long division routines Paolo Bonzini 2021-05-05 13:16 ` Paolo Bonzini 2021-05-05 19:46 ` Bill Wendling
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).