glibc: elf file OS ABI invalid - linux

downloaded and compiled glibc-2.13. when i try to run a sample C program which does a malloc(). I get following error
elf file OS ABI invalid
Can anybody please pass my any pointer helpful in resolving this issue.Please note that my kernel version is linux-2.6.35.9

It's not your kernel version that's the problem.
The loader on your system does not support the new Linux ABI. Until relatively recently, Linux ELF binaries used the System V ABI. Recently, in support of STT_GNU_IFUNC, the Linux ABI was added. You would have to update your system C library to have a loader that support STT_GNU_IFUNC, and then it will also recognize ELF objects with the Linux ABI type.
See Dave Miller's blog entry on STT_GNU_IFUNC for Sparc (archived) to gain an understanding of what STT_GNU_IFUNC does, if you care.

If you get your hands in the loader from a newer system, you might be able to make it work using that. But you'll have to carry the loader wherever your program go. You can either compile your program to use that loader as explained here, or compile your program and patch it later using patchelf, in a way similar to what I mention here. I was able to run a program that was giving me the OS ABI invalid error on a linux 2.6.18 (older than yours) that had ld-2.5.so, by copying a ld-2.15.so from somewhere else.
NOTE: do NOT overwrite your system ld*.so or ld-linux. ;-/

It is possible your glibc was built with the --enable-multiarch flag that forced using ifunc and new LINUX ABI

From what I can tell is that --enable-multiarch is the default setting and you should disable it by setting --enable-multiarch=no.

Related

Kernel module compatibility with kernel recompiled with new patch

I would like to know if a Linux Kernel Module can be used with a Linux Kernel version of a higher patch number (last number in the version) than the kernel was compiled against.
Take the following example:
You are currently using Linux 4.14.75 for an ARM target
I give you an RPM containing an application and kernel module that work together. The module was compiled against the 4.14.75 kernel. The module is loaded with insmod by the application.
A security concern arises and you update your target's kernel to 4.14.100.
Given this situation, will the kernel module in the RPM I gave you work with the new kernel?Is it possible to compile a kernel once and have it be compatible with all 4.14 kernels?
I am NOT asking if depmod/modprobe will work or if it is good practice.
"Is it possible to compile a kernel once and have it be compatible with all 4.14 kernels?"
If security updates and backports do not break anything, maybe.
However there is no stable Kernel API/ABI in the Kernel.
Just userland API/ABIs are stable.
https://www.phoronix.com/scan.php?page=news_item&px=Linux-Kernel-Stable-API-ABI
https://github.com/torvalds/linux/blob/master/Documentation/process/stable-api-nonsense.rst
Here a post to automatically check, if any API/ABI to userland will break/breaks:
Linux kernel API changes/additions
For Kernel ABI I found a tool for that (and your use case):
https://developers.redhat.com/blog/2018/03/28/analyzing-binary-interface-changes-linux-kernel/

Get kernel version | Linux kernel API [duplicate]

how can I obtain runtime information about which version of kernel is running from inside linux kernel module code (kernel mode)?
By convention, Linux kernel module loading mechanism doesn't allow loading modules that were not compiled against the running kernel, so the "running kernel" you are referring to is most likely is already known at kernel module compilation time.
For retrieving the version string constant, older versions require you to include <linux/version.h>, others <linux/utsrelease.h>, and newer ones <generated/utsrelease.h>. If you really want to get more information at run-time, then utsname() function from linux/utsname.h is the most standard run-time interface.
The implementation of the virtual /proc/version procfs node uses utsname()->release.
If you want to condition the code based on kernel version in compile time, you can use a preprocessor block such as:
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,16)
...
#else
...
#endif
It allows you to compare against major/minor versions.
You can only safely build a module for any one kernel version at a time. This means that asking from a module at runtime is redundant.
You can find this out at build time, by looking at the value of UTS_RELEASE in recent kernels this is in <generated/utsrelease.h> amongst other ways of doing this.
Why can't I build a kernel module for any version?
Because the kernel module API is unstable by design as explained in the kernel tree at: Documentation/stable_api_nonsense.txt. The summary reads:
Executive Summary
-----------------
You think you want a stable kernel interface, but you really do not, and
you don't even know it. What you want is a stable running driver, and
you get that only if your driver is in the main kernel tree. You also
get lots of other good benefits if your driver is in the main kernel
tree, all of which has made Linux into such a strong, stable, and mature
operating system which is the reason you are using it in the first
place.
See also: How to build a Linux kernel module so that it is compatible with all kernel releases?
How to do it at compile time was asked at: Is there a macro definition to check the Linux kernel version?

ARMv8 - Running legacy 32 bit Applications on 64 bit OS

