How to use patchelf with --set-interpreter? - linux

I'm trying to do the following:
Change the libc of a simple test.c from the system default (Debian 9.11, libc-2.24.so) to libc 2.27.
This is my attempt:
user#pc:~/patchelf_test$ cat test.c
#include <stdio.h>
int main(int argc, char **argv)
{
printf("hello patchelf\n");
return 0;
}
user#pc:~/patchelf_test$ gcc test.c -o test
user#pc:~/patchelf_test$ ./test
hello patchelf
user#pc:~/patchelf_test$ ldd test
linux-vdso.so.1 (0x00007ffd9d1d8000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f7ea0290000)
/lib64/ld-linux-x86-64.so.2 (0x00007f7ea0831000)
user#pc:~/patchelf_test$ patchelf --set-interpreter ./libc6-amd64_2.27-3ubuntu1_i386.so test
warning: working around a Linux kernel bug by creating a hole of 2093056 bytes in ‘test’
user#pc:~/patchelf_test$ ldd test
linux-vdso.so.1 (0x00007fff20b9a000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fa46a35e000)
./libc6-amd64_2.27-3ubuntu1_i386.so => /lib64/ld-linux-x86-64.so.2 (0x00007fa46a900000)
user#pc:~/patchelf_test$ ./test
GNU C Library (Ubuntu GLIBC 2.27-3ubuntu1) stable release version 2.27.
Copyright (C) 2018 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.
There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE.
Compiled by GNU CC version 7.3.0.
libc ABIs: UNIQUE IFUNC
For bug reporting instructions, please see:
<https://bugs.launchpad.net/ubuntu/+source/glibc/+bugs>.
user#pc:~/patchelf_test$
The expected result here, is that it should run the actual program. Actual results, are that it runs the linker itself.
Question: How do I need to modify my command to fix this?
I've also tried to use libc6-amd64_2.27-3ubuntu1_i386.ld instead of .so:
user#pc:~/patchelf_test$ !gcc
gcc test.c -o test
user#pc:~/patchelf_test$ patchelf --set-interpreter ./libc6-amd64_2.27-3ubuntu1_i386.ld test
warning: working around a Linux kernel bug by creating a hole of 2093056 bytes in ‘test’
user#pc:~/patchelf_test$ ./test
Segmentation fault
I've also tried to use my system default libc, and patch with that, just to establish that patchelf works at all, but again I get the same problem -- it executes the linker binary itself, instead of the test binary.
user#pc:~/patchelf_test$ !gcc
gcc test.c -o test
user#pc:~/patchelf_test$ patchelf --set-interpreter ./libc_default.so test
warning: working around a Linux kernel bug by creating a hole of 2093056 bytes in ‘test’
user#pc:~/patchelf_test$ ./test
GNU C Library (Debian GLIBC 2.24-11+deb9u4) stable release version 2.24, by Roland McGrath et al.
Copyright (C) 2016 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.
There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE.
Compiled by GNU CC version 6.3.0 20170516.
Available extensions:
crypt add-on version 2.1 by Michael Glad and others
GNU Libidn by Simon Josefsson
Native POSIX Threads Library by Ulrich Drepper et al
BIND-8.2.3-T5B
libc ABIs: UNIQUE IFUNC
For bug reporting instructions, please see:
<http://www.debian.org/Bugs/>.
strace:
$ strace ./test
execve("./test", ["./test"], [/* 44 vars */]) = 0
write(1, "GNU C Library (Debian GLIBC 2.24"..., 616GNU C Library (Debian GLIBC 2.24-11+deb9u4) stable release version 2.24, by Roland McGrath et al.
Copyright (C) 2016 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.
There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE.
Compiled by GNU CC version 6.3.0 20170516.
Available extensions:
crypt add-on version 2.1 by Michael Glad and others
GNU Libidn by Simon Josefsson
Native POSIX Threads Library by Ulrich Drepper et al
BIND-8.2.3-T5B
libc ABIs: UNIQUE IFUNC
For bug reporting instructions, please see:
<http://www.debian.org/Bugs/>.
) = 616
exit_group(0) = ?
+++ exited with 0 +++

