2

I have a "shared object" file my.so that I tried to load in python:

from ctypes import cdll
lib = cdll.LoadLibrary("my.so")

This fails with

OSError: dlopen(my.so, 6): no suitable image found.  Did find:
my.so: unknown file type, first eight bytes: 0x7F 0x45 0x4C 0x46 0x02 0x01 0x01 0x00
/path/to/.../my.so: unknown file type, first eight bytes: 0x7F 0x45 0x4C 0x46 0x02 0x01 0x01 0x00`

Reseach into other SO questions reveals:

Python ctypes not loading dynamic library on Mac OS X

This user shares the "No suitable image." error. The reason for them was a mismatch between the architecture of the processor running python (x86_64) and the target architecture of their .so file (ARM). The way to confirm this issue is to run, from the command line:

>file my.so

This outputs ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, BuildID[sha1]=..., stripped

The focus of Error "mach-o, but wrong architecture" after installing anaconda on mac was 32-bit vs 64-bit. From python I can see that import platform;platform.architecture() gives ('64bit', '').

From a response I now can't find it was stated that this technique can be unreliable and instead to use max int size. import sys; sys.maxsixe gives 9223372036854775807 which means 64-bit.

Finally, in a blog post on ELF binaries the author gives the Python snippet import os; os.uname()[4] to give the machine architecture. For me this returns x86_64.


To sum up, cdll doesn't recognise the ELF ("unknown filetype"). The environment and binary are both 64 bit. The architectures also both match (and are x86_64).

Why is this not working as expected?

edit (credit to Max): OS running python is macOS 10.15.7 Catalina.

Robino
  • 4,530
  • 3
  • 37
  • 40
  • 1
    MacOS doesn’t use .so in ELF format, they use .dylibs in Mach-O format. It’s unclear what platform you’re using since you didn’t actually specify, but more than the architecture needs to match: the file format and system it’s compiled for need to match. – Max Aug 19 '21 at 14:06
  • But, ELF is a standard file format, ubiquitous and widely accepted since '97. Why would Apple....ah, never mind. – Robino Aug 19 '21 at 14:19
  • Well, the heritage of MacOS/Darwin is based on NextStep which is older than 1997? And MacOS was first released in 2000? So, transitioning to a new format was probably not on their mind. It’s not like Windows switched either. And even if ELF is a standard format, what’s in it is still not portable between machiens. You can’t, in general, just take a FreeBSD Elf Binary and run it on Linux either even if the architectures match (without a lot of trickery) – Max Aug 19 '21 at 14:29
  • Furthermore, MacOS is based on the Mach microkernel, so it would make sense to use Mach formats. – Max Aug 19 '21 at 14:30
  • @Max well, there goes my next idea. I was planning to run this in a a Linux VM. Is there a way to dig deeper into the ELF to see really what system it is expeting? – Robino Aug 19 '21 at 14:36
  • 1
    I’m not aware of a good way to identify the host for a system, that’s out my expertise. If it’s a purely mathematical or crypto library or similar, you might be able to get it to run on the “wrong kind” of machine. I think “identifying what system an .so was compiled for” might be a separate question (perhaps already answered on SO) – Max Aug 19 '21 at 14:44
  • 1
    I think I answered you roriginal question, so I’ll turn it into an answer. – Max Aug 19 '21 at 14:44

1 Answers1

3

MacOS doesn’t use the ELF shared object format, so it can’t be loaded by the MacOS dynamic linker. As it is based on the Mach microkernel, it continues to use the Mach-O binary format, and its shared libraries generally use the file extension .dylib.

In general, even if the architectures match and they both use ELF, you can’t use executable binaries/shared objects across different Operating Systems.

Max
  • 10,701
  • 2
  • 24
  • 48