All of lore.kernel.org
 help / color / mirror / Atom feed
From: Yonghong Song <yonghong.song@linux.dev>
To: 赵佳炜 <phoenix500526@163.com>
Cc: ast@kernel.org, daniel@iogearbox.net, andrii@kernel.org,
	bpf@vger.kernel.org, linux-kselftest@vger.kernel.org,
	linux-kernel@vger.kernel.org
Subject: Re: [PATCH v7 2/2] selftests/bpf: Force -O2 for USDT selftests to cover SIB handling logic
Date: Mon, 18 Aug 2025 10:35:04 -0700	[thread overview]
Message-ID: <7495eeb9-777b-4b9e-8312-c6654268d6ec@linux.dev> (raw)
In-Reply-To: <46f4c341.1dea.198b845a4b0.Coremail.phoenix500526@163.com>



On 8/17/25 6:43 AM, 赵佳炜 wrote:
>
>
>
>
>
>
> Hi, Yonghong. I've already filed an issue[1] in GCC  community.
>
>
> Accroding to the discussion, it's not a gcc bug but may be a systemtap bug.
> I don't know how to report this bug to systemtap, but I found that the
> libbpf/usdt have the same problem. I've filed an issue in libbpf/usdt repo[2].
>
> I also have some ideas about it. I wrote it down in the issue[2] comment.
> May be we can discuss there.
>
> [1]. https://gcc.gnu.org/bugzilla/show_bug.cgi?id=121569
> [2]. https://github.com/libbpf/usdt/issues/13

Thanks for filing an issue on gcc and getting some feedback/suggestions
from gcc community.

Currently, libbpf/usdt does not suport format like '-1@ti(%rip)'. If we do
intend to implement this. libbpf/usdt can reject that if 'ti' is a
static variable. libbpf can provide some hints about how to make it
work (see above [1] and [2]). Then, it would be user's reponsibility to
change code so libbpf can support it.

