How to upload two .so which are depended on each other

Indeed, this is not supported.

but if i am running GCC built main program which will load these two .so,
then i run cling and .L two .so, might it work?

i have other problem to run the main program, so currently i can’t test above idea.

Thanks
Xinghao Chen

If you really, really, really cannot solve the problem in a proper way, you may try to use a brutal fix: circular_dependency.tar.gz (808 Bytes)

Wile_E,

Thanks for your reply, i built the “joint .so” via linking of the two circular .so as your suggested, (i don’t follow -Wl,-rpath,’${ORIGIN}’, but directly link the two .so with absolute path and lib name)
however when i .L the “joint .so” from the cling shell, seems the dependent two .so are not loaded automatically,
then when i call APIs, it still report undefined symbols,

‘xxxxx’ unresolved while linking [cling interface function]!

Thanks
Xinghao Chen

i used LD_LIBRARY_PATH, instead of rpath,
but i am sure the .so can be load correctly.

so the problem is why when i load the “joint” .so, the linked .so are not loaded automatically.

ldd libtestScript.so
linux-vdso.so.1 (0x00007ffff7ffa000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007ffff77e2000)
/lib64/ld-linux-x86-64.so.2 (0x00007ffff7dd5000)

doesn’t show the dependency of the two .so (named libcpss.so and libhelper.so)

the generated map shows ld trying to load the two .so.
Linker script and memory map

LOAD /usr/lib/gcc/x86_64-linux-gnu/7/…/…/…/x86_64-linux-gnu/crti.o
LOAD /usr/lib/gcc/x86_64-linux-gnu/7/crtbeginS.o
LOAD compilation_root/cpss_4.2/sim64_DX_SHARED/cpssEnabler/libs/TESTSCRIPT.a
LOAD compilation_root/cpss_4.2/sim64_DX_SHARED/libcpss.so
LOAD compilation_root/cpss_4.2/sim64_DX_SHARED/libhelper.so
LOAD /usr/lib/gcc/x86_64-linux-gnu/7/libgcc.a
LOAD /usr/lib/gcc/x86_64-linux-gnu/7/libgcc_s.so

Thanks
Xinghao Chen

In your last post, I cannot see any files that I provided. Please try my “brutal fix” without any modifications.

BTW. Maybe you again face problems related to C versus C++ libraries’ building.

HI Wile_E,

it’s working now,
i am taking your concept to link the two .so to a "joint .so, so i don’t follow exactly the example you show me.

previously it is not working because the joint .so doesn’t have a API call to the two .so, it’s dummy.
after i have a API in the joint to call the two .so, it works.

Thanks a lot for your help. Cheers.
Xinghao Chen.

ldd libtestScript.so
linux-vdso.so.1 (0x00007ffff7ffa000)
libcpss.so => ./libcpss.so (0x00007ffff0c70000)

  •    libhelper.so => ./libhelper.so (0x00007fffacc70000)*
      libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fffac87f000)
      /lib64/ld-linux-x86-64.so.2 (0x00007ffff7dd5000)

Hi Wile_E

still has some problems with your proposal (brutal fix),

in my program, two so has to be loaded into a fixed virtual address,
it’s done by the ld script,
SECTIONS
{
/* Code section, access rights RX */
. = 0x14600000;

}
the elf program linked with these two .so, we can see the two so indeed were loaded into the expected fixed address,

ldd ./appDemo
linux-vdso.so.1 => (0x0000ffff917ec000)
> libcpss.so => ./libcpss.so (0x0000000010000000)

** libhelper.so => ./libhelper.so (0x0000000014600000)**
libpthread.so.0 => /lib/aarch64-linux-gnu/libpthread.so.0 (0x0000ffff917b5000)
librt.so.1 => /lib/aarch64-linux-gnu/librt.so.1 (0x0000ffff9179d000)
libdl.so.2 => /lib/aarch64-linux-gnu/libdl.so.2 (0x0000ffff91789000)
libm.so.6 => /lib/aarch64-linux-gnu/libm.so.6 (0x0000ffff916d7000)
libc.so.6 => /lib/aarch64-linux-gnu/libc.so.6 (0x0000ffff91583000)
/lib/ld-linux-aarch64.so.1 (0x0000aaaadd94f000)

however, the “joint” so that linking these two so, seems not able to load these two so into proper fixed address, see below -

ldd ./libtestScript.so
linux-vdso.so.1 => (0x0000ffff8d87c000)
> libcpss.so => ./libcpss.so (0x0000ffff89d50000)

** libhelper.so => ./libhelper.so (0x0000ffff5e350000)**
libpthread.so.0 => /lib/aarch64-linux-gnu/libpthread.so.0 (0x0000ffff5e31c000)
librt.so.1 => /lib/aarch64-linux-gnu/librt.so.1 (0x0000ffff5e304000)
libdl.so.2 => /lib/aarch64-linux-gnu/libdl.so.2 (0x0000ffff5e2f0000)
libm.so.6 => /lib/aarch64-linux-gnu/libm.so.6 (0x0000ffff5e23e000)
libc.so.6 => /lib/aarch64-linux-gnu/libc.so.6 (0x0000ffff5e0ea000)
/lib/ld-linux-aarch64.so.1 (0x0000aaaae0958000)

