Sample Header Ad - 728x90

Unix & Linux Stack Exchange

Q&A for users of Linux, FreeBSD and other Unix-like operating systems

Latest Questions

2 votes
2 answers
101 views
Update mmap mapping to be readonly without overwriting existing data
I'm making a custom ELF loader to learn how the dynamic loader works behind the scenes, and one of the program headers often found in them is `PT_GNU_RELRO`, which tells the loader to make that segment read-only after performing relocations. However, it doesn't look like there's a good way to update...
I'm making a custom ELF loader to learn how the dynamic loader works behind the scenes, and one of the program headers often found in them is PT_GNU_RELRO, which tells the loader to make that segment read-only after performing relocations. However, it doesn't look like there's a good way to update existing memory mappings' protections without replacing the entire thing. MAP_UNINITIALIZED seems to be what I'm looking for, but mmap(2) states that it doesn't work on most systems for security reasons. >**MAP_UNINITIALIZED (since Linux 2.6.33)** > >Don't clear anonymous pages. This flag is intended to improve performance on embedded devices. This flag is honored only if the kernel was configured with the CONFIG_MMAP_ALLOW_UNINITIALIZED option. Because of the security implications, that option is normally enabled only on embedded devices (i.e., devices where one has complete control of the contents of user memory). Which is reasonable for loosening permissions, but I'm looking to restrict them. Is there a way, as a user process, to update a mmap mapping to be read-only without replacing existing data at that address?
Electro_593 (23 rep)
Jun 21, 2025, 02:49 AM • Last activity: Jun 21, 2025, 08:43 AM
1 votes
2 answers
51 views
How to specify ELF shared objects in `LD_PRELOAD` if their path contains a space character?
Paths to ELF shared objects in `LD_PRELOAD` cannot contain spaces, as space is one of the two list separators, and it cannot be escaped: > `LD_PRELOAD` > > A list of additional, user-specified, ELF shared objects to be loaded before all others. This feature can be used to selectively override functi...
Paths to ELF shared objects in LD_PRELOAD cannot contain spaces, as space is one of the two list separators, and it cannot be escaped: > LD_PRELOAD > > A list of additional, user-specified, ELF shared objects to be loaded before all others. This feature can be used to selectively override functions in other shared objects. > > The items of the list can be separated by spaces or colons, and there is no support for escaping either separator. Source: https://manpages.debian.org/bookworm/manpages/ld.so.8.en.html So assuming I want to execute program myprogram and preload an ELF shared object from /path/with space/lib/libsomething.so, then this doesn't work: $ LD_PRELOAD="/path/with space/lib/libsomething.so" myprogram ERROR: ld.so: object '/path/with' from LD_PRELOAD cannot be preloaded (cannot open shared object file): ignored. ERROR: ld.so: object 'space/lib/libsomething.so' from LD_PRELOAD cannot be preloaded (cannot open shared object file): ignored. ...
finefoot (3554 rep)
Jun 2, 2025, 12:28 AM • Last activity: Jun 2, 2025, 06:48 AM
4 votes
1 answers
2348 views
How to make $ORIGIN in RPATH not follow symlinks?
I have an executable `app`, which depends on a library `libbar.so` and loads it via `RPATH` with `$ORIGIN` like this: $ readelf -d app Dynamic section at offset 0xe08 contains 26 entries: Tag Type Name/Value 0x0000000000000001 (NEEDED) Shared library: [libbar.so] 0x0000000000000001 (NEEDED) Shared l...
I have an executable app, which depends on a library libbar.so and loads it via RPATH with $ORIGIN like this: $ readelf -d app Dynamic section at offset 0xe08 contains 26 entries: Tag Type Name/Value 0x0000000000000001 (NEEDED) Shared library: [libbar.so] 0x0000000000000001 (NEEDED) Shared library: [libc.so.6] 0x000000000000000f (RPATH) Library rpath: [$ORIGIN/lib/] It would be nice to run it in the appropriate directory structure, made with symlinks to the executable and the libbar.so: $ ls -R .: app@ lib/ ./lib: libbar.so@ -- but **the linker follows symlinks to the original file of the executable, sets $ORIGIN to the directory of the executable file and resolves the dependency paths from there. Is it possible to make it not do this?** So that directory-path-wise, in the search for lib files, the symlinks are treated as real files of the filesystem ("end-points" of the search). Also, some reasoning to this problem: 1. It is convenient to have binaries set up to **search for dependencies in a couple relational directories**, for instance in the $ORIGIN/ of a binary itself and also in $ORIGIN/appname_dependencies/ (so that one can just copy the binary and its' dependencies into one directory and run it, but also has a fall-back for a more complicated set-up with multiple versions of the same binary in the system). 2. Due to the requirement of **several dependency search paths, RPATH is the search method to use**: a "slashed" name of dependency (NEEDED Shared library: [./libbar.so]) sets only 1 search path. Also, for simplicity the dependency resolution paths should be in the binary itself. 3. It's nice to be able to combine all binaries (the application and all its' dependencies) into the **full dependency graph with links**, instead of copying the files. And **symbolic links are more resilient** than hard links: they link across filesystems. In fact, I have this problem in one academic environment of a linux cluster, where a hard link to parent directory cannot be done: $ ln ../afile ln: creating hard link ./afile' => ../afile': Invalid cross-device link
xealits (2267 rep)
Aug 10, 2016, 03:04 PM • Last activity: May 31, 2025, 05:05 AM
2 votes
1 answers
1960 views
How to make my ELF run with both new and old version of glibc?
When I'm compiling my elf, it is "best practice" to make it link against the oldest version of glibc I can, so it will work both on new and old versions of glibc. i.e. if I use realpath, which in `readelf` output of glibc we can see has both a GLIBC_2.0 version and a GLIBC_2.3 version, I want to use...
When I'm compiling my elf, it is "best practice" to make it link against the oldest version of glibc I can, so it will work both on new and old versions of glibc. i.e. if I use realpath, which in readelf output of glibc we can see has both a GLIBC_2.0 version and a GLIBC_2.3 version, I want to use the old version so my ELF would work on glibc 2.0/1/2. But the GLIBC_2.3 version was probably developed and upgraded since it was published, and I guess GLIBC_2.0 version hasn't changed since glibc 2.3 has been published. So I guess I want my elf to use GLIBC_2.3 version when it is present, and when not, to fallback to the GLIBC_2.0 version. Is is possible? Or what don't I understand?
speller (509 rep)
Feb 22, 2015, 07:46 PM • Last activity: Apr 22, 2025, 10:04 PM
2 votes
1 answers
208 views
Calculate byte offset for unquashfs
I'm trying to calculate the `-o` value for extracting an `.AppImage` file using `unsquashfs` on foreign architectures/OSs , but using `objdump` instead of `readelf` to make the solution more compatible with OSs such as macOS. ``` unsquashfs Usage: -o BYTES, -offset BYTES skip BYTES at start of FILES...
I'm trying to calculate the -o value for extracting an .AppImage file using unsquashfs on foreign architectures/OSs , but using objdump instead of readelf to make the solution more compatible with OSs such as macOS.
unsquashfs

Usage:

-o BYTES, -offset BYTES
              skip BYTES at start of FILESYSTEM.  Optionally a suffix of K, M or G can be given to specify Kbytes, Mbytes or Gbytes respectively (default 0
              bytes).
I'm following the guidance of [this solution](https://superuser.com/a/1690054?_gl=1*1ytjlvt*_ga*MTU2NzA5OTc3NS4xNzMzMzU0NzA4*_ga_S812YQPLT2*MTczNzA0OTY3Ny4xMS4xLjE3MzcwNTEwMzQuMC4wLjA.) , which uses readelf to calculate the -o offset value. This works great on Ubuntu, but does not work for macOS due to the generally unavailability of readelf. However, I'd like to use objdump if possible. I've found a few questions that explain how to find the entry point/offset of a binary executable, but no matter what values I try, I can't find a way to get the correct value for unsquashfs. I'm converting hex values to decimal, but nothing from objdump matches up to the readelf values below, even when using [Employed Russian's](https://stackoverflow.com/a/71367851) ehdr->e_entry - phdr->p_vaddr + phdr->p_offset. equation. * https://stackoverflow.com/a/71367851 * https://stackoverflow.com/a/57841768 * https://stackoverflow.com/a/16019798 For example, take Audacity's AppImage for example:
https://github.com/audacity/audacity/releases/download/Audacity-3.7.1/audacity-linux-3.7.1-x64-22.04.AppImage 
* Calling readelf -h audacity-linux-3.7.1-x64-22.04.AppImage gives me some helpful values, such as Start of section headers, Size of section headers, Number of section headers. * Next, using [Martin Vyskočil's](https://superuser.com/a/1690054?_gl=1*1sf6dim*_ga*MTU2NzA5OTc3NS4xNzMzMzU0NzA4*_ga_S812YQPLT2*MTczNzA0OTY3Ny4xMS4xLjE3MzcwNTExMDEuMC4wLjA.) $START_OF_SECTION + $SECTION_SIZE * $SECTION_NO logic , I can get a correct value of 191680 + 64 * 32, which is 193728. * The following command succeeds (on macOS and Ubuntu):
unsquashfs -o 193728 audacity-linux-3.7.1-x64-22.04.AppImage squashfs-root
... but how can I calculate this offset value with objdump instead of readelf?
tresf (355 rep)
Jan 16, 2025, 06:10 PM • Last activity: Mar 31, 2025, 10:19 PM
1 votes
0 answers
43 views
What is the difference between the ELF Visibility Values STV_INTERNAL and STV_HIDDEN?
I was trying to understand Visibility values in ELF file , and I couldn't Understand the difference between `STV_HIDDEN` and `STV_INTERNAL` . After some reseach I found that this may be related to how symbols are exported in symbol table , am not sure whether that is correct or not but if some one e...
I was trying to understand Visibility values in ELF file , and I couldn't Understand the difference between STV_HIDDEN and STV_INTERNAL . After some reseach I found that this may be related to how symbols are exported in symbol table , am not sure whether that is correct or not but if some one explain the story behind the difference it will be helpful for me . Possible Duplicate : https://unix.stackexchange.com/questions/472660/what-are-difference-between-the-elf-symbol-visibility-levels But from the answer there I still couldn't get the difference , perhaps more explaination may help me . Thanks
AbdAllah Talaat (197 rep)
Feb 4, 2025, 06:17 PM
4 votes
1 answers
462 views
Who maintains architecture IDs (and OS ABIs) for ELF format now?
The latest [spec for ELF](https://www.sco.com/developers/gabi/latest/ch4.eheader.html) list many architectures that can be used with it, but some self-assignments are made in the wild (e.g. [Chinese LoongArch](https://loongson.github.io/LoongArch-Documentation/LoongArch-ELF-ABI-EN.html#_e_machine_id...
The latest [spec for ELF](https://www.sco.com/developers/gabi/latest/ch4.eheader.html) list many architectures that can be used with it, but some self-assignments are made in the wild (e.g. [Chinese LoongArch](https://loongson.github.io/LoongArch-Documentation/LoongArch-ELF-ABI-EN.html#_e_machine_identifies_the_machine)) . Is there anyone coordinating these assignments? LANANA doesn't seem to have such list, or am I missing something?
DannyNiu (692 rep)
Feb 4, 2025, 09:11 AM • Last activity: Feb 4, 2025, 09:40 AM
1 votes
1 answers
149 views
Why is the stack segment not explicit in ELF files?
Everything mapped in memory is explicit in ELF files *except* the stack segment. The stack segment is mapped automatically. Why is the stack segment not like other segments, with explicit settings in ELF files? Some programs might want a specific stack size that does not necessarily match the limit...
Everything mapped in memory is explicit in ELF files *except* the stack segment. The stack segment is mapped automatically. Why is the stack segment not like other segments, with explicit settings in ELF files? Some programs might want a specific stack size that does not necessarily match the limit set by ulimit -s. So they can't use the automatically allocated stack. The program should know better than the user how much stack memory it actually needs. Some programs might not need a stack at all. For example garbage collected languages may want to allocate their stack frames on the heap. Wouldn't it be simpler and better for the stack segment to be explicit? The stack could either be a segment in the ELF file (perhaps with an "automatically growable" bit set), or it could be mmaped by the process itself at startup.
Tomek Czajka (121 rep)
Dec 16, 2024, 01:16 PM • Last activity: Dec 18, 2024, 12:41 PM
0 votes
0 answers
80 views
GDB doesn't hit catchpoint on the child process forked off from debuggee
I was re-doing what described [here][1] about multiprocessing debugging in `GDB`. The weird thing is that `GDB` doesn't hit the `exec` catchpoint on the child process running `cat` command (the latter is forked off from `bash`). ubuntu@ubuntu:~$ echo $$ 670639 ubuntu@ubuntu:~$ cat /etc/issue root@ub...
I was re-doing what described here about multiprocessing debugging in GDB. The weird thing is that GDB doesn't hit the exec catchpoint on the child process running cat command (the latter is forked off from bash). ubuntu@ubuntu:~$ echo $$ 670639 ubuntu@ubuntu:~$ cat /etc/issue root@ubuntu:~# gdb -q -p 670639 Attaching to process 670639 Reading symbols from /usr/bin/bash... (No debugging symbols found in /usr/bin/bash) Reading symbols from /lib/x86_64-linux-gnu/libtinfo.so.6... (No debugging symbols found in /lib/x86_64-linux-gnu/libtinfo.so.6) Reading symbols from /lib/x86_64-linux-gnu/libc.so.6... Reading symbols from /usr/lib/debug/.build-id/49/0fef8403240c91833978d494d39e537409b92e.debug... Reading symbols from /lib64/ld-linux-x86-64.so.2... Reading symbols from /usr/lib/debug/.build-id/41/86944c50f8a32b47d74931e3f512b811813b64.debug... [Thread debugging using libthread_db enabled] Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1". pselect64_syscall (sigmask=0x564025a0c820 , timeout=, exceptfds=0x0, writefds=0x0, readfds=0x7ffe468736e0, nfds=1) at ../sysdeps/unix/sysv/linux/pselect.c:34 34 ../sysdeps/unix/sysv/linux/pselect.c: No such file or directory. (gdb) catch fork Catchpoint 1 (fork) (gdb) catch exec Catchpoint 2 (exec) (gdb) c Continuing. Catchpoint 1 (forked process 719946), arch_fork (ctid=0x7fbccdc6fa10) at ../sysdeps/unix/sysv/linux/arch-fork.h:52 52 ../sysdeps/unix/sysv/linux/arch-fork.h: No such file or directory. (gdb) info inferiors Num Description Connection Executable * 1 process 670639 1 (native) /usr/bin/bash (gdb) set detach-on-fork off (gdb) nexti [New inferior 2 (process 719946)] [Thread debugging using libthread_db enabled] Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1". 52 in ../sysdeps/unix/sysv/linux/arch-fork.h (gdb) c Continuing. What is the reason behind it? Thanks.
CarloC (385 rep)
Nov 26, 2024, 01:20 PM • Last activity: Nov 26, 2024, 01:52 PM
6 votes
1 answers
4095 views
Disassemble ELF binary without section headers (program headers only) using objdump
I've got an ELF binary that contains nothing but two LOAD segments in the program header table, one for code and one for data. `readelf -a` tells me there's no section headers. If I attempt do disassemble the ARM binary on my amd64 machine with ARM cross binutils, it doesn't give me proper output. H...
I've got an ELF binary that contains nothing but two LOAD segments in the program header table, one for code and one for data. readelf -a tells me there's no section headers. If I attempt do disassemble the ARM binary on my amd64 machine with ARM cross binutils, it doesn't give me proper output. However, as far as I understand, the binary's architecture shouldn't be relevant for this question, since the issue is ELF-related.
$ file ./binary
./binary: ELF 32-bit LSB executable, ARM, EABI5 version 1 (GNU/Linux), statically linked, stripped

$ arm-linux-gnueabi-objdump -d ./binary 

./binary:     file format elf32-littlearm

$ arm-linux-gnueabi-objdump -x ./binary 

./binary:     file format elf32-littlearm
./binary
architecture: arm, flags 0x00000102:
EXEC_P, D_PAGED
start address 0x0004c8d8

Program Header:
    LOAD off    0x00000000 vaddr 0x00010000 paddr 0x00010000 align 2**16
         filesz 0x0003d27e memsz 0x0003d27e flags r-x
    LOAD off    0x00005c78 vaddr 0x00085c78 paddr 0x00085c78 align 2**16
         filesz 0x00000000 memsz 0x00000000 flags rw-
   STACK off    0x00000000 vaddr 0x00000000 paddr 0x00000000 align 2**4
         filesz 0x00000000 memsz 0x00000000 flags rw-
private flags = 5000400: [Version5 EABI] [hard-float ABI]

Sections:
Idx Name          Size      VMA       LMA       File off  Algn
SYMBOL TABLE:
no symbols
**Is there a way to make objdump disassemble ELF segments?**
ulmer-a (229 rep)
Aug 18, 2019, 06:59 PM • Last activity: Nov 7, 2024, 02:03 PM
0 votes
0 answers
346 views
How to cross-compile Linux tools/perf for embedded system?
I am working on an embedded Linux system (kernel-5.19.20) on MIPS, and I want to build `tools/perf` for my system. I want to have `libelf` feature enabled when cross compile perf, so I firstly cross-compile and installed the `libelf` to `$(proj)/sysroot/usr/lib/`. Then I tried following command to c...
I am working on an embedded Linux system (kernel-5.19.20) on MIPS, and I want to build tools/perf for my system. I want to have libelf feature enabled when cross compile perf, so I firstly cross-compile and installed the libelf to $(proj)/sysroot/usr/lib/. Then I tried following command to cross compile perf.
CC=mips-none-gnu-gcc make ARCH=mips CROSS_COMPILE=mips-none-gnu- EXTRA_CFLAGS="-I/home/t/proj/target/usr/include" LDFLAGS="-L/home/t/proj/target/usr/lib -Wl,-rpath-link=/home/t/proj/target/usr/lib"
And I got following feature list.
Auto-detecting system features:
...                         dwarf: [ OFF ]
...            dwarf_getlocations: [ OFF ]
...                         glibc: [ on  ]
...                        libbfd: [ OFF ]
...                libbfd-buildid: [ OFF ]
...                        libcap: [ OFF ]
...                        libelf: [ OFF ]
...                       libnuma: [ OFF ]
...        numa_num_possible_cpus: [ OFF ]
...                       libperl: [ OFF ]
...                     libpython: [ OFF ]
...                     libcrypto: [ OFF ]
...                     libunwind: [ OFF ]
...            libdw-dwarf-unwind: [ OFF ]
...                          zlib: [ OFF ]
...                          lzma: [ OFF ]
...                     get_cpuid: [ OFF ]
...                           bpf: [ on  ]
...                        libaio: [ on  ]
...                       libzstd: [ OFF ]
...        disassembler-four-args: [ OFF ]
I checked the ../build/feature/test-libelf.make.output, and I got,
/home/t/proj/mips-none-gnu/bin/ld: warning: libz.so.1, needed by /home/t/proj/target/usr/lib/libelf.so, not found (try using -rpath or -rpath-link)
/home/t/proj/target/usr/lib/libelf.so: undefined reference to `inflate'
/home/t/proj/target/usr/lib/libelf.so: undefined reference to `deflate'
/home/t/proj/target/usr/lib/libelf.so: undefined reference to deflateInit_'    /home/t/proj/target/usr/lib/libelf.so: undefined reference to inflateEnd'
/home/t/proj/target/usr/lib/libelf.so: undefined reference to `deflateEnd'
/home/t/proj/target/usr/lib/libelf.so: undefined reference to inflateInit_'    /home/t/proj/target/usr/lib/libelf.so: undefined reference to inflateReset'    collect2: error: ld returned 1 exit status
The libz.so is built within buildroot and already installed into /home/t/proj/target/usr/lib. So, how to make perf with libelf succeed in this case?
wangt13 (631 rep)
Oct 17, 2024, 06:25 AM • Last activity: Oct 17, 2024, 07:04 AM
0 votes
1 answers
204 views
Calculation of relocation address; ELF
I am learning about the relocation from [the ELF reference][1] and [this blog][2], but I can't get my head around calculating the relocation address. 1. Suppose we have two files `A` and `B` of type `ET_REL`, we want to merge their sections named `S` during linkage; these sections include symbols `S...
I am learning about the relocation from the ELF reference and this blog , but I can't get my head around calculating the relocation address. 1. Suppose we have two files A and B of type ET_REL, we want to merge their sections named S during linkage; these sections include symbols SA (in A file) and SB (in B) file. If we have relocation entries and relocation offsets in A.elf and B.elf, I don't understand how linker avoids conflict of relocation addresses: I assume that these offsets might be the same in A.elf and B.elf, since these files don't know about each other during compilation. 2. What is the purpose of relocation table in ET_EXEC? I can't see why is it needed. 3. What is the purpose of the addend in relocation of Rela type? I think that most of all I don't have a clear intuition on how the relocation looks like, step by step. There is an example in the blog , but I don't understand what happens exactly with that symbol, what is the result and how do we combine multiple sections. Any suggestions on resource to learn would be appreciated.
Question (1 rep)
Mar 22, 2024, 01:05 PM • Last activity: Oct 2, 2024, 10:50 AM
0 votes
0 answers
69 views
How to trace the current instruction pointer of an executable dependent on shared libraries?
I would like to trace the api calls made by an executable to the linked shared libraries. When the libraries are complied with the executable, I can trace function calls using python's Ptrace debugger. But **when the executable is linked with shared libraries each time instruction pointer is random*...
I would like to trace the api calls made by an executable to the linked shared libraries. When the libraries are complied with the executable, I can trace function calls using python's Ptrace debugger. But **when the executable is linked with shared libraries each time instruction pointer is random** so I couldn't be able to trace the api calls. I read that due to ASLR this address is random each time. Steps followed to trace function calls: - Got the function address from the elf file - Got the Instruction pointer by linking pid with ptrace debugger - Matched instruction pointer and function address to get the function call made. I also read that shared libraries are compiled with position independent flag, so it will the linked with PLT table in runtime. Is there any other way to get the next instruction pointer and match it with function address to trace each function call made to shared library?
raghul (1 rep)
Sep 18, 2024, 05:53 PM
3 votes
1 answers
4424 views
How to list imported functions (.plt) for an ELF executable without disassembling using objdump?
Currently, I check for imported functions (`.plt`) using `objdump`: objdump -D -j .plt myprog | grep '@plt' However, it doesn't seem right to have `objdump` output annotated disassembly to `grep` to list imported (`.plt`) functions. To check exported functions, I use `readelf -s myprog`, but the imp...
Currently, I check for imported functions (.plt) using objdump: objdump -D -j .plt myprog | grep '@plt' However, it doesn't seem right to have objdump output annotated disassembly to grep to list imported (.plt) functions. To check exported functions, I use readelf -s myprog, but the imported .plt functions doesn't show up here? How can I list all imported (.plt) function in an ELF executable?
Shuzheng (4931 rep)
Jun 23, 2019, 08:38 AM • Last activity: Mar 22, 2024, 07:05 PM
9 votes
1 answers
2159 views
Why can an aarch64 ELF executable be run on an x86_64 machine?
I compiled a simple "Hello World" C program on Raspberry Pi 3, which was then transferred to an AMD64 laptop. Out of curiosity, I executed it, and it runs even though I did not expect it to: ```shell $ uname -a Linux 15ud490-gx76k 6.5.0-25-generic #25~22.04.1-Ubuntu SMP PREEMPT_DYNAMIC Tue Feb 20 16...
I compiled a simple "Hello World" C program on Raspberry Pi 3, which was then transferred to an AMD64 laptop. Out of curiosity, I executed it, and it runs even though I did not expect it to:
$ uname -a
Linux 15ud490-gx76k 6.5.0-25-generic #25~22.04.1-Ubuntu SMP PREEMPT_DYNAMIC Tue Feb 20 16:09:15 UTC 2 x86_64 x86_64 x86_64 GNU/Linux
$ file hello64
hello64: ELF 64-bit LSB executable, ARM aarch64, version 1 (GNU/Linux), statically linked, BuildID[sha1]=486ee1cde035cd704b49c037a32fb77239b6a1c2, for GNU/Linux 3.7.0, not stripped
$ ./hello64
Hello World!
Like that, how can it execute? QEMU User Emulation is installed, but I don't know whether it is playing a part in this or not.
pico (150 rep)
Mar 10, 2024, 07:26 AM • Last activity: Mar 10, 2024, 05:57 PM
1 votes
0 answers
157 views
Why can't linux use $ORIGIN to find the loader (aka interpreter)
When compiling a binary on Linux there's this thing called the RPATH, which tells the dynamic loader where to look for the shared objects. What I like about the RPATH is that you can vendor a particular `.so` file if needed by using the `$ORIGIN` attribute, where the loader searches for it in a path...
When compiling a binary on Linux there's this thing called the RPATH, which tells the dynamic loader where to look for the shared objects. What I like about the RPATH is that you can vendor a particular .so file if needed by using the $ORIGIN attribute, where the loader searches for it in a path relative to the executable path. So if my binary has a RPATH with $ORIGIN/. the loader will search in its directory, that's super useful for distributing software. There's a problem, the loader itself must be hard-coded, so even if I can ship all my dependencies, it's useless if the loader is wrong. If I take the musl loader for example, I can set the interpreter path with something like ld or patchelf to be ./musl-ld.so, problem is, this will only work if the executable is invoked from its own directory, using $ORIGIN causes the kernel to search for a literal path called $ORIGIN/./musl-ld.so. Is there any reason why the interpreter can do this but the kernel seemingly can't? Would it be in the interest of the kernel maintainers to fix such limitation? This would massively simplify making portable executables to linux without using hacks like AppImage, as the system does have a stable syscall interface.
the_the_the (11 rep)
Feb 2, 2024, 05:46 PM • Last activity: Feb 2, 2024, 05:47 PM
1 votes
1 answers
377 views
Why the same offset of two sections in ELF?
Recently I noticed something in several ELF files which looks for me a bit suspicious under Linux. Taking for example "/bin/ls" file and running readelf on it I can see following: There are 27 section headers, starting at offset 0x213b8: Section Headers: [Nr] Name Type Address Off Size ES Flg Lk Inf...
Recently I noticed something in several ELF files which looks for me a bit suspicious under Linux. Taking for example "/bin/ls" file and running readelf on it I can see following: There are 27 section headers, starting at offset 0x213b8: Section Headers: [Nr] Name Type Address Off Size ES Flg Lk Inf Al [ 0] NULL 0000000000000000 000000 000000 00 0 0 0 [ 1] .interp PROGBITS 0000000000000318 000318 00001c 00 A 0 0 1 [ 2] .note.gnu.property NOTE 0000000000000338 000338 000050 00 A 0 0 8 [ 3] .note.gnu.build-id NOTE 0000000000000388 000388 000024 00 A 0 0 4 [ 4] .note.ABI-tag NOTE 00000000000003ac 0003ac 000020 00 A 0 0 4 [ 5] .gnu.hash GNU_HASH 00000000000003d0 0003d0 00005c 00 A 6 0 8 [ 6] .dynsym DYNSYM 0000000000000430 000430 000bb8 18 A 7 1 8 [ 7] .dynstr STRTAB 0000000000000fe8 000fe8 0005dd 00 A 0 0 1 [ 8] .gnu.version VERSYM 00000000000015c6 0015c6 0000fa 02 A 6 0 2 [ 9] .gnu.version_r VERNEED 00000000000016c0 0016c0 0000d0 00 A 7 1 8 .rela.dyn RELA 0000000000001790 001790 001ea8 18 A 6 0 8 .init PROGBITS 0000000000004000 004000 00001b 00 AX 0 0 4 .text PROGBITS 0000000000004020 004020 0133d3 00 AX 0 0 16 .fini PROGBITS 00000000000173f4 0173f4 00000d 00 AX 0 0 4 .rodata PROGBITS 0000000000018000 018000 00514f 00 A 0 0 32 .eh_frame_hdr PROGBITS 000000000001d150 01d150 0005bc 00 A 0 0 4 .eh_frame PROGBITS 000000000001d710 01d710 0021a0 00 A 0 0 8 .init_array INIT_ARRAY 0000000000020f70 01ff70 000008 08 WA 0 0 8 .fini_array FINI_ARRAY 0000000000020f78 01ff78 000008 08 WA 0 0 8 .data.rel.ro PROGBITS 0000000000020f80 01ff80 000af8 00 WA 0 0 32 .dynamic DYNAMIC 0000000000021a78 020a78 0001c0 10 WA 7 0 8 .got PROGBITS 0000000000021c38 020c38 0003b0 08 WA 0 0 8 .data PROGBITS 0000000000022000 021000 000278 00 WA 0 0 32 .bss NOBITS 0000000000022280 021278 001298 00 WA 0 0 32 .comment PROGBITS 0000000000000000 021278 00001b 01 MS 0 0 1 .gnu_debuglink PROGBITS 0000000000000000 021294 000010 00 0 0 4 .shstrtab STRTAB 0000000000000000 0212a4 00010f 00 0 0 1 Key to Flags: W (write), A (alloc), X (execute), M (merge), S (strings), I (info), L (link order), O (extra OS processing required), G (group), T (TLS), C (compressed), x (unknown), o (OS specific), E (exclude), D (mbind), l (large), p (processor specific) Taking a look at offset for section headers and we can see that these two sections have the same offset value of 021278. Is it possible that these 2 sections share the same offset in file? I'm not sure. Any bug here? I noticed that also in other ELF files there are other sections that share the same offset like .bss section. Anyone could explain why there is such conflict in offsets?
user2699113 (197 rep)
Feb 1, 2024, 12:29 PM • Last activity: Feb 1, 2024, 01:05 PM
1 votes
0 answers
77 views
why some android elf file has interpreter path?
I am learning the elf file format for Android, but I have found that some elf files can specify the loader through the interpreter path in the program header. However, the elf test file I wrote myself through Android Studio does not have this attribute. What is the reason for this? In elf files with...
I am learning the elf file format for Android, but I have found that some elf files can specify the loader through the interpreter path in the program header. However, the elf test file I wrote myself through Android Studio does not have this attribute. What is the reason for this? In elf files with an interpreter path, I can specify my own loader linker to get an earlier elf debugging time, but now many files do not have an interpreter path. Is there any other alternative?
金坷垃金银花茶 (11 rep)
Jan 21, 2024, 10:34 AM
-1 votes
1 answers
305 views
Why do I get different results when running a program with ld-linux.so and when changing the interpreter with patchelf?
What's the difference between running a program with ld + --library-path and with changing the loader with patchelf? To illustrate, here is a binary that wouldn't run as is, presumably because of lack of recent versions of libraries: $ ~/DOWNLOADS/APPS/magick /tmp/.mount_magickXiWzgy/usr/bin/magick:...
What's the difference between running a program with ld + --library-path and with changing the loader with patchelf? To illustrate, here is a binary that wouldn't run as is, presumably because of lack of recent versions of libraries: $ ~/DOWNLOADS/APPS/magick /tmp/.mount_magickXiWzgy/usr/bin/magick: /lib/x86_64-linux-gnu/libm.so.6: version `GLIBC_2.29' not found (required by /tmp/.mount_magickXiWzgy/usr/lib/libMagickCore-7.Q16HDRI.so.10) /tmp/.mount_magickXiWzgy/usr/bin/magick: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.25' not found (required by /tmp/.mount_magickXiWzgy/usr/lib/libMagickCore-7.Q16HDRI.so.10) /tmp/.mount_magickXiWzgy/usr/bin/magick: /lib/x86_64-linux-gnu/libm.so.6: version `GLIBC_2.29' not found (required by /tmp/.mount_magickXiWzgy/usr/lib/liblcms2.so.2) ... $ I tried to run it with 3 other loaders and library paths, (core18, core20 and core22). Got ELF file ABI version invalid each time. $ /snap/core18/current/lib64/ld-linux-x86-64.so.2 --library-path /snap/core18/current/usr/lib/x86_64-linux-gnu/ ~/DOWNLOADS/APPS/magick /home/ychaouche/DOWNLOADS/APPS/magick: error while loading shared libraries: /home/ychaouche/DOWNLOADS/APPS/magick: ELF file ABI version invalid $ /snap/core20/current/lib64/ld-linux-x86-64.so.2 --library-path /snap/core20/current/usr/lib/x86_64-linux-gnu/ ~/DOWNLOADS/APPS/magick /home/ychaouche/DOWNLOADS/APPS/magick: error while loading shared libraries: /home/ychaouche/DOWNLOADS/APPS/magick: ELF file ABI version invalid $ /snap/core22/current/lib64/ld-linux-x86-64.so.2 --library-path /snap/core22/current/usr/lib/x86_64-linux-gnu/ ~/DOWNLOADS/APPS/magick /home/ychaouche/DOWNLOADS/APPS/magick: error while loading shared libraries: /home/ychaouche/DOWNLOADS/APPS/magick: ELF file ABI version invalid $ Then got a Segmentation fault when I tried to run it after changing the loader and the rpath directly in the binary with patchelf, like so: $ patchelf --set-interpreter /snap/core18/current/lib64/ld-linux-x86-64.so.2 --set-rpath /snap/core18/current/usr/lib/x86_64-linux-gnu/ magick $ ./magick Segmentation fault $ ldd magick not a dynamic executable $ even ldd fails to recognize it as a dynamic executable, although readelf can read it. here's output of ldd as requested by @user10489 $ file DOWNLOADS/APPS/magick DOWNLOADS/APPS/magick: ELF 64-bit LSB executable, x86-64, version 1, dynamically linked (uses shared libs), for GNU/Linux 2.6.32, BuildID[sha1]=9fdbc145689e0fb79cb7291203431012ae8e1911, stripped $ My question is why do I have ELF file ABI version invalid when specifying the loader from the command line, and a segmentation fault when changing the loader (and rpath) inside the binary?
ychaouche (1033 rep)
Jan 4, 2024, 03:42 PM • Last activity: Jan 8, 2024, 04:06 PM
3 votes
0 answers
123 views
Why is my 32 bit programs load in 3GB address space mode?
I have noticed, that Manjaro Linux (kernel 6.6.8) loads 32 bit executable files with ADDR_LIMIT_3GB set. Or as: `setarch -B --3g`. But I have a clear memory, that earlier it was not the case and 32 bit programs started in --4G mode. Is it hardcoded in the kernel or is configurable behavior? How to c...
I have noticed, that Manjaro Linux (kernel 6.6.8) loads 32 bit executable files with ADDR_LIMIT_3GB set. Or as: setarch -B --3g. But I have a clear memory, that earlier it was not the case and 32 bit programs started in --4G mode. Is it hardcoded in the kernel or is configurable behavior? How to change it?
johnfound (263 rep)
Jan 2, 2024, 12:28 PM • Last activity: Jan 5, 2024, 10:37 PM
Showing page 1 of 20 total questions