Using $ORIGIN to specify the interpreter in ELF binaries isn't working
If I specify an absolute path instead of using $ORIGIN then it seems to work fine.
This is working as intended.
It is the dynamic linker that interprets (expands) $ORIGIN
and other special tokens.
The Linux kernel doesn't.
And it is the kernel that reads PT_INTERP
segment of the main executable and (if present) loads and invokes the interpreter (the dynamic linker). When you set interpreter to non-existant path (such as $ORIGIN/lib/ld-linux-x86-64.so.2
), you get ENOENT
from the kernel execve
system call.
There is no way to make interpreter itself be anything other than valid path.
Depending on what you are actually trying to achieve, rtldi may be the answer.
patchelf set interpreter to a path relative to executable
You need to specify the path relative to the current working directory (the one you use to execute the program) and not relative to the directory that contains the binary file.
echo 'int main() { return 0; }' > main.c
gcc -Wl,--dynamic-linker=./lib/ld-linux-x86-64.so.2 -o main main.c
mkdir bin
mkdir lib
cp /lib64/ld-linux-x86-64.so.2 lib/
cp main bin/
bin/main # this should run without problems
cd bin; ./main # this throws a "No such file or directory" error
ELF, Build-ID, is there a utility to recompute it?
So, I've got an answer from Mark. Since it is an up to date info, I post it here. But basically you guys are right. Indeed there is no tool for computing Build-ID, and the intentions of Build-ID are not (1) identification of the file contents, and not even (2) identification of the executable (code) part of it, but it is for (3) capturing "semantic meaning" of a build, which is the hard bit for formalization. (Numbers are for self-reference.)
Quote from the email:
-- "Is there a user tool recomputing the build-id from the file itself, to
check if it's not corrupted/compromised somehow etc?"
If you have time, maybe you could post an answer there?
Sorry, I don't have a stackoverflow account.
But the answer is: No, there is no such tool because the precise way a
build-id is calculated isn't specified. It just has to be universally
unique. Even the precise length of the build-id isn't specified. There
are various ways using different hashing algorithms a build-id could be
calculated to get a universally unique value. And not all data might
(still be) in the ELF file to recalculate it even if you knew how it was
created originally.Apparently, the intentions of Build-ID changed
since the Fedora Feature page was written about
it.
And people's opinions diverge on what it is now.
Maybe in your answer you could include status of Build-ID and what it is
now as well?
I think things weren't very precisely formulated. If a tool changes the
build that creates the ELF file so that it isn't a "semantically
identical" binary anymore then it should get a new (recalculated)
build-id. But if a tool changes something about the file that still
results in a "semantically identical" binary then the build-id stays the
same.What isn't precisely defined is what "semantically identical binary"
means. The intention is that it captures everything that a build was
made from. So if the source files used to generate a binary are
different then you expect different build-ids, even if the binary code
produced might happen to be the same.This is why when calculating the build-id of a file through a hash
algorithm you use not just the (allocated) code sections, but also the
debuginfo sections (which will contain references to the source file
names).But if you then for example strip the debuginfo out (and put it into a
separate file) then that doesn't change the build-id (the file was still
created from the same build).This is also why, even if you knew the precise hashing algorithm used to
calculate the build-id, you might not be able to recalculate the
build-id. Because you might be missing some of the original data used in
the hashing algorithm to calculate the build-id.Feel free to share this answer with others.
Cheers,
Mark
Also, for people interested in debuginfo
(linux performance & tracing, anyone?), he mentioned a couple projects for managing them on Fedora:
- https://fedoraproject.org/wiki/Changes/ParallelInstallableDebuginfo
- https://fedoraproject.org/wiki/Changes/SubpackageAndSourceDebuginfo
GNU C Cross-compiler: Cannot execute binary file
This really looks like a kernel that is configured for pure 64-bit userspace, no i386 support.
This would be CONFIG_IA32_EMULATION
in the kernel config. Check /proc/config.gz
to confirm.
Multiple glibc libraries on a single host
It is very possible to have multiple versions of glibc on the same system (we do that every day).
However, you need to know that glibc consists of many pieces (200+ shared libraries) which all must match. One of the pieces is ld-linux.so.2, and it must match libc.so.6, or you'll see the errors you are seeing.
The absolute path to ld-linux.so.2 is hard-coded into the executable at link time, and can not be easily changed after the link is done (Update: can be done with patchelf; see this answer below).
To build an executable that will work with the new glibc, do this:
g++ main.o -o myapp ... \
-Wl,--rpath=/path/to/newglibc \
-Wl,--dynamic-linker=/path/to/newglibc/ld-linux.so.2
The -rpath
linker option will make the runtime loader search for libraries in /path/to/newglibc
(so you wouldn't have to set LD_LIBRARY_PATH
before running it), and the -dynamic-linker
option will "bake" path to correct ld-linux.so.2
into the application.
If you can't relink the myapp
application (e.g. because it is a third-party binary), not all is lost, but it gets trickier. One solution is to set a proper chroot
environment for it. Another possibility is to use rtldi and a binary editor. Update: or you can use patchelf.
Would there ever be a reason to write code in pure binary?
Historical reason: You are running a machine that requires its boot code to be toggled in on the front panel. (And yes, this was done. Regularly in the first couple of generation of machines.)
Not-what-you-were-looking-for modern reason: When you are writing an assembler you have to figure out the process.
Related Topics
Movdqu Instruction + Page Boundary
Export_Symbol in Kernel Module | Undefined Symbol During Insmod
Fail If a Script Expects Input or Entering Passwords
Can Someone Explain the Shell Shock Bash Code
Difference Between Source and ./ Execution of Linux Scripts
How to Get the CPU Time for a Perl System Call
Bash Assign Output to Variable Inside Here Document
Why Can't I Access This Folder
Python3 Mlpy Installation Error - 'Py_Initmodule3' Was Not Declared in This Scope
How to Add a System Call via a Lkm
Changing the Owner of an Existing Process in Linux
Differentiate Between Exit and Session Timeout
Glassfish There Is a Process Already Using the Admin Port 4848
Using Scanf into Global or Local Variables (On the Stack), 32-Bit Calling Convention
Linking to Modules Folder Gives Undefined Reference
Terminal Closes When I Source My Script (Run with Dot at the Start)