[Solved] Dlopen(): Dynamic loading not supported

Hello, I was trying to build some custom software and encountered problem with dlopen().

Here is minimalistic example:

#include <stdio.h>
#include <dlfcn.h>
int main(void)
{
    printf("Hello\n");
    void *dll = dlopen(NULL, RTLD_LAZY);
    if (NULL == dll)
        printf("dlopen(): %s\n", dlerror());
    printf("Goodbye\n");
}

On host machine:

@HP-Laptop ~/openwrt $ LANG=C git branch 
* (HEAD detached at v21.02.3)
  master

Example compiled with

arm-openwrt-linux-gcc dll.c -static -ldl -o dll

On target machine:

BusyBox v1.30.1 (2021-06-07 15:40:37 MSK) built-in shell (ash)

###############################
>    TELEOFIS LT40 va2.0.8    <
###############################

root@LT40:~# 
root@LT40:~# 
root@LT40:~# ./dll 
Hello
dlopen(): Dynamic loading not supported
Goodbye
root@LT40:~# 
root@LT40:~# 
root@LT40:~# uname -a
Linux LT40 3.18.20 #1 PREEMPT Mon Jun 7 15:39:25 MSK 2021 armv7l GNU/Linux

So the question is why dlopen does not work for me?
Is there some way to fix this?

Chaos Calmer?
It's time to upgrade...

1 Like

Did you mean that ''dynamic loading not supported" by the kernel in my particular case?

1 Like

So much has changed in seven years, including the standard C library and multiple major toolchain and kernel versions, that no one wants to look back to the old times (a version that has been EOL for over half a decade).

1 Like

No, I meant you're 6 years or so behind the current release.

Actually, not exactly me but manufacturer of that router :slight_smile:
It just has happened I had this device around the corner and tried to compile some progs for it.

Ok, I got it. Thanks for the answers.

Then you should really ask them, manufacturer fw are openwrt based, but black boxes for the openwrt community, and the rest of the world.

Another option is to check if it's supported, or make it supported.

I see. They have some customized version here at github,
but it failed to build on my host system and then I took latest (non-rc) official release (hence static linking, except explicit dlopen() of course).

wait...

a@HP-Laptop ~/openwrt $ LANG=C git branch 
* (HEAD detached at v21.02.3)
  master

and

@HP-Laptop ~/openwrt $ grep -rIi "Dynamic loading not supported"
build_dir/toolchain-arm_arm926ej-s_gcc-8.4.0_musl_eabi/musl-1.1.24/src/ldso/dlopen.c:	__dl_seterr("Dynamic loading not supported");

Does that mean that musl libc does not implement wrapper for dlopen() syscall?..

Your toolchain uses musl libc. Statically linked programs using musl libc do not support dlopen(). (See also https://www.openwall.com/lists/musl/2012/12/08/4)

You will need to build a toolchain matching the target system's libc (musl, glibc or uclibc) and link your executable dynamically.

1 Like

This is the answer I needed! Thanks a lot!

Yes, I know that dynamical linking requires matching toolchains but this is another story. The issue actually is not so urgent for me, at the moment I just wanted to have clear understanding why it is happening like this.

Although I've already marked the topic as solved, let me make one note.
It's appeared I did not have to mess around with BuildRoot at all.
Linux MInt distro has gcc-7-multilib-arm-linux-gnueabi package and this
toolchain did the job right.

Compile at host:

arm-linux-gnueabi-gcc-7 dll.c -ldl -odll
$ file dll
dll: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV),
dynamically linked, interpreter /lib/ld-linux.so.3, for GNU/Linux 3.2.0,
BuildID[sha1]=26a880514567c06814a6b2cf4f2274f63e62d5e9, not stripped

Run on target

@LT40:~# ./dll 
Hello
Goodbye

Now dlopen() works.

1 Like

This topic was automatically closed 10 days after the last reply. New replies are no longer allowed.