>
>
>
> At 2025-08-13 13:24:39, "Yonghong Song" <yonghong.song@linux.dev> wrote:
>>
>> On 8/12/25 7:27 PM, 赵佳炜 wrote:
>>>
>>>
>>>
>>>
>>> Sure.
>>>
>>> The usdt_rip.c source code:
>>>
>>> ```C
>>> // the usdt_rip.c file
>>> #include <stddef.h>
>>> #include <stdint.h>
>>> #include "sdt.h"
>>>
>>> static volatile char ti = 0;
>>>
>>> int add(int a, int b) {
>>>     return a + b;
>>> }
>>> int (*add_ptr)(int, int) = add;
>>>
>>> struct st{
>>>     int a;
>>>     char b;
>>> };
>>>
>>> volatile struct st t1 = {.a = 1, .b = 'a'};
>>>
>>> static void __always_inline trigger_func() {
>>>     STAP_PROBE4(usdt_rip, rip_global_var, ti, add_ptr, t1.b, ti);
>>> }
>>>
>>> int main() {
>>>     trigger_func();
>>>     return 0;
>>> }
>>> ```
>>>
>>> The test/usdt_rip.c source code:
>>>
>>> ```C
>>> // The test/usdt_rip.c file
>>> static volatile char ti = 0;
>>> ```
>>>
>>> The compiler option is `gcc -O2 -g usdt_rip.c test/usdt_rip.c -o usdt_rip`
>>>
>>> My compiler version:
>>> ```bash
>>> $ gcc -v
>>> Using built-in specs.
>>> COLLECT_GCC=gcc
>>> COLLECT_LTO_WRAPPER=/usr/libexec/gcc/x86_64-linux-gnu/13/lto-wrapper
>>> OFFLOAD_TARGET_NAMES=nvptx-none:amdgcn-amdhsa
>>> OFFLOAD_TARGET_DEFAULT=1
>>> Target: x86_64-linux-gnu
>>> Configured with: ../src/configure -v --with-pkgversion='Ubuntu 13.3.0-6ubuntu2~24.04' --with-bugurl=file:///usr/share/doc/gcc-13/README.Bugs --enable-languages=c,ada,c++,go,d,fortran,objc,obj-c++,m2 --prefix=/usr --with-gcc-major-version-only --program-suffix=-13 --program-prefix=x86_64-linux-gnu- --enable-shared --enable-linker-build-id --libexecdir=/usr/libexec --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --enable-bootstrap --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-libstdcxx-backtrace --enable-gnu-unique-object --disable-vtable-verify --enable-plugin --enable-default-pie --with-system-zlib --enable-libphobos-checking=release --with-target-system-zlib=auto --enable-objc-gc=auto --enable-multiarch --disable-werror --enable-cet --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --enable-multilib --with-tune=generic --enable-offload-targets=nvptx-none=/build/gcc-13-fG75Ri/gcc-13-13.3.0/debian/tmp-nvptx/usr,amdgcn-amdhsa=/build/gcc-13-fG75Ri/gcc-13-13.3.0/debian/tmp-gcn/usr --enable-offload-defaulted --without-cuda-driver --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu --with-build-config=bootstrap-lto-lean --enable-link-serialization=2
>>> Thread model: posix
>>> Supported LTO compression algorithms: zlib zstd
>>> gcc version 13.3.0 (Ubuntu 13.3.0-6ubuntu2~24.04)
>>> ```
>> Thanks for the code. I compiled with gcc14 compiler and the below is the asm code for 'main' function:
>>
>> 0000000000401020 <main>:
>>    401020:       90                      nop
>>    401021:       31 c0                   xor    %eax,%eax
>>    401023:       c3                      ret
>>    401024:       66 2e 0f 1f 84 00 00    cs nopw 0x0(%rax,%rax,1)
>>    40102b:       00 00 00
>>    40102e:       66 90                   xchg   %ax,%ax
>>
>> stapsdt note:
>>    Displaying notes found in: .note.stapsdt
>>      Owner                Data size        Description
>>      stapsdt              0x00000066       NT_STAPSDT (SystemTap probe descriptors)
>>        Provider: usdt_rip
>>        Name: rip_global_var
>>        Location: 0x0000000000401020, Base: 0x0000000000402010, Semaphore: 0x0000000000000000
>>        Arguments: -1@ti(%rip) 8@add_ptr(%rip) -1@t1+4(%rip) -1@ti(%rip)
>>
>> $ readelf -s usdt_rip | grep ti
>>       4: 0000000000404019     1 OBJECT  LOCAL  DEFAULT   24 ti
>>      14: 000000000040401a     1 OBJECT  LOCAL  DEFAULT   24 ti
>>
>> So yet, it would be hard to find which 'ti' should be used to resolve usdt arguments.
>>
>>
>> I then tried with clang21. The 'main' function:
>>
>> 0000000000001140 <main>:
>>      1140:       0f b6 05 f2 2e 00 00    movzbl 0x2ef2(%rip),%eax        # 4039 <ti>
>>      1147:       48 8b 0d da 2e 00 00    mov    0x2eda(%rip),%rcx        # 4028 <add_ptr>
>>      114e:       0f b6 15 df 2e 00 00    movzbl 0x2edf(%rip),%edx        # 4034 <t1+0x4>
>>      1155:       0f b6 35 dd 2e 00 00    movzbl 0x2edd(%rip),%esi        # 4039 <ti>
>>      115c:       88 44 24 f7             mov    %al,-0x9(%rsp)
>>      1160:       48 89 4c 24 f8          mov    %rcx,-0x8(%rsp)
>>      1165:       88 54 24 f6             mov    %dl,-0xa(%rsp)
>>      1169:       40 88 74 24 f5          mov    %sil,-0xb(%rsp)
>>      116e:       90                      nop
>>      116f:       31 c0                   xor    %eax,%eax
>>      1171:       c3                      ret
>>      1172:       66 90                   xchg   %ax,%ax
>>
>> For this case, usdt should work properly. The following is related symbol table:
>>
>>      74: 0000000000004028     8 OBJECT  GLOBAL DEFAULT    26 add_ptr
>>      64: 0000000000004030     8 OBJECT  GLOBAL DEFAULT    26 t1
>>      50: 0000000000004039     1 OBJECT  LOCAL  DEFAULT    27 ti  <=== for '# 4039 <ti>'.
>>
>> And for llvm21, only one 'ti' in the symbol table.
>>
>> $ readelf -s usdt_rip | grep ti
>>      50: 0000000000004039     1 OBJECT  LOCAL  DEFAULT   27 ti
>>
>> The stapsdt note:
>>    Displaying notes found in: .note.stapsdt
>>      Owner                Data size        Description
>>      stapsdt              0x00000061       NT_STAPSDT (SystemTap probe descriptors)
>>        Provider: usdt_rip
>>        Name: rip_global_var
>>        Location: 0x000000000000116e, Base: 0x0000000000002004, Semaphore: 0x0000000000000000
>>        Arguments: -1@-9(%rsp) 8@-8(%rsp) -1@-10(%rsp) -1@-11(%rsp)
>>
>> It looks like clang optimized away the following:
>>    // The test/usdt_rip.c file
>>    static volatile char ti = 0;
>> but gcc does not. But even if the above 'ti' is preserved for clang,
>> clang generated code should still be fine since the argument
>> is -1@-9(%rsp) 8@-8(%rsp) -1@-10(%rsp) -1@-11(%rsp).
>>
>> I think you can file a bug for gcc community.
>>
>>>
>>> At 2025-08-13 00:11:45, "Yonghong Song" <yonghong.song@linux.dev> wrote:
>>>> On 8/12/25 12:02 AM, 赵佳炜 wrote:
>>>>> Yes, I've tried that but it didn't help. FYI:
>>>>>
>>>>> $ readelf -nsr usdt_rip
>>>>>
>>>>>
>>>>> Relocation section '.rela.dyn' at offset 0x530 contains 9 entries:
>>>>>      Offset          Info           Type           Sym. Value    Sym. Name + Addend
>>>>> 000000003df0  000000000008 R_X86_64_RELATIVE                    1150
>>>>> 000000003df8  000000000008 R_X86_64_RELATIVE                    1110
>>>>> 000000004008  000000000008 R_X86_64_RELATIVE                    4008
>>>>> 000000004018  000000000008 R_X86_64_RELATIVE                    1160
>>>>> 000000003fd8  000100000006 R_X86_64_GLOB_DAT 0000000000000000 __libc_start_main@GLIBC_2.34 + 0
>>>>> 000000003fe0  000200000006 R_X86_64_GLOB_DAT 0000000000000000 _ITM_deregisterTM[...] + 0
>>>>> 000000003fe8  000300000006 R_X86_64_GLOB_DAT 0000000000000000 __gmon_start__ + 0
>>>>> 000000003ff0  000400000006 R_X86_64_GLOB_DAT 0000000000000000 _ITM_registerTMCl[...] + 0
>>>>> 000000003ff8  000500000006 R_X86_64_GLOB_DAT 0000000000000000 __cxa_finalize@GLIBC_2.2.5 + 0
>>>>>
>>>>>
>>>>> Symbol table '.dynsym' contains 6 entries:
>>>>>       Num:    Value          Size Type    Bind   Vis      Ndx Name
>>>>>         0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND
>>>>>         1: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND _[...]@GLIBC_2.34 (2)
>>>>>         2: 0000000000000000     0 NOTYPE  WEAK   DEFAULT  UND _ITM_deregisterT[...]
>>>>>         3: 0000000000000000     0 NOTYPE  WEAK   DEFAULT  UND __gmon_start__
>>>>>         4: 0000000000000000     0 NOTYPE  WEAK   DEFAULT  UND _ITM_registerTMC[...]
>>>>>         5: 0000000000000000     0 FUNC    WEAK   DEFAULT  UND [...]@GLIBC_2.2.5 (3)
>>>>>
>>>>>
>>>>> Symbol table '.symtab' contains 42 entries:
>>>>>       Num:    Value          Size Type    Bind   Vis      Ndx Name
>>>>>         0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND
>>>>>         1: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS Scrt1.o
>>>>>         2: 000000000000038c    32 OBJECT  LOCAL  DEFAULT    4 __abi_tag
>>>>>         3: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS usdt_rip.c
>>>>>         4: 0000000000004021     1 OBJECT  LOCAL  DEFAULT   25 ti
>>>>>         5: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS crtstuff.c
>>>>>         6: 00000000000010a0     0 FUNC    LOCAL  DEFAULT   14 deregister_tm_clones
>>>>>         7: 00000000000010d0     0 FUNC    LOCAL  DEFAULT   14 register_tm_clones
>>>>>         8: 0000000000001110     0 FUNC    LOCAL  DEFAULT   14 __do_global_dtors_aux
>>>>>         9: 0000000000004020     1 OBJECT  LOCAL  DEFAULT   25 completed.0
>>>>>        10: 0000000000003df8     0 OBJECT  LOCAL  DEFAULT   21 __do_global_dtor[...]
>>>>>        11: 0000000000001150     0 FUNC    LOCAL  DEFAULT   14 frame_dummy
>>>>>        12: 0000000000003df0     0 OBJECT  LOCAL  DEFAULT   20 __frame_dummy_in[...]
>>>>>        13: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS damo.c
>>>>>        14: 0000000000004022     1 OBJECT  LOCAL  DEFAULT   25 ti
>>>>>        15: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS crtstuff.c
>>>>>        16: 00000000000020d8     0 OBJECT  LOCAL  DEFAULT   19 __FRAME_END__
>>>>>        17: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS
>>>>>        18: 0000000000003e00     0 OBJECT  LOCAL  DEFAULT   22 _DYNAMIC
>>>>>        19: 0000000000002008     0 NOTYPE  LOCAL  DEFAULT   18 __GNU_EH_FRAME_HDR
>>>>>        20: 0000000000003fc0     0 OBJECT  LOCAL  DEFAULT   23 _GLOBAL_OFFSET_TABLE_
>>>>>        21: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND __libc_start_mai[...]
>>>>>        22: 0000000000000000     0 NOTYPE  WEAK   DEFAULT  UND _ITM_deregisterT[...]
>>>>>        23: 0000000000004000     0 NOTYPE  WEAK   DEFAULT   24 data_start
>>>>>        24: 0000000000001160     8 FUNC    GLOBAL DEFAULT   14 add
>>>>>        25: 0000000000004020     0 NOTYPE  GLOBAL DEFAULT   24 _edata
>>>>>        26: 0000000000002004     1 NOTYPE  WEAK   HIDDEN    17 _.stapsdt.base
>>>>>        27: 0000000000004010     8 OBJECT  GLOBAL DEFAULT   24 t1
>>>>>        28: 0000000000001168     0 FUNC    GLOBAL HIDDEN    15 _fini
>>>>>        29: 0000000000004000     0 NOTYPE  GLOBAL DEFAULT   24 __data_start
>>>>>        30: 0000000000000000     0 NOTYPE  WEAK   DEFAULT  UND __gmon_start__
>>>>>        31: 0000000000004008     0 OBJECT  GLOBAL HIDDEN    24 __dso_handle
>>>>>        32: 0000000000002000     4 OBJECT  GLOBAL DEFAULT   16 _IO_stdin_used
>>>>>        33: 0000000000004028     0 NOTYPE  GLOBAL DEFAULT   25 _end
>>>>>        34: 0000000000001070    38 FUNC    GLOBAL DEFAULT   14 _start
>>>>>        35: 0000000000004020     0 NOTYPE  GLOBAL DEFAULT   25 __bss_start
>>>>>        36: 0000000000001040    48 FUNC    GLOBAL DEFAULT   14 main
>>>>>        37: 0000000000004018     8 OBJECT  GLOBAL DEFAULT   24 add_ptr
>>>>>        38: 0000000000004020     0 OBJECT  GLOBAL HIDDEN    24 __TMC_END__
>>>>>        39: 0000000000000000     0 NOTYPE  WEAK   DEFAULT  UND _ITM_registerTMC[...]
>>>>>        40: 0000000000000000     0 FUNC    WEAK   DEFAULT  UND __cxa_finalize@G[...]
>>>>>        41: 0000000000001000     0 FUNC    GLOBAL HIDDEN    11 _init
>>>>>
>>>>>
>>>>> Displaying notes found in: .note.gnu.property
>>>>>      Owner                Data size        Description
>>>>>      GNU                  0x00000020       NT_GNU_PROPERTY_TYPE_0
>>>>>          Properties: x86 feature: IBT, SHSTK
>>>>>            x86 ISA needed: x86-64-baseline
>>>>>
>>>>>
>>>>> Displaying notes found in: .note.gnu.build-id
>>>>>      Owner                Data size        Description
>>>>>      GNU                  0x00000014       NT_GNU_BUILD_ID (unique build ID bitstring)
>>>>>        Build ID: eb615daa575687cc44edc1d339b27890c12c27f1
>>>>>
>>>>>
>>>>> Displaying notes found in: .note.ABI-tag
>>>>>      Owner                Data size        Description
>>>>>      GNU                  0x00000010       NT_GNU_ABI_TAG (ABI version tag)
>>>>>        OS: Linux, ABI: 3.2.0
>>>>>
>>>>>
>>>>> Displaying notes found in: .note.stapsdt
>>>>>      Owner                Data size        Description
>>>>>      stapsdt              0x00000066       NT_STAPSDT (SystemTap probe descriptors)
>>>>>        Provider: usdt_rip
>>>>>        Name: rip_global_var
>>>>>        Location: 0x0000000000001058, Base: 0x0000000000002004, Semaphore: 0x0000000000000000
>>>>>        Arguments: -1@ti(%rip) 8@add_ptr(%rip) -1@4+t1(%rip) -1@ti(%rip)
>>>> Could you share the complete source codes and compiler options which
>>>> reproduce the above result?
>>>>
>>>>>
>>>>> At 2025-08-12 13:06:40, "Yonghong Song" <yonghong.song@linux.dev> wrote:
>>>>>> On 8/10/25 1:55 AM, 赵佳炜 wrote:
>>>>>>> Hi Yonghong,
>>>>>>>
>>>>>>> I found another issue where symbols can be duplicated, and I’m not sure how to tell them apart.
>>>>>>>
>>>>>>> For example, I created two C files named usdt_rip.c and hello.c. Both define their own static ti variables, like:`static volatile char ti = 0;`.
>>>>>>>
>>>>>>> After compiling, I obtained an ELF file usdt_rip whose .symtab contains the following entries:
>>>>>>>
>>>>>>> $ readelf -s usdt_rip
>>>>>>>
>>>>>>> Symbol table '.symtab' contains 42 entries:
>>>>>>>        Num:    Value          Size Type    Bind   Vis      Ndx Name
>>>>>>>          0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND
>>>>>>>          1: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS Scrt1.o
>>>>>>>          2: 000000000000038c    32 OBJECT  LOCAL  DEFAULT    4 __abi_tag
>>>>>>>          3: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS usdt_rip.c
>>>>>>>          4: 0000000000004021     1 OBJECT  LOCAL  DEFAULT   25 ti
>>>>>>>          5: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS crtstuff.c
>>>>>>>          6: 00000000000010a0     0 FUNC    LOCAL  DEFAULT   14 deregister_tm_clones
>>>>>>>          7: 00000000000010d0     0 FUNC    LOCAL  DEFAULT   14 register_tm_clones
>>>>>>>          8: 0000000000001110     0 FUNC    LOCAL  DEFAULT   14 __do_global_dtors_aux
>>>>>>>          9: 0000000000004020     1 OBJECT  LOCAL  DEFAULT   25 completed.0
>>>>>>>         10: 0000000000003df8     0 OBJECT  LOCAL  DEFAULT   21 __do_global_dtor[...]
>>>>>>>         11: 0000000000001150     0 FUNC    LOCAL  DEFAULT   14 frame_dummy
>>>>>>>         12: 0000000000003df0     0 OBJECT  LOCAL  DEFAULT   20 __frame_dummy_in[...]
>>>>>>>         13: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS damo.c
>>>>>>>         14: 0000000000004022     1 OBJECT  LOCAL  DEFAULT   25 ti
>>>>>>>         15: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS crtstuff.c
>>>>>>>         16: 00000000000020d8     0 OBJECT  LOCAL  DEFAULT   19 __FRAME_END__
>>>>>>>
>>>>>>>
>>>>>>> As you can see, there are two ti variables in the .symtab section. Their values are very close, making them hard to distinguish.
>>>>>>>
>>>>>>> I’m unsure how to handle this situation. Do you have any suggestions?
>>>>>> Did you check relocations? Relocaitons should be able to point exact which symbol.
>>>>>>
>>>>>>> Thanks,
>>>>>>> Jiawei Zhao
>>>>>> [...]


  reply	other threads:[~2025-08-18 17:35 UTC|newest]

