What is the SO file format?
A .so file contains a dynamically-loaded shared library for Unix and Linux applications. .so is a binary file used to provide access to shared code and data that one or more programs can use when launched. The extension stands for Shared Object, reflecting the fact that once the library is loaded into memory its objects - functions and data - can be accessed by multiple processes simultaneously. The MIME type registered for .so files is application/x-sharedlib.
.so libraries are ELF objects (short for Executable and Linkable Format), the standard binary format used across Linux and many Unix-like systems for executables, compiled objects, shared libraries, and core dumps. Every valid ELF file - including .so files - begins with the four-byte magic number \x7FELF at offset 0. The file structure comprises:
- ELF header - defines architecture, endianness, and bitness (32-bit or 64-bit), plus the counts of entries in the segment and section tables,
- Program header table - describes memory segments used at load time,
- Section header table - describes individual sections used by the linker and debugger,
- Data referenced by those headers.
Segments are used during program execution and may be composed of multiple sections; sections are used during the linking operation. .so files can be linked into a program at compile time or loaded at runtime via dlopen().
.so filenames follow a naming convention where the library name is preceded by a lib prefix - for example, a library named abc will have the filename libabc.so, and the -labc flag is used when linking against it. The .so suffix may be followed by a version number, such as libabc.so.3 for the major-version file or libabc.so.3.1.2 for a fully versioned build. In practice, libabc.so is often only a symbolic link pointing to the real versioned file, and libabc.so.3 may itself be a symlink to the most recent compatible release. The version stored in the DT_SONAME dynamic entry is what the runtime linker ld.so records and checks. Some low-level system libraries - such as ld.so itself - do not follow the lib prefix convention.
On Windows the equivalent concept is a .DLL file; on macOS it is a .dylib file. Static alternatives on Linux are archived in .a files.
Security & safety
RISK: MEDIUMA .so is executable native code that runs inside whatever process loads it, so a malicious shared library can do anything the host program can. The real risks: (1) library hijacking - a rogue .so placed where the loader searches first, or LD_PRELOAD/LD_LIBRARY_PATH abuse, can inject code into a legitimate program; (2) downloading individual .so files from random websites to fix an error - these may be malicious or ABI-incompatible and can break or compromise the system. Always install libraries from your distribution's signed package repositories. Deleting system .so files (in /lib, /usr/lib) can render the OS or apps unbootable.
Format details
in a nutshellPrograms that open SO files
Technical details
deep spec| MIME type | application/x-sharedlib |
| Magic bytes | 7F 45 4C 46 ("\x7FELF") at file offset 0 - identical magic to all ELF files; the e_type field distinguishes shared objects |
| ELF e_type value | ET_DYN (0x0003) - distinguishes a shared object from an executable (ET_EXEC = 0x0002) or relocatable object (ET_REL = 0x0001) |
| Bitness | EI_CLASS byte at offset 4: 1 = 32-bit (Elf32), 2 = 64-bit (Elf64); both variants are widely deployed on Linux |
| Endianness | EI_DATA byte at offset 5: 1 = little-endian (ELFDATA2LSB), 2 = big-endian (ELFDATA2MSB); architecture-specific |
| Position-independent code | Must be compiled with -fPIC so the library can be mapped to any virtual address without relocation conflicts between processes |
| Dynamic symbol table | .dynsym section exports and imports symbols visible at runtime; .dynstr holds the corresponding name strings |
| PLT / GOT | Procedure Linkage Table and Global Offset Table enable lazy (default) or eager (-z now) symbol resolution at load time |
| soname (DT_SONAME) | Canonical library name embedded in the ELF dynamic section; ld.so records this name when a program is linked, enabling ABI-version tracking independent of filename |
| Symbol versioning | .gnu.version and .gnu.version_r sections allow multiple symbol versions within one file, enabling backward-compatible ABI evolution |
| Runtime linker | Loaded by ld.so / ld-linux-x86-64.so.2; search path controlled by LD_LIBRARY_PATH, DT_RUNPATH, or /etc/ld.so.conf + ldconfig cache |
| Naming convention | lib<name>.so[.major[.minor.patch]]; libabc.so is typically a development symlink → libabc.so.3 → libabc.so.3.1.2 |
| Embedded search path | DT_RPATH or DT_RUNPATH dynamic entries bake library search paths into the file at link time; DT_RUNPATH is preferred as it can be overridden by LD_LIBRARY_PATH |
| Inspection tools | readelf -a, objdump -d, nm --dynamic (binutils); ldd for dependency listing; file command identifies ELF type and architecture |
| Released | ELF format 1990s (System V Release 4); .so shared libraries are core to Linux/Unix |
| Open standard | Yes · royalty-free |
| Specification | refspecs.linuxfoundation.org |
SO conversions
Community Q&A
asked by usersNo questions yet - be the first to ask about SO files.