What is the version number field in the output of the linux file command
Asked Answered
D

2

6

If I do the following command on my executable called "version", compiled on Fedora Core 11, I get this output

file version

version: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.18, not stripped

What's the significance of the 2.6.18 number towards the end, and is it any use in distinguishing to customers which version of some software they should download ?

From what I've looked at so far, this number is definitely not

  1. The kernel version
  2. The libc version
  3. Anything to do with the lsb_release

I'd like to get some easy identifier to allow customers to know which binary release they should download, which they should ideally be able to identify by typing a command (like uname -a, although that obviously isn't the one in this case).

Thanks

Deuteron answered 25/1, 2010 at 16:37 Comment(0)
T
7

It's the kernel version of the machine the binary was compiled on. If you use precompiled binaries from your distribution, it's the kernel version of a machine of the distribution vendor, probably in its compile farm.

It's relevant e.g. when considering syscalls. Say your binary uses the syscall no. X and you use a kernel which does not support X yet or worse has assigned syscall no. X to a different syscall.

The vanilla Linux Kernel User API is stable. That means every syscall available in Linux version A is available in Linux version B if A <=B. But it may happen that some developer releases his/her own development version of Linux (something like linux-2.6.18-xy) and s/he implements a new syscall. If s/he now compiles a binary using that kernel version, the binary gets tagged with that version. So, you are later on able to know that it may or may not work.

Btw, /usr/include/asm/unistd_32.h contains syscall numbers, excerpt:

[...]
#define __NR_restart_syscall      0
#define __NR_exit         1
#define __NR_fork         2
#define __NR_read         3
#define __NR_write        4
#define __NR_open         5
[...]
Telephoto answered 25/1, 2010 at 16:40 Comment(5)
Thanks - so effectively, the minimum kernel version that has binary compatibility with the executable ? I discounted a kernel version initially as a user space program only "depends" (like ldd output) on libc.so, but I can see the link there.Deuteron
You could say so. The real truth is a bit more subtile: Not every kernel version brings new syscalls AND in normal programs you use syscall wrappers from libc. So the numbers are not hardcoded in the program itself but in libc. But IF a kernel invented a new syscall, your program depends on it, you can't execute that program on a older kernel...Telephoto
Yes - that's what I was thinking - as a userspace program, I don't care about the kernel - only libc. But of course, libc must care about the kernel, since it bridges user space with the kernel. So, really, the number is the kernel version that libc was compiled against, which comes from the vendor (Fedora in this case). Thanks for your timeDeuteron
@JohannesWeiß You say that "every syscall available in Linux version A is available in Linux version B if A <= B". But I have an executable that was compiled on GNU/Linux 2.6 that will not run on GNU/Linux 3.2. I believe this is the point of Linux Standard Base, is it not?Raincoat
@JonathanMee , the Kernel's user land interface should be stable in Linux (en.wikipedia.org/wiki/Linux_kernel_interfaces). LSB specifies that as well and a lot more. But still, there's no guarantee that every binary will run on a newer version but the syscall should generally be available.Telephoto
P
0

The kernel version shown in the "file" command output is taken from an ELF (the common executable file format on Linux) section called ".note.ABI-tag". It is defined not by the kernel, but the GNU libc the program is compiled on.

The number here defines the Linux kernel API level (the supported syscalls) the C library expects at a minimum and is defined in the .note.ABI-tag section in crt1.o, the startup object statically linked into every executable. For details, see its specification.

While Johannes Weiss is generally right that API is stable (and backward compatible), new interfaces that deliver new features are regularly implemented. The newest major one (as of 2024) would be the 64-bit time API for 32-bit systems (e.g. ARM 32), introduced in Linux kernel 5.15.0 and utilised with GNU libc 2.34 and newer, which will be needed after we hit 2^31 seconds of UNIX time in 2038.

Puberty answered 10/5 at 16:47 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.