Thread overview: 24+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-08-06  9:24 [PATCH v7 0/2] libbpf: fix USDT SIB argument handling causing unrecognized register error Jiawei Zhao
2025-08-06  9:24 ` [PATCH v7 1/2] " Jiawei Zhao
2025-08-06  9:24 ` [PATCH v7 2/2] selftests/bpf: Force -O2 for USDT selftests to cover SIB handling logic Jiawei Zhao
2025-08-06 18:17   ` Yonghong Song
2025-08-07  2:57     ` 赵佳炜
2025-08-07 18:01       ` Yonghong Song
2025-08-10  8:55         ` 赵佳炜
2025-08-10  9:39           ` 赵佳炜
2025-08-12  5:06           ` Yonghong Song
2025-08-12  7:02             ` 赵佳炜
2025-08-12 16:11               ` Yonghong Song
2025-08-13  2:27                 ` 赵佳炜
2025-08-13  5:24                   ` Yonghong Song
2025-08-13  6:23                     ` 赵佳炜
2025-08-17 13:43                     ` 赵佳炜
2025-08-18 17:35                       ` Yonghong Song [this message]
2025-08-19  9:50                         ` 赵佳炜
2025-08-20 20:57                           ` Yonghong Song
2025-08-20 23:00                         ` Andrii Nakryiko
2025-08-21 15:38                           ` 赵佳炜
2025-08-21 18:28                             ` Andrii Nakryiko
2025-08-22 15:39                               ` 赵佳炜
2025-08-07  9:28     ` Jiri Olsa
2025-08-06 18:07 ` [PATCH v7 0/2] libbpf: fix USDT SIB argument handling causing unrecognized register error Yonghong Song

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=7495eeb9-777b-4b9e-8312-c6654268d6ec@linux.dev \
    --to=yonghong.song@linux.dev \
    --cc=andrii@kernel.org \
    --cc=ast@kernel.org \
    --cc=bpf@vger.kernel.org \
    --cc=daniel@iogearbox.net \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-kselftest@vger.kernel.org \
    --cc=phoenix500526@163.com \
    /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.