* hmmm... @ 2017-04-26 1:52 David Miller 2017-04-26 2:56 ` hmmm Alexei Starovoitov 0 siblings, 1 reply; 5+ messages in thread From: David Miller @ 2017-04-26 1:52 UTC (permalink / raw) To: ast; +Cc: netdev Alexei, I found something strange on my computer :-) [davem@localhost binutils]$ ./objdump -d x.o x.o: file format elf64-bpf Disassembly of section test1: 0000000000000000 <process>: 0: b7 00 00 00 00 00 00 02 mov r0, 2 8: 61 21 00 50 00 00 00 00 ldxw r2, [r1+80] 10: 61 11 00 4c 00 00 00 00 ldxw r1, [r1+76] 18: bf 41 00 00 00 00 00 00 mov r4, r1 20: 07 40 00 00 00 00 00 0e add r4, 14 28: 2d 42 00 25 00 00 00 00 jgt r4, r2, 148 <LBB0_11> 30: 71 51 00 0d 00 00 00 00 ldxb r5, [r1+13] 38: 71 31 00 0c 00 00 00 00 ldxb r3, [r1+12] 40: 67 30 00 00 00 00 00 08 lsh r3, 8 48: 4f 35 00 00 00 00 00 00 or r3, r5 50: 15 30 00 09 00 00 dd 86 jeq r3, 56710, 90 <process+0x90> 58: 55 30 00 1d 00 00 00 08 jne r3, 8, 138 <LBB0_6+0x70> 60: bf 31 00 00 00 00 00 00 mov r3, r1 68: 07 30 00 00 00 00 00 22 add r3, 34 70: 2d 32 00 1c 00 00 00 00 jgt r3, r2, 148 <LBB0_11> 78: b7 30 00 00 00 00 00 03 mov r3, 3 80: 71 54 00 00 00 00 00 00 ldxb r5, [r4+0] 88: 67 50 00 00 00 00 00 02 lsh r5, 2 90: 57 50 00 00 00 00 00 3c and r5, 60 98: 05 00 00 05 00 00 00 00 ja b8 <LBB0_5+0x18> 00000000000000a0 <LBB0_5>: a0: b7 50 00 00 00 00 00 28 mov r5, 40 a8: b7 30 00 00 00 00 00 00 mov r3, 0 b0: bf 41 00 00 00 00 00 00 mov r4, r1 b8: 07 40 00 00 00 00 00 36 add r4, 54 c0: 2d 42 00 12 00 00 00 00 jgt r4, r2, 148 <LBB0_11> 00000000000000c8 <LBB0_6>: c8: bf 41 00 00 00 00 00 00 mov r4, r1 d0: 0f 45 00 00 00 00 00 00 add r4, r5 d8: 07 40 00 00 00 00 00 0e add r4, 14 e0: 15 40 00 0c 00 00 00 00 jeq r4, 0, 138 <LBB0_6+0x70> e8: bf 54 00 00 00 00 00 00 mov r5, r4 f0: 07 50 00 00 00 00 00 14 add r5, 20 f8: 2d 52 00 0b 00 00 00 00 jgt r5, r2, 148 <LBB0_11> 100: 0f 13 00 00 00 00 00 00 add r1, r3 108: 71 11 00 14 00 00 00 00 ldxb r1, [r1+20] 110: 57 10 00 00 00 00 00 ff and r1, 255 118: 55 10 00 07 00 00 00 06 jne r1, 6, 148 <LBB0_11> 120: 07 40 00 00 00 00 00 12 add r4, 18 128: 2d 42 00 05 00 00 00 00 jgt r4, r2, 148 <LBB0_11> 130: b7 00 00 00 00 00 00 00 mov r0, 0 138: 69 14 00 00 00 00 00 00 ldxh r1, [r4+0] 140: 15 10 00 02 00 00 00 7b jeq r1, 123, 148 <LBB0_11> 0000000000000148 <LBB0_11>: 148: 18 00 00 00 ff ff ff ff ldimm64 r0, 4294967295 150: 00 00 00 00 00 00 00 00 0000000000000158 <LBB0_12>: 158: 95 00 00 00 00 00 00 00 exit [davem@localhost binutils]$ ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: hmmm... 2017-04-26 1:52 hmmm David Miller @ 2017-04-26 2:56 ` Alexei Starovoitov 2017-04-26 3:38 ` hmmm David Miller 0 siblings, 1 reply; 5+ messages in thread From: Alexei Starovoitov @ 2017-04-26 2:56 UTC (permalink / raw) To: David Miller; +Cc: netdev On 4/25/17 6:52 PM, David Miller wrote: > > Alexei, I found something strange on my computer :-) > > [davem@localhost binutils]$ ./objdump -d x.o No way! :) I thought it will take weeks! Ship it. Ship it. Ship it. Cannot wait to pull. This is awesome. Thanks a ton! What is the mnemonic for 32-bit alu ? ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: hmmm... 2017-04-26 2:56 ` hmmm Alexei Starovoitov @ 2017-04-26 3:38 ` David Miller 2017-04-26 5:31 ` hmmm Alexei Starovoitov 0 siblings, 1 reply; 5+ messages in thread From: David Miller @ 2017-04-26 3:38 UTC (permalink / raw) To: ast; +Cc: netdev From: Alexei Starovoitov <ast@fb.com> Date: Tue, 25 Apr 2017 19:56:06 -0700 > On 4/25/17 6:52 PM, David Miller wrote: >> >> Alexei, I found something strange on my computer :-) >> >> [davem@localhost binutils]$ ./objdump -d x.o > > No way! :) I thought it will take weeks! > Ship it. Ship it. Ship it. > Cannot wait to pull. > This is awesome. Thanks a ton! Relax, it is in a very raw state still. :) > What is the mnemonic for 32-bit alu ? It is of the form "xxx32". Here is opcodes table below. I think there are no formal mnenomics defined anywhere yet right? So just tell me what adjustments you want to make. #include "sysdep.h" #include <stdio.h> #include "opcode/bpf.h" #define BPF_OPC_ALU64 0x07 #define BPF_OPC_DW 0x18 #define BPF_OPC_XADD 0xc0 #define BPF_OPC_MOV 0xb0 #define BPF_OPC_ARSH 0xc0 #define BPF_OPC_END 0xd0 #define BPF_OPC_TO_LE 0x00 #define BPF_OPC_TO_BE 0x08 #define BPF_OPC_JNE 0x50 #define BPF_OPC_JSGT 0x60 #define BPF_OPC_JSGE 0x70 #define BPF_OPC_CALL 0x80 #define BPF_OPC_EXIT 0x90 #define BPF_OPC_LD 0x00 #define BPF_OPC_LDX 0x01 #define BPF_OPC_ST 0x02 #define BPF_OPC_STX 0x03 #define BPF_OPC_ALU 0x04 #define BPF_OPC_JMP 0x05 #define BPF_OPC_RET 0x06 #define BPF_OPC_MISC 0x07 #define BPF_OPC_W 0x00 #define BPF_OPC_H 0x08 #define BPF_OPC_B 0x10 #define BPF_OPC_IMM 0x00 #define BPF_OPC_ABS 0x20 #define BPF_OPC_IND 0x40 #define BPF_OPC_MEM 0x60 #define BPF_OPC_LEL 0x80 #define BPF_OPC_MSH 0xa0 #define BPF_OPC_ADD 0x00 #define BPF_OPC_SUB 0x10 #define BPF_OPC_MUL 0x20 #define BPF_OPC_DIV 0x30 #define BPF_OPC_OR 0x40 #define BPF_OPC_AND 0x50 #define BPF_OPC_LSH 0x60 #define BPF_OPC_RSH 0x70 #define BPF_OPC_NEG 0x80 #define BPF_OPC_MOD 0x90 #define BPF_OPC_XOR 0xa0 #define BPF_OPC_JA 0x00 #define BPF_OPC_JEQ 0x10 #define BPF_OPC_JGT 0x20 #define BPF_OPC_JGE 0x30 #define BPF_OPC_JSET 0x40 #define BPF_OPC_K 0x00 #define BPF_OPC_X 0x08 const struct bpf_opcode bpf_opcodes[] = { { "mov32", BPF_OPC_ALU | BPF_OPC_MOV | BPF_OPC_X, "1,2" }, { "mov", BPF_OPC_ALU64 | BPF_OPC_MOV | BPF_OPC_X, "1,2" }, { "add32", BPF_OPC_ALU | BPF_OPC_ADD | BPF_OPC_X, "1,2" }, { "add", BPF_OPC_ALU64 | BPF_OPC_ADD | BPF_OPC_X, "1,2" }, { "sub32", BPF_OPC_ALU | BPF_OPC_SUB | BPF_OPC_X, "1,2" }, { "sub", BPF_OPC_ALU64 | BPF_OPC_SUB | BPF_OPC_X, "1,2" }, { "and32", BPF_OPC_ALU | BPF_OPC_AND | BPF_OPC_X, "1,2" }, { "and", BPF_OPC_ALU64 | BPF_OPC_AND | BPF_OPC_X, "1,2" }, { "or32", BPF_OPC_ALU | BPF_OPC_OR | BPF_OPC_X, "1,2" }, { "or", BPF_OPC_ALU64 | BPF_OPC_OR | BPF_OPC_X, "1,2" }, { "xor32", BPF_OPC_ALU | BPF_OPC_XOR | BPF_OPC_X, "1,2" }, { "xor", BPF_OPC_ALU64 | BPF_OPC_XOR | BPF_OPC_X, "1,2" }, { "mul32", BPF_OPC_ALU | BPF_OPC_MUL | BPF_OPC_X, "1,2" }, { "mul", BPF_OPC_ALU64 | BPF_OPC_MUL | BPF_OPC_X, "1,2" }, { "div32", BPF_OPC_ALU | BPF_OPC_DIV | BPF_OPC_X, "1,2" }, { "div", BPF_OPC_ALU64 | BPF_OPC_DIV | BPF_OPC_X, "1,2" }, { "mod32", BPF_OPC_ALU | BPF_OPC_MOD | BPF_OPC_X, "1,2" }, { "mod", BPF_OPC_ALU64 | BPF_OPC_MOD | BPF_OPC_X, "1,2" }, { "lsh32", BPF_OPC_ALU | BPF_OPC_LSH | BPF_OPC_X, "1,2" }, { "lsh", BPF_OPC_ALU64 | BPF_OPC_LSH | BPF_OPC_X, "1,2" }, { "rsh32", BPF_OPC_ALU | BPF_OPC_RSH | BPF_OPC_X, "1,2" }, { "rsh", BPF_OPC_ALU64 | BPF_OPC_RSH | BPF_OPC_X, "1,2" }, { "arsh32", BPF_OPC_ALU | BPF_OPC_ARSH | BPF_OPC_X, "1,2" }, { "arsh", BPF_OPC_ALU64 | BPF_OPC_ARSH | BPF_OPC_X, "1,2" }, { "neg32", BPF_OPC_ALU | BPF_OPC_NEG | BPF_OPC_X, "1" }, { "neg", BPF_OPC_ALU64 | BPF_OPC_NEG | BPF_OPC_X, "1" }, { "endbe", BPF_OPC_ALU | BPF_OPC_END | BPF_OPC_TO_BE, "1,i" }, { "endle", BPF_OPC_ALU | BPF_OPC_END | BPF_OPC_TO_LE, "1,i" }, { "mov32", BPF_OPC_ALU | BPF_OPC_MOV | BPF_OPC_K, "1,i" }, { "mov", BPF_OPC_ALU64 | BPF_OPC_MOV | BPF_OPC_K, "1,i" }, { "add32", BPF_OPC_ALU | BPF_OPC_ADD | BPF_OPC_K, "1,i" }, { "add", BPF_OPC_ALU64 | BPF_OPC_ADD | BPF_OPC_K, "1,i" }, { "sub32", BPF_OPC_ALU | BPF_OPC_SUB | BPF_OPC_K, "1,i" }, { "sub", BPF_OPC_ALU64 | BPF_OPC_SUB | BPF_OPC_K, "1,i" }, { "and32", BPF_OPC_ALU | BPF_OPC_AND | BPF_OPC_K, "1,i" }, { "and", BPF_OPC_ALU64 | BPF_OPC_AND | BPF_OPC_K, "1,i" }, { "or32", BPF_OPC_ALU | BPF_OPC_XOR | BPF_OPC_K, "1,i" }, { "or", BPF_OPC_ALU64 | BPF_OPC_XOR | BPF_OPC_K, "1,i" }, { "xor32", BPF_OPC_ALU | BPF_OPC_OR | BPF_OPC_K, "1,i" }, { "xor", BPF_OPC_ALU64 | BPF_OPC_OR | BPF_OPC_K, "1,i" }, { "mul32", BPF_OPC_ALU | BPF_OPC_MUL | BPF_OPC_K, "1,i" }, { "mul", BPF_OPC_ALU64 | BPF_OPC_MUL | BPF_OPC_K, "1,i" }, { "div32", BPF_OPC_ALU | BPF_OPC_DIV | BPF_OPC_K, "1,i" }, { "div", BPF_OPC_ALU64 | BPF_OPC_DIV | BPF_OPC_K, "1,i" }, { "mod32", BPF_OPC_ALU | BPF_OPC_MOD | BPF_OPC_K, "1,i" }, { "mod", BPF_OPC_ALU64 | BPF_OPC_MOD | BPF_OPC_K, "1,i" }, { "lsh32", BPF_OPC_ALU | BPF_OPC_LSH | BPF_OPC_K, "1,i" }, { "lsh", BPF_OPC_ALU64 | BPF_OPC_LSH | BPF_OPC_K, "1,i" }, { "rsh32", BPF_OPC_ALU | BPF_OPC_RSH | BPF_OPC_K, "1,i" }, { "rsh", BPF_OPC_ALU64 | BPF_OPC_RSH | BPF_OPC_K, "1,i" }, { "arsh32", BPF_OPC_ALU | BPF_OPC_ARSH | BPF_OPC_K, "1,i" }, { "arsh", BPF_OPC_ALU64 | BPF_OPC_ARSH | BPF_OPC_K, "1,i" }, { "ja", BPF_OPC_JMP | BPF_OPC_JA, "L" }, { "jeq", BPF_OPC_JMP | BPF_OPC_JEQ | BPF_OPC_X, "1,2,L" }, { "jgt", BPF_OPC_JMP | BPF_OPC_JGT | BPF_OPC_X, "1,2,L" }, { "jge", BPF_OPC_JMP | BPF_OPC_JGE | BPF_OPC_X, "1,2,L" }, { "jne", BPF_OPC_JMP | BPF_OPC_JNE | BPF_OPC_X, "1,2,L" }, { "jsgt", BPF_OPC_JMP | BPF_OPC_JSGT | BPF_OPC_X, "1,2,L" }, { "jsge", BPF_OPC_JMP | BPF_OPC_JSGE | BPF_OPC_X, "1,2,L" }, { "jset", BPF_OPC_JMP | BPF_OPC_JSET | BPF_OPC_X, "1,2,L" }, { "jeq", BPF_OPC_JMP | BPF_OPC_JEQ | BPF_OPC_K, "1,i,L" }, { "jgt", BPF_OPC_JMP | BPF_OPC_JGT | BPF_OPC_K, "1,i,L" }, { "jge", BPF_OPC_JMP | BPF_OPC_JGE | BPF_OPC_K, "1,i,L" }, { "jne", BPF_OPC_JMP | BPF_OPC_JNE | BPF_OPC_K, "1,i,L" }, { "jsgt", BPF_OPC_JMP | BPF_OPC_JSGT | BPF_OPC_K, "1,i,L" }, { "jsge", BPF_OPC_JMP | BPF_OPC_JSGE | BPF_OPC_K, "1,i,L" }, { "jset", BPF_OPC_JMP | BPF_OPC_JSET | BPF_OPC_K, "1,i,L" }, { "call", BPF_OPC_JMP | BPF_OPC_CALL, "C" }, { "tailcall",BPF_OPC_JMP | BPF_OPC_CALL | BPF_OPC_X, "C" }, { "exit", BPF_OPC_JMP | BPF_OPC_EXIT, "" }, { "ldimm64", BPF_OPC_LD | BPF_OPC_IMM | BPF_OPC_DW, "1,D" }, { "ldxw", BPF_OPC_LDX | BPF_OPC_MEM | BPF_OPC_W, "1,[2+O]" }, { "ldxh", BPF_OPC_LDX | BPF_OPC_MEM | BPF_OPC_H, "1,[2+O]" }, { "ldxb", BPF_OPC_LDX | BPF_OPC_MEM | BPF_OPC_B, "1,[2+O]" }, { "ldxdw", BPF_OPC_LDX | BPF_OPC_MEM | BPF_OPC_DW, "1,[2+O]" }, { "stw", BPF_OPC_ST | BPF_OPC_MEM | BPF_OPC_W, "[1+O],i" }, { "sth", BPF_OPC_ST | BPF_OPC_MEM | BPF_OPC_H, "[1+O],i" }, { "stb", BPF_OPC_ST | BPF_OPC_MEM | BPF_OPC_B, "[1+O],i" }, { "stdw", BPF_OPC_ST | BPF_OPC_MEM | BPF_OPC_DW, "[1+O],i" }, { "stw", BPF_OPC_STX | BPF_OPC_MEM | BPF_OPC_W, "[1+O],2" }, { "sth", BPF_OPC_STX | BPF_OPC_MEM | BPF_OPC_H, "[1+O],2" }, { "stb", BPF_OPC_STX | BPF_OPC_MEM | BPF_OPC_B, "[1+O],2" }, { "stdw", BPF_OPC_STX | BPF_OPC_MEM | BPF_OPC_DW, "[1+O],2" }, { "xaddw", BPF_OPC_STX | BPF_OPC_XADD | BPF_OPC_W, "[1+O],2" }, { "xadddw", BPF_OPC_STX | BPF_OPC_XADD | BPF_OPC_DW, "[1+O],2" }, }; const int bpf_num_opcodes = ((sizeof bpf_opcodes)/(sizeof bpf_opcodes[0])); ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: hmmm... 2017-04-26 3:38 ` hmmm David Miller @ 2017-04-26 5:31 ` Alexei Starovoitov 2017-04-26 17:25 ` hmmm David Miller 0 siblings, 1 reply; 5+ messages in thread From: Alexei Starovoitov @ 2017-04-26 5:31 UTC (permalink / raw) To: David Miller; +Cc: netdev On 4/25/17 8:38 PM, David Miller wrote: > From: Alexei Starovoitov <ast@fb.com> > Date: Tue, 25 Apr 2017 19:56:06 -0700 > >> On 4/25/17 6:52 PM, David Miller wrote: >>> >>> Alexei, I found something strange on my computer :-) >>> >>> [davem@localhost binutils]$ ./objdump -d x.o >> >> No way! :) I thought it will take weeks! >> Ship it. Ship it. Ship it. >> Cannot wait to pull. >> This is awesome. Thanks a ton! > > Relax, it is in a very raw state still. :) hehe, before replied i checked binutils repo... hoping to find a miracle there :) >> What is the mnemonic for 32-bit alu ? > > It is of the form "xxx32". Here is opcodes table below. > > I think there are no formal mnenomics defined anywhere yet right? > So just tell me what adjustments you want to make. > > const struct bpf_opcode bpf_opcodes[] = { > { "mov32", BPF_OPC_ALU | BPF_OPC_MOV | BPF_OPC_X, "1,2" }, > { "mov", BPF_OPC_ALU64 | BPF_OPC_MOV | BPF_OPC_X, "1,2" }, > { "add32", BPF_OPC_ALU | BPF_OPC_ADD | BPF_OPC_X, "1,2" }, the very first bpf gen looked like canonical asm, but then I found myself spending too much time looking at ldb and ldd and thinking is it 8-byte or 64-byte load? jgt/jge/jsgt/sge was a stumbling block for me as well, since it still takes me longer than necessary to disambiguate into > vs >= and signed/unsigned gcc bpf backend was done way before llvm and it had quite confusing GT vs bpf GT vs x86 GT. https://github.com/iovisor-obsolete/bpf_gcc/commit/ff47b3acd6d3c60900fab8cd93afd8106c49c8c3#diff-ee684c67b9329b734b7fb535d86a558dR452 gcc GTU == bpf GT == x86 GA gcc GT == bpf SGT == x86 G gcc GE == bpf SGE == x86 GE I couldn't change bpf GT to GTU to match gcc, since it came from classic bpf, so could only add SGT. S for Signed. Through all this confusion I figured that the only output not superhuman can quickly read is C-like output, hence the final gcc output looked like: https://github.com/iovisor-obsolete/bpf_gcc/commit/ff47b3acd6d3c60900fab8cd93afd8106c49c8c3#diff-0db71d60fd74b52befee102a27f0b4c4R292 +(define_insn "movdi_2mem" + [(set (match_operand:DI 0 "memory_operand" "=m,m") + (match_operand:DI 1 "int_reg_or_const_operand" "r,K"))] + "" + "@ + BPF_INSN_ST(BPF_DW, %0, %1), // *(uint64*)(%0)=%1 + BPF_INSN_ST_IMM(BPF_DW, %0, %1), // *(uint64*)(%0)=%1" +[(set_attr "type" "store, store")]) yes, gcc was emitting C macros with C looking comments into fake .s file that we #included into .c code to be loaded into the kernel. (that code is abandoned and probably doesn't compile anymore) I made the verifier to emit C-like output to make it easier for program writers to understand. llvm asm until version 4.0 looked like: mov r0, 1 ldd r4, 8(r1) ldd r3, 0(r1) mov r5, r3 addi r5, 14 jgt r5, r4 goto LBB0_3 which was causing confusion as well, so when I realized that llvm can emit and parse any type of text, I switched to emit verifier like asm code: r2 = *(u64 *)(r10 - 16) r5 = r2 r5 += 34 r0 = 2 if r5 > r3 goto LBB0_1 which I think is way easier to read. Though I think Daniel still prefers old classic bpf asm ;) Anyway, back to the question... since BFD and GCC are so much entrenched into canonical style of asm code, I don't mind that gnu toolchain will be using it. I like that you used 'dw' in 'ldxdw' instead of just 'd' though 'x' can probably be dropped. 'x' should be added here instead: { "stb", BPF_OPC_ST | BPF_OPC_MEM | BPF_OPC_B, "[1+O],i" }, { "stb", BPF_OPC_STX | BPF_OPC_MEM | BPF_OPC_B, "[1+O],2" }, I would use ld8/ld16/ld32/ld64 and st8/stx8/st16/stx16/... but I spent too much time looking into asm and I'm biased. Thanks again for working on it! This is major milestone. ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: hmmm... 2017-04-26 5:31 ` hmmm Alexei Starovoitov @ 2017-04-26 17:25 ` David Miller 0 siblings, 0 replies; 5+ messages in thread From: David Miller @ 2017-04-26 17:25 UTC (permalink / raw) To: ast; +Cc: netdev From: Alexei Starovoitov <ast@fb.com> Date: Tue, 25 Apr 2017 22:31:06 -0700 > On 4/25/17 8:38 PM, David Miller wrote: > jgt/jge/jsgt/sge was a stumbling block for me as well, > since it still takes me longer than necessary to disambiguate > into > vs >= and signed/unsigned I had this problem while writing Sparc JIT :) > Though I think Daniel still prefers old classic bpf asm ;) I do too. > Anyway, back to the question... > since BFD and GCC are so much entrenched into canonical style > of asm code, I don't mind that gnu toolchain will be using it. Ok. All data flows from right to left in the instructions so it will be familiar for x86 assembler hackers. > I like that you used 'dw' in 'ldxdw' instead of just 'd' > though 'x' can probably be dropped. Ok, dropped. > 'x' should be added here instead: > { "stb", BPF_OPC_ST | BPF_OPC_MEM | BPF_OPC_B, "[1+O],i" }, > { "stb", BPF_OPC_STX | BPF_OPC_MEM | BPF_OPC_B, "[1+O],2" }, The 'x' really isn't necessary, I would say. Assembler can tell from context whether immediate or register variant is wanted and thus: stb [r1+8], 2 stb [r1+8], r4 are both assembled correctly. ^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2017-04-26 17:25 UTC | newest] Thread overview: 5+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2017-04-26 1:52 hmmm David Miller 2017-04-26 2:56 ` hmmm Alexei Starovoitov 2017-04-26 3:38 ` hmmm David Miller 2017-04-26 5:31 ` hmmm Alexei Starovoitov 2017-04-26 17:25 ` hmmm David Miller
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).