Re: RTLD_DEEPBIND question
- Reply: Andriy Gapon : "Re: RTLD_DEEPBIND question"
- In reply to: Andriy Gapon : "Re: RTLD_DEEPBIND question"
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Sat, 19 Apr 2025 09:39:27 UTC
On 19/04/2025 12:25, Andriy Gapon wrote:
> On 19/04/2025 02:41, Konstantin Belousov wrote:
>> Could it be that the module is linked to the main binary?
>
> It does not appear to be so.
> The binary:
> $ ldd /usr/local/bin/mdb
> /usr/local/bin/mdb:
> libncursesw.so.9 => /lib/libncursesw.so.9 (0xbf191c93000)
> libtinfow.so.9 => /lib/libtinfow.so.9 (0xbf190b45000)
> libkvm.so.7 => /lib/libkvm.so.7 (0xbf192a74000)
> libproc.so.5 => /usr/lib/libproc.so.5 (0xbf1930f4000)
> librtld_db.so.2 => /usr/lib/librtld_db.so.2 (0xbf19382d000)
> libctf.so.2 => /lib/libctf.so.2 (0xbf19466c000)
> libumem.so.2 => /lib/libumem.so.2 (0xbf194b0a000)
> libelf.so.2 => /lib/libelf.so.2 (0xbf194eb6000)
> libutil.so.9 => /lib/libutil.so.9 (0xbf19550c000)
> libz.so.6 => /lib/libz.so.6 (0xbf195875000)
> libc.so.7 => /lib/libc.so.7 (0xbf1961fb000)
> libcxxrt.so.1 => /lib/libcxxrt.so.1 (0xbf197493000)
> libprocstat.so.1 => /usr/lib/libprocstat.so.1 (0xbf197753000)
> libspl.so.2 => /lib/libspl.so.2 (0xbf197f77000)
> libsys.so.7 => /lib/libsys.so.7 (0xbf198bc6000)
> libgcc_s.so.1 => /lib/libgcc_s.so.1 (0xbf199475000)
> [vdso] (0xbf1902db000)
>
> The module:
> $ ldd /usr/local/lib/mdb/kvm/amd64/dtrace.so
> /usr/local/lib/mdb/kvm/amd64/dtrace.so:
> libdtrace.so.2 => /lib/libdtrace.so.2 (0x24d1702c8000)
> libm.so.5 => /lib/libm.so.5 (0x24d1711c3000)
> libc.so.7 => /lib/libc.so.7 (0x24d16cfbb000)
> libctf.so.2 => /lib/libctf.so.2 (0x24d16eee6000)
> libelf.so.2 => /lib/libelf.so.2 (0x24d16c13e000)
> libproc.so.5 => /usr/lib/libproc.so.5 (0x24d172085000)
> librtld_db.so.2 => /usr/lib/librtld_db.so.2 (0x24d173d46000)
> libxo.so.0 => /lib/libxo.so.0 (0x24d172b1d000)
> libthr.so.3 => /lib/libthr.so.3 (0x24d17411c000)
> libspl.so.2 => /lib/libspl.so.2 (0x24d174e8d000)
> libz.so.6 => /lib/libz.so.6 (0x24d173a38000)
> libcxxrt.so.1 => /lib/libcxxrt.so.1 (0x24d17635a000)
> libprocstat.so.1 => /usr/lib/libprocstat.so.1 (0x24d175fb8000)
> libutil.so.9 => /lib/libutil.so.9 (0x24d176864000)
> libsys.so.7 => /lib/libsys.so.7 (0x24d16df97000)
> libgcc_s.so.1 => /lib/libgcc_s.so.1 (0x24d17567f000)
> libkvm.so.7 => /lib/libkvm.so.7 (0x24d177768000)
>
>> RTLD_DEEPBIND works by first iterating over all (recursive) DT_NEEEDED
>> object for the object where the symbol is resolved, then by looking at
>> the global list of loaded objects.
>> Non-deepbind resolution is performed by looking at the global list.
>>
>> You can see it in the rtld.c:symlook_default().
From a quick look at the code, should we try to resolve the symbol in refobj
itself when it's marked with deepbind?
>> Also it might be useful to set LD_DEBUG=1 and read the debugging output
>> from rtld.
> Thank you for reminding me about LD_DEBUG.I can provide the full output I got
> with it, but here are some interesting bits.
> BTW, I tried both RTLD_NOW and RTLD_LAZY, just in case.
> There was no difference in behavior.
> This output is when using RTLD_LAZY.
>
> dlopen_object name "/usr/local/lib/mdb/kvm/amd64/dtrace.so" fd -1 refobj "/usr/
> local/bin/mdb" lo_flags 0x82 mode 0x1
>
> lm_find("/usr/local/bin/mdb", "/usr/local/lib/mdb/kvm/amd64/dtrace.so")
> lml_find(0x2fe0e1004198, "/usr/local/lib/mdb/kvm/amd64/dtrace.so")
> loading "/usr/local/lib/mdb/kvm/amd64/dtrace.so"
> /usr/local/lib/mdb/kvm/amd64/dtrace.so valid_hash_sysv 1 valid_hash_gnu 1
> dynsymcount 75
> 0x1b24f41bf000 .. 0x1b24f41cdfff: /usr/local/lib/mdb/kvm/amd64/dtrace.so
> lm_find("/usr/local/lib/mdb/kvm/amd64/dtrace.so", "libdtrace.so.2")
> lmp_find("/usr/local/lib/mdb/kvm/amd64/dtrace.so")
> lml_find(0x2fe0e1004198, "libdtrace.so.2")
> Searching for "libdtrace.so.2"
> search_library_pathfds('libdtrace.so.2', '(null)', fdp)
> lm_find("/usr/local/lib/mdb/kvm/amd64/dtrace.so", "/lib")
> lmp_find("/usr/local/lib/mdb/kvm/amd64/dtrace.so")
> Trying "/lib/libdtrace.so.2"
> Opened "/lib/libdtrace.so.2", fd 51
> loading "/lib/libdtrace.so.2"
> /lib/libdtrace.so.2 valid_hash_sysv 1 valid_hash_gnu 1 dynsymcount 810
> 0x1b24efbcc000 .. 0x1b24efc7afff: /lib/libdtrace.so.2
> lm_find("/usr/local/lib/mdb/kvm/amd64/dtrace.so", "libm.so.5")
> lmp_find("/usr/local/lib/mdb/kvm/amd64/dtrace.so")
> lm_find("/usr/local/lib/mdb/kvm/amd64/dtrace.so", "/lib")
> lmp_find("/usr/local/lib/mdb/kvm/amd64/dtrace.so")
> lm_find("/lib/libdtrace.so.2", "libxo.so.0")
> lmp_find("/lib/libdtrace.so.2")
> lm_find("/lib/libdtrace.so.2", "/lib")
> lmp_find("/lib/libdtrace.so.2")
> lm_find("/lib/libdtrace.so.2", "libthr.so.3")
> lmp_find("/lib/libdtrace.so.2")
> lm_find("/lib/libdtrace.so.2", "/lib")
> lmp_find("/lib/libdtrace.so.2")
> relocating "/usr/local/lib/mdb/kvm/amd64/dtrace.so"
> relocating "/lib/libdtrace.so.2"
> calling init function for /lib/libdtrace.so.2 at 0x1b24efc689cc
> calling init function for /lib/libdtrace.so.2 at 0x1b24efc179a0
> calling init function for /lib/libdtrace.so.2 at 0x1b24efc420d0
> "getenv" in "libdtrace.so.2" ==> 0x1b24edfea3f0 in "libc.so.7"
> "rd_init" in "libdtrace.so.2" ==> 0x1b24e9dd07d0 in "librtld_db.so.2"
> calling init function for /usr/local/lib/mdb/kvm/amd64/dtrace.so at 0x1b24f41cacac
> calling init function for /usr/local/lib/mdb/kvm/amd64/dtrace.so at
> 0x1b24f41c49e0So far so good, I think.The module got loaded, libdtrace got
> loaded as its dependency and then some dependencies Then I executed a command
> that made a call into dtrace.so module.
> "mdb_getopts" in "dtrace.so" ==> 0x1b1cc46b6760 in "mdb"
> "mdb_readvar" in "dtrace.so" ==> 0x1b1cc46db470 in "mdb"
> "mdb_vread" in "dtrace.so" ==> 0x1b1cc46db040 in "mdb"
> "memset" in "dtrace.so" ==> 0x1b24edfde8f0 in "libc.so.7"
> "dtrace_vopen" in "dtrace.so" ==> 0x1b24efc43320 in "libdtrace.so.2"
> "elf_version" in "libdtrace.so.2" ==> 0x1b24eafbefe0 in "libelf.so.2"
> "calloc" in "libdtrace.so.2" ==> 0x1b24edffd0a0 in "libc.so.7"
> "dt_proc_init" in "libdtrace.so.2" ==> 0x1b24efc5be40 in "libdtrace.so.2"
> "dt_zalloc" in "libdtrace.so.2" ==> 0x1b24efc61df0 in "libdtrace.so.2"
> "pthread_mutex_init" in "libdtrace.so.2" ==> 0x1b24edf165d0 in "libc.so.7"
> "pthread_cond_init" in "libdtrace.so.2" ==> 0x1b24edf163d0 in "libc.so.7"
> "strdup" in "libdtrace.so.2" ==> 0x1b1cc46ed5a0 in "mdb"
> "malloc" in "libdtrace.so.2" ==> 0x1b24edffc370 in "libc.so.7"
>
> (lots of output skipped)
>
> "dt_idstack_push" in "libdtrace.so.2" ==> 0x1b24efc360c0 in "libdtrace.so.2"
> "dt_irlist_create" in "libdtrace.so.2" ==> 0x1b24efc1b240 in "libdtrace.so.2"
> "yyinit" in "libdtrace.so.2" ==> 0x1b24efc3b030 in "libdtrace.so.2"
> "strlen" in "libdtrace.so.2" ==> 0x1b24edfdfc30 in "libc.so.7"
> "yybegin" in "libdtrace.so.2" ==> 0x1b24efc39b00 in "libdtrace.so.2"
> "setjmp" in "libdtrace.so.2" ==> 0x1b24edf3ede0 in "libc.so.7"
> "yyparse" in "libdtrace.so.2" ==> 0x1b1cc46fe300 in "mdb"
>
> The last line is what causes the trouble.
> It's interesting that yyinit and yybegin were resolved correctly... ah, but
> there are no such symbols in the main binary.
>
> Additional info:
>
> $ nm -D /usr/local/bin/mdb | grep yyparse
> 00000000000b6300 T yyparse
>
> $ nm -D /usr/local/lib/mdb/kvm/amd64/dtrace.so| grep yyparse
> $
>
> $ nm -D /lib/libdtrace.so.2 | grep yyparse
> 0000000000066460 T yyparse
>
> $ nm -D /usr/local/bin/mdb | grep yybegin
> $
>
>
--
Andriy Gapon