Going thru the ARMv8 manual, I have the following questions to help understand the big picture.
Can legacy 32 bit app. (ARMv7 or earlier) run as is on the ARMv8 OS?
If the legacy applications need to be rebuilt for ARMv8 and assuming that I rebuild the application as 32 bit (Aarch32), does this need 32 bit OS underlying support? (It is interesting to know how the addressing mechanism works here.)
Please provide references wherever possible.
PS: I am targeting Linux OS with Aarch64 support (3.7 and later)
Aarch64 platform may run 32bit ARM but this compatibility is optional.
To run AArch32 binaries you need all libraries application would use in 32bit versions. Same as with i686 binaries on x86-64 systems.
There is also a Linux arm64 CONFIG_COMPAT at: https://github.com/torvalds/linux/blob/v4.17/arch/arm64/Kconfig#L1274 which says:
This option enables support for a 32-bit EL0 running under a 64-bit
kernel at EL1. AArch32-specific components such as system calls,
the user helper functions, VFP support and the ptrace interface are
handled appropriately by the kernel.
which will likely be required, and an ARM employee mentioned on this thread: https://community.arm.com/processors/f/discussions/5535/running-armv7-binaries-on-armv8 that userland instructions are basically the same with some exceptions:
For something like a Linux application, then yes. ARMv8-A includes AArch32, which provides backwards compatibility with ARMv7-A. There are some limitations, such as the SWP instruction no longer being supported. But these are types of things that applications are unlikely to be using (and were deprecated in ARMv7).
For baremetal, you have all the usual problems of using a binary from one platform on another. So you are going to need to do some degree of porting in most cases.
I then tried it for myself with this QEMU full system setup but my attempt failed: I compiled a C hello world with the armv7 compiler as:
arm-linux-gcc -static hello_world.c
and put the built file into the aarch64 target, but when I tried to run it it failed with:
a.out: line 1: syntax error: unexpected word (expecting ")")
even though /proc/config.gz says that CONFIG_COMPAT is set.
It seems that the Linux kernel is not identifying it as an ELF file but rather falling back to /bin/sh, I get the same error if I do:
sh /mnt/9p/a.out
is trying to use the shell binfmt instead of ELF.
In particular, I know that the Linux kernel can choose between archs from the binfmt signature because qemu-user does so: https://unix.stackexchange.com/questions/41889/how-can-i-chroot-into-a-filesystem-with-a-different-architechture

symbols in kernel module

I built linux kernel module with SSP support for mips architecture. I added -fstack-protector-all to compilation flags. But after loading this module I've got undefined references to __stack_chk_guard and __stack_chk_fail. But I added libssp.so to linker. It looks like I should export those symbols in kernel something like this:
EXPORT_SYMBOL(__stack_chk_guard);
Because my kernel is old and didn't contain them yet. But unfortunately I should use this version.
My question is: why user space can use this symbols from toolchain library, but kernel space don't ?
I think, I missed some linux kernel essentials.
You can't link the kernel to shared libraries. If you have a static library of libssp, it MAY work - but it would require that the library isn't calling something else that would cause problems in the kernel.
In general, stack-checking isn't something that you should be doing on the kernel - I'm pretty sure it serves no particularly good purpose [I'm also pretty sure that the kernel uses a "guard page" for each kernel stack].
You cannot use shared libraries anywhere in kernel space (including as part of kernel modules).
You could think of kernel modules themselves as an equivalent of shared libraries in kernel space but with lot of differences.
Kernel modules can depend on exported symbols from other kernel modules.
My question is: why user space can use this symbols from toolchain
library, but kernel space don't ?
Nothing in kernel space has access to the libc C library. Kernel has its own set of builtin standard string manipulation functions, etc. that you could use instead. The toolchain libraries are built on top of libc.
+1 on Mats's answer. You could use a static library as long as it does not depend on standard C libraries like libc

compiling linux kernel with non-gcc

Linux kernel is written for compiling with gcc and uses a lot of small and ugly gcc-hacks.
Which compilers can compile linux kernel except gcc?
The one, which can, is the Intel Compiler. What minimal version of it is needed for kernel compiling?
There also was a Tiny C compiler, but it was able to compile only reduced and specially edited version of the kernel.
Is there other compilers capable of building kernel?
An outdatet information: you need to patch the kernel in order to compile using the Intel CC
Download Linux kernel patch for IntelĀ® Compiler
See also Is it possible to compile Linux kernel with something other than gcc for further links and information
On of the most recent sources :http://forums.fedoraforum.org/showthread.php?p=1328718
There is ongoing process of committing LLVMLinux patches into vanilla kernel (2013-2014).
The LLVMLinux is project by The Linux Foundation: http://llvm.linuxfoundation.org/ to enable vanilla kernel to be built with LLVM. Lot of patches are prepared by Behan Webster, who is LLVMLinux project lead.
There is LWN article about the project from May 2013
https://lwn.net/Articles/549203/ "LFCS: The LLVMLinux project"
Current status of LLVMLinux project is tracked at page http://llvm.linuxfoundation.org/index.php/Bugs#Linux_Kernel_Issues
Things (basically gcc-isms) already eliminated from kernel:
* Expicit Registers Variables (non-C99)
* VLAIS (non C99-compliant undocumented GCC feature "Variable length arrays in structs") like struct S { int array[N];} or even struct S { int array[N]; int array_usb_gadget[M]; } where N and M are non-constant function argument
* Nested Functions (Ada feature ported into C by GCC/Gnat developers; not allowed in C99)
* Some gcc/gas magic like special segments, or macro
Things to be done:
* Usage of __builtin_constant_p builtin to implement scary magic like BUILD_BUG_ON(!__builtin_constant_p(offset));
The good news about LLVMLinux are that after its patches kernel not only becomes buildable with LLVM+clang, but also easier to build by other non-GCC compilers, because the project kills much not C99 code like VLAIS, created by usb gadget author, by netfilter hackers, and by crypto subsystem hackers; also nested functions are killed.
In short, you cannot, because the kernel code was written to take advantage of the gcc's compiler semantics...and between the kernel and the compiled code, the relationship is a very strong one, i.e. must be compiled with gcc...Since gcc uses 'ELF' (Embedded Linking Format) object files, the kernel must be built using the object code format. Unless you can hack it up to work with another compiler - it may well compile but may not work, as the compilers under Windows produces PE code, there could be unexpected results, meaning the kernel may not boot at all!

Resources