This command makes no sense:
patchelf --set-interpreter ./libc6-amd64_2.27-3ubuntu1_i386.so test
libc.so.6 and ld-linux.so.2 are not at all the same, and you are setting PT_INTERP to (equivalent of) libc.so.6.
This command is "correct":
patchelf --set-interpreter ./libc6-amd64_2.27-3ubuntu1_i386.ld test
but the result crashes most likely due to system GLIBC being a different version. As I said here, ld-linux and libc.so.6 must match exactly.
To make this all work, you should get rid of the funny libc-amd64... naming convention, fully extract the 2.27 build into e.g. ./libc6-amd64_2.27/ directory, then use something like:
patchelf --set-interpreter ./libc6-amd64_2.27/lib64/ld-linux-x86-64.so.2 test
LD_LIBRARY_PATH=./libc6-amd64_2.27/lib64 ./test

Related

I have a technical issue compiling with mpicc

My gcc works fine when I compile '''gcc''' but I'm trying to compile a C program with '''mpicc''' and my terminal returns this error, which deletes also the script:
/usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/Scrt1.o: In function `_start':
(.text+0x20): undefined reference to `main'
collect2: error: ld returned 1 exit status
The compiling instructions are: mpicc -o p35.c.
How could I solve this?
My gcc version:
gcc --version
gcc (Ubuntu 7.5.0-3ubuntu1~18.04) 7.5.0
Copyright (C) 2017 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
My mpicc version:
mpicc --version
gcc (Ubuntu 7.5.0-3ubuntu1~18.04) 7.5.0
Copyright (C) 2017 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Thanks.
Compiling Command is Wrong
mpicc p35.c -o p35.out
Now run p35.out file
./p35.out
I think you got this.

Building cross compiler: pthread.h: No such file or directory

I'm currently trying to compile my own gcc 9.1.0 cross compiler for aarch64-linux-gnu target. I used this tutorial: https://wiki.osdev.org/GCC_Cross-Compiler
The compile progress for the gcc and g++ compiler seems to finish without errors, but allways when I try to compile libgcc with the command make all-target-libgcc I run into this error:
In file included from ../../../gcc-9.1.0/libgcc/gthr.h:148,
from ../../../gcc-9.1.0/libgcc/libgcov-interface.c:27:
./gthr-default.h:35:10: fatal error: pthread.h: No such file or directory
35 | #include <pthread.h>
| ^~~~~~~~~~~
compilation terminated.
g++ --version on my build maschine prints:
g++ (GCC) 9.1.0
Copyright (C) 2019 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
And my configuration command for gcc is:
../gcc-9.1.0/configure --target=$TARGET --prefix="$PREFIX" --disable-nls --without-headers
With:
export TARGET=aarch64-linux-gnu
export PREFIX=/opt/aarch64-linux-gnu
What do I forget?
From GCC installation manual:
In order to build GCC, the C standard library and headers must be
present for all target variants for which target libraries will be
built (and not only the variant of the host C++ compiler).
So you need a libc for aarch64.
If you want to build it yourself, Preshing has a good article on the topic, which I haven't read in full but recommend anyway. He even has a picture mentioning both pthread.h and libgcc.a.
AFAIK, GCC can pick up a symlink to newlib sources and build it automatically during the course of building a full cross compiler with target libraries. Not sure about Glibc.

How do I link libraries from multiple locations (corresponding to multiple GCC versions)?

I am currently trying to use Oracle Linux 6 OS on a SPARC S7 server to run the NPB benchmarks (with OpenMP multithreading support). The OS comes preloaded with gcc 4.4.7, which is missing the Niagara 7 optimizations. I downloaded devtoolset-3 from the Oracle Yum Repository, which has gcc 4.9.2 installed in /opt/rh/devtoolset-3/root/usr/bin. However, when I compile the NPB benchmark using the newer gcc, it automatically links to libraries associated with the older gcc 4.4.7 (located in /usr/lib). This caused my program to segfault during execution. I believe that it is because libgomp 4.4.7 is incompatible with libgomp 4.9.2. I have tried several ways of linking to the libraries in the gcc 4.9.2 folder (which is /opt/rh/devtoolset-3/root/usr/lib/gcc); none of the methods work:
-Xlinker -rpath=lib_location
-Wl -Bstatic
-L lib_location
The closest I got was when using -Wl -Bstatic ~/libgomp.a or -static -L ~/libgomp.a. It fails to find libraries such as libm that reside in the default gcc lib folder (usr/lib).
The actual command used to link is:
/opt/rh/devtoolset-3/root/usr/bin/gcc -O3 -fopenmp -mcmodel=medmid -static -L/opt/rh/devtoolset-3/root/usr/lib/gcc/sparc64-redhat-linux/4.9.2 -o ../bin/bt.W.x bt.o initialize.o exact_solution.o exact_rhs.o set_constants.o adi.o rhs.o x_solve.o y_solve.o solve_subs.o z_solve.o add.o error.o verify.o ../common/print_results.o ../common/c_timers.o ../common/wtime.o -lm -L/opt/rh/devtoolset-3/root/usr/lib/gcc/sparc64-redhat-linux/4.9.2/lib/
/opt/rh/devtoolset-3/root/usr/libexec/gcc/sparc64-redhat-linux/4.9.2/ld: cannot find -lm
/opt/rh/devtoolset-3/root/usr/libexec/gcc/sparc64-redhat-linux/4.9.2/ld: cannot find -lrt
/opt/rh/devtoolset-3/root/usr/libexec/gcc/sparc64-redhat-linux/4.9.2/ld: cannot find -lpthread
/opt/rh/devtoolset-3/root/usr/libexec/gcc/sparc64-redhat-linux/4.9.2/ld: cannot find -lc
Is there a way I can link just the libgomp library from gcc 4.9.2 while linking the remaining libraries from gcc 4.4.7?
The devtoolset compilers are all using the system libgcc, libstdc++, version 4.4.7, and can therefore not compile e.g. c++11.
I guess the gcc53-c++-5.3.0-1.el6.x86_64.rpm will do. Comes with the internal */gcc53/lib64{libgcc_s.so**, libgomp.so**, libstdc++} (version 5.3.0) ... Provides /usr/bin/{ gcc53, g++53 }
The package was created a year ago ... well tested, as extra compiler. Download link : https://drive.google.com/file/d/0B7S255p3kFXNbTBneHgwSzBodFE/view?usp=sharing
If you're going to do the -Wl,-Bstatic thing, make sure to follow it immediately by -Wl,-Bdynamic to reset to normal after your added library argument. By default, not all system libraries have static versions installed, which is why you get e.g. cannot find -lc.
So you can try this as a modification of your workaround:
-Wl,-Bstatic ~/libgomp.a -Wl,-Bdynamic
Not pretty, and this question deserves a much better answer (this is still pretty much a hack), but it should get the job done for now.

"cmath: No such file or directory" when compiled with GCC

I wrote the simple program in linux ubuntu, when I use g++ there is no error but when I use gcc I see this error:
test.c:1:17: fatal error: cmath: No such file or directory #include <cmath>
Note : "as a matter of fact I see this error in compiling the package, I thought it might be related to gcc library which is not set to linux environment, so I wrote the simple program to determine the error clearly and whitout dependency!"
so the program should compile with gcc so that I can over come the main problem.
I khow that I can use math.h instead of cmath, but the packege used the cmath!
this is the simple program:
/*test.c*/
#include <cmath>
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
using namespace std;
int main(){
double sinx = sin(3.14/3);
cout<< "sinx= " << sinx;
return 0;
}
here is cmath pathes:
root#geant4:/# find -name cmath
./opt/root5.32.00/cint/cint/include/cmath
./app/gcc/4.8.0/include/c++/4.8.0/ext/cmath
./app/gcc/4.8.0/include/c++/4.8.0/cmath
./app/gcc/4.8.0/include/c++/4.8.0/tr1/cmath
./usr/include/boost/compatibility/cpp_c_headers/cmath
./usr/include/boost/tr1/tr1/cmath
./usr/include/c++/4.5/cmath
./usr/include/c++/4.5/tr1_impl/cmath
./usr/include/c++/4.5/tr1/cmath
./usr/include/c++/4.6/cmath
./usr/include/c++/4.6/tr1/cmath
./usr/share/gccxml-0.9/GCC/2.95/cmath
./gcc-build/gcc-4.8.0/stage1-i686-pc-linux-gnu/libstdc++-v3/include/ext/cmath
./gcc-build/gcc-4.8.0/stage1-i686-pc-linux-gnu/libstdc++-v3/include/cmath
./gcc-build/gcc-4.8.0/stage1-i686-pc-linux-gnu/libstdc++-v3/include/tr1/cmath
./gcc-build/gcc-4.8.0/i686-pc-linux-gnu/libstdc++-v3/include/ext/cmath
./gcc-build/gcc-4.8.0/i686-pc-linux-gnu/libstdc++-v3/include/cmath
./gcc-build/gcc-4.8.0/i686-pc-linux-gnu/libstdc++-v3/include/tr1/cmath
./gcc-build/gcc-4.8.0/libstdc++-v3/include/ext/cmath
./gcc-build/gcc-4.8.0/libstdc++-v3/include/c/cmath
./gcc-build/gcc-4.8.0/libstdc++-v3/include/c_global/cmath
./gcc-build/gcc-4.8.0/libstdc++-v3/include/c_std/cmath
./gcc-build/gcc-4.8.0/libstdc++-v3/include/tr1/cmath
./gcc-build/gcc-4.8.0/libstdc++-v3/testsuite/26_numerics/headers/cmath
./gcc-build/gcc-4.8.0/libstdc++-v3/testsuite/tr1/8_c_compatibility/cmath
./gcc-build/gcc-4.8.0/prev-i686-pc-linux-gnu/libstdc++-v3/include/ext/cmath
./gcc-build/gcc-4.8.0/prev-i686-pc-linux-gnu/libstdc++-v3/include/cmath
./gcc-build/gcc-4.8.0/prev-i686-pc-linux-gnu/libstdc++-v3/include/tr1/cmath
and after installing gcc-4.8 I did this instruction:
root#geant4:~/Desktop# update-alternatives --install /usr/bin/gcc gcc /app/gcc/4.8.0/bin/gcc 40 --slave /usr/bin/g++ g++ /app/gcc/4.8.0/bin/g++
root#geant4:~/Desktop#update-alternatives --install /usr/bin/gcc gcc /app/gcc/4.8.0/bin/gcc 60 --slave /usr/bin/g++ g++ /app/gcc/4.8.0/bin/g++
root#geant4:~/Desktop# update-alternatives --config gcc
to make gcc-4.8 my default gcc.
now
root#geant4:~/Desktop# gcc --version
gcc (GCC) 4.8.0
Copyright (C) 2013 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
as a matter of fact I wrote the main problem in https://askubuntu.com/questions/309195/cmath-no-such-file-or-directory-include-cmath
please help me
I don`t know what to do.
thanks
Some basics::
GCC:: GNU Compiler Collection
G++:: GNU C++ Compiler
Both are drivers which calls the compilers as needed.
Clearing your doubt::
The problem with GCC is that it doesn't links in the std C++ libraries by default as G++ does. GCC is just a front-end. The actual compiler is cc1plus. So it is always advisable to use G++ when compiling C++ files. The result can be same with both GCC and G++ if you do know the exact arguments to link them. You may find this link helpful.
But if you still want to use GCC, use it with linker-option -lstdc++ at the end of the command. This linker-option is added by default when you use G++. You can verify this by compiling your code using GCC with -### option and it will show you that -lstdc++ option is missing.
Compile C++ source files with g++, not gcc.

How to compile on linux so that the resulting executable does not require shared libraries

I successfully compiled swftools using their instructions (http://wiki.swftools.org/index.php/FAQ) on my Fedora 14 machine. I want to use one of the tools (pdf2swf) on another Linux machine. When I move it and run it on the other machine it asks for some shared libraries. Is it possible to compile swftools (in particular pdf2swf) so that when I run it on another Linux machine it does not ask for any shared libraries? It is OK if the executable itself is bigger in size, as far as it can run independently.
I am new to Linux, so if something requires advanced knowledge please point me to the appropriate online resource.
Regards
it's trivial: link with -static. of course, this implies that you'll need static libraries installed. the linker (often called through cc) simply defaults to using shared libraries when both are available.
[hahn#box ~]$ cat hello.c
#include <stdio.h>
int main() {
printf("Hello, world!\n");
return 0;
}
[hahn#box ~]$ cc hello.c -o hello
[hahn#box ~]$ file hello
hello: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.32, not stripped
[hahn#box ~]$ ldd hello
linux-gate.so.1 => (0x00205000)
libc.so.6 => /lib/libc.so.6 (0x00697000)
/lib/ld-linux.so.2 (0x005b4000)
[hahn#box ~]$ cc hello.c -o hello -static
[hahn#box ~]$ file hello
hello: ELF 32-bit LSB executable, Intel 80386, version 1 (GNU/Linux), statically linked, for GNU/Linux 2.6.32, not stripped
[hahn#box ~]$ ldd hello
not a dynamic executable
[hahn#box ~]$ ./hello
Hello, world!
to make this work, I needed to install glibc-static, which is not installed by default (at least on this box, which is Fedora14). some packages let you select static linking at the ./configure level, or else you may need to modify the Makefile.
Well, what you want are statically linked libraries, as opposed to dynamically/shared libraries.
You need to compile your application and link it statically. If you use gcc you can apply the static switch to your call of the compiler:
gcc -static <and the whole gcc shebang>
Most of the times you can edit the makefile (look for a CC define or CC_ARGS something like that) and just include the static switch as above.

Resources