do i missed any LD flags during building of the “joint” so ?
i saw the only difference between elf main program and “joint” so is the flag of “-shared”, so why “joint” so missed the info of the dependent two so’s loading address?

i appreciate if you can help me out.
Best regards
Xinghao Chen

Hi Wile_E
sorry to bother you again.

i fixed the “so” issue in above, by adding flag of -Wl,-Ttext-segment=0xXXXXXXXX(e.g. 0x70000000),

according to ldd , the dependent two “so” indeed are fixing on the pre-defined VA.
ldd libtestScript.so
linux-vdso.so.1 (0x0000007fa6f04000)
libcpss.so => ./libcpss.so (0x0000000010000000)
libhelper.so => ./libhelper.so (0x0000000014600000)
libpthread.so.0 => /lib/aarch64-linux-gnu/libpthread.so.0 (0x0000007fa6ece000)
librt.so.1 => /lib/aarch64-linux-gnu/librt.so.1 (0x0000007fa6eb7000)
libdl.so.2 => /lib/aarch64-linux-gnu/libdl.so.2 (0x0000007fa6ea2000)
libm.so.6 => /lib/aarch64-linux-gnu/libm.so.6 (0x0000007fa6de6000)
libc.so.6 => /lib/aarch64-linux-gnu/libc.so.6 (0x0000007fa6c8d000)
/lib/ld-linux-aarch64.so.1 (0x0000005565c4c000)

But, but
when i load libtestScript.so via cling,
either by .L libtestScript.so or #pragma cling load(“libtestScript.so”)
it shows that the two “so” are loaded randomly, instead of into the pre-defined address.

so does cling load “so” differently than “ld.so” ?

Thanks
Xinghao Chen

AFAIK, you cannot enforce a specific fixed address when loading libraries on demand at runtime (e.g. this address may already be used by another library which has been loaded earlier).

I think, you would need to recreate the main “${ROOTSYS}/bin/root.exe” executable (or the “cling” executable, if you use it), explicitly linking it against your special library and using your special ld script.

HI Wile_E

thanks for your reply.
i just want to understand the behavior difference in Cling and ld.so, how cling to load a “.so”? doesn’t it look on the ELF header if it’s asked to be loaded into a fixed address?

see below:
i) readelf -h ./libtestScript.so
according to link script, libtestScript.so supposed to be loaded into fixed address 0x70000000

Magic:   7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00 
Class:                             ELF64
Data:                              2's complement, little endian
Version:                           1 (current)
OS/ABI:                            UNIX - System V
ABI Version:                       0
Type:                              DYN (Shared object file)
Machine:                           AArch64
Version:                           0x1
Entry point address:               0x70000840
Start of program headers:          64 (bytes into file)
Start of section headers:          7248 (bytes into file)
Flags:                             0x0
Size of this header:               64 (bytes)
Size of program headers:           56 (bytes)
Number of program headers:         6
Size of section headers:           64 (bytes)
Number of section headers:         28
Section header string table index: 25

ii) LD_DEBUG=all /lib/ld-linux-aarch64.so.1 ./libtestScript.so

  2627:     file=./libtestScript.so [0];  generating link map
  2627:       dynamic: 0x0000000070010cc0  base: 0x0000000000000000   size:  
         0x0000000000010f70
  2627:         entry: 0x0000000070000840  phdr: 0x0000000070000040  phnum:  
             6

  2627:       trying file=./libcpss.so
  2627:
  2627:     file=libcpss.so [0];  generating link map
  2627:       dynamic: 0x00000000111f0a60  base: 0x0000000000000000   size:  
  0x0000000003b187b8
  2627:         entry: 0x0000000010302708  phdr: 0x0000007faafd75f0  phnum:  
             7

  2627:       trying file=./libhelper.so
  2627:    
  2627:     file=libhelper.so [0];  generating link map
  2627:       dynamic: 0x000000001462aba0  base: 0x0000000000000000   size:  
0x000000002b9ff004
  2627:         entry: 0x0000000014607ad8  phdr: 0x0000007faafd7cc0  phnum:  
             8

iii) LD_DEBUG=all cling -ltestScript

  2681:     file=./libtestScript.so [0];  dynamically loaded by cling [0]
  2681:     file=./libtestScript.so [0];  generating link map
  2681:       dynamic: 0x0000007fac08ecc0  base: 0x0000007f3c07e000   size: 0x0000000000010f70
  2681:         entry: 0x0000007fac07e840  phdr: 0x0000007fac07e040  phnum:                  6
  2681:

  2681:       trying file=./libcpss.so
  2681:
  2681:     file=libcpss.so [0];  generating link map
  2681:       dynamic: 0x0000007fa9755a60  base: 0x0000007f98565000   size: 0x0000000003b187b8
  2681:         entry: 0x0000007fa8867708  phdr: 0x00000055a8c48af0  phnum:                  7
  2681:
  2681:

  2681:       trying file=./libhelper.so
  2681:    
  2681:     file=libhelper.so [0];  generating link map
  2681:       dynamic: 0x0000007f7cb8fba0  base: 0x0000007f68565000   size: 0x000000002b9ff004
  2681:         entry: 0x0000007f7cb6cad8  phdr: 0x00000055a8e0d720  phnum:                  8
  2681:

Try: LD_PRELOAD=libtestScript.so cling

Wile_E,
Thanks a lot, i tried but it didn’t help.
LD_PRELOAD just assign the priority of lib looking path,
but didn’t change the behavior of loading so to be dynamic or fixed.

ld.so should read “.so” ELF info and load dynamic or fixed accordingly (according to the link script during the generation of “.so”)

but cling always load “.so” dynamically?

indeed it tries to load libtestScript.so at very beginning (before loading all other “.so”) .

LD_DEBUG=all LD_PRELOAD=./libtestScript.so cling

  5528:     WARNING: Unsupported flag value(s) of 0x8000000 in DT_FLAGS_1.
  5528:
  5528:     file=./libtestScript.so [0];  needed by cling [0]
  5528:     file=./libtestScript.so [0];  generating link map
  5528:       dynamic: 0x0000007f9f8d5cc0  base: 0x0000007f2f8c5000   size: 0x0000000000010f70
  5528:         entry: 0x0000007f9f8c5840  phdr: 0x0000007f9f8c5040  phnum:                  6
  5528:
  5528:

LD_DEBUG=all LD_PRELOAD=./libtestScript.so ./appDemo

  5728:
  5728:     file=./libtestScript.so [0];  needed by ./appDemo [0]
  5728:     file=./libtestScript.so [0];  generating link map
  5728:       dynamic: 0x0000000070010cc0  base: 0x0000000000000000   size: 0x0000000000010f70
  5728:         entry: 0x0000000070000840  phdr: 0x0000000070000040  phnum:                  6
  5728:

might some differences(LDFLAGS -nocopyreloc -rdynamic?) during the generation of cling or my program (appDemo)?

/home/ericxh/work/toolchain/gcc-5.2.1-16.02.0-armv8/armv8/le/aarch64v8-
marvell-linux-gnu-5.2.1_i686_20151110/bin/aarch64-none-linux-gnu-gcc -Xlinker
–whole-archive
compilation_root/cpss_4.2/armv8_DX_SHARED/referenceCode/libs/REFERENCECODE.a


compilation_root/cpss_4.2/armv8_DX_SHARED/cpssEnabler/libs/CPSSAPPREF.a
compilation_root/cpss_4.2/armv8_DX_SHARED/version_info.o -Xlinker --no-whole-
archive \ compilation_root/cpss_4.2/armv8_DX_SHARED/libcpss.so
compilation_root/cpss_4.2/armv8_DX_SHARED/libhelper.so -Xlinker -z -Xlinker
nocopyreloc -rdynamic -lpthread -lrt -ldl -lm -Xlinker -Map -Xlinker
compilation_root/cpss_4.2/armv8_DX_SHARED/appDemo.map -o
compilation_root/cpss_4.2/armv8_DX_SHARED/appDemo

via command of:
LD_FLAG=all LD_PRELOAD=libtestScript.so XXXX

XXXX - different programs,
my own program - appDemo, ld.so when pre-load libtestScript.so, it can load it to a pre-defined fixed address,

while cling or many other programs can’t (still dynamically).

hints, for the programs can’t do fixed loading all show below warning, i am not sure whether it’s relevant.

WARNING: Unsupported flag value(s) of 0x8000000 in DT_FLAGS_1.

cling uses dlopen to load your library.

Please hand in a pull request if there is something you’d like to see improved on cling’s side. Your use case is niche enough that you won’t find a lot of help here I’m afraid.

Cheers, Axel.

Hi Axel & Wile_E

sorry to bother you so much.
i did get valuable suggestion from you. i appreciate it very much.

eventually i might find the reason,
it’s due to different gcc i use to generate my program(via cross toolchain) and cling(via armv8 native GCC)

the main difference is the armv8 native GCC is built-in with “–enable-default-pie”,

file appDemo
appDemo: ELF 64-bit LSB executable, ARM aarch64, version 1 (SYSV), dynamically linked, interpreter /lib/ld-, for GNU/Linux 3.7.0, BuildID[sha1]=3c53df2ba4bc6b8408718d893553545f5c7b55e5, not stripped

file cling
cling: ELF 64-bit LSB shared object, ARM aarch64, version 1 (GNU/Linux), dynamically linked, interpreter /lib/ld-, for GNU/Linux 3.7.0, BuildID[sha1]=afebc34b4e2098c74ded19b2b58f039340e45578, not stripped

i believe i am very closed to the problem fix.
so the last questions – :slight_smile:

  1. can cling project support to build with cross compiler ? if yes, how to?
    now i am using native armv8 machine to build cling with target of aarch64-linux-gnu
  2. would you mind to guide me how to put “-no-pie” in the CFLAGS in the cling project?

Thanks a lot.
Xinghao Chen