I am trying to compile and run the sockex3 example (sockex3_user.c and sockex3_kern.c from v5.10) in a new project (out of the kernel tree) with libbpf v0.3 as submodule of my repository. I have compiled the code with the following flags:
kernel (ebpf program)
set(CMAKE_C_COMPILER clang)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -g -target bpf")
user
set(CMAKE_C_COMPILER clang)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -g")
clang
$ clang -v
clang version 11.0.0
So, when I run the binary, I have faced the following error:
$ sudo ./build/samples/sockex3
[sudo] password for navarro:
libbpf: loading ./build/samples/bpf/CMakeFiles/sockex3_kern.dir/sockex3_kern.c.o
libbpf: elf: section(3) socket/3, size 1264, link 0, flags 6, type=1
libbpf: sec 'socket/3': found program 'bpf_func_PARSE_IP' at insn offset 0 (0 bytes), code size 158 insns (1264 bytes)
libbpf: elf: section(4) .relsocket/3, size 128, link 31, flags 0, type=9
libbpf: elf: section(5) socket/4, size 1360, link 0, flags 6, type=1
libbpf: sec 'socket/4': found program 'bpf_func_PARSE_IPV6' at insn offset 0 (0 bytes), code size 170 insns (1360 bytes)
libbpf: elf: section(6) .relsocket/4, size 112, link 31, flags 0, type=9
libbpf: elf: section(7) socket/1, size 256, link 0, flags 6, type=1
libbpf: sec 'socket/1': found program 'bpf_func_PARSE_VLAN' at insn offset 0 (0 bytes), code size 32 insns (256 bytes)
libbpf: elf: section(8) .relsocket/1, size 16, link 31, flags 0, type=9
libbpf: elf: section(9) socket/2, size 120, link 0, flags 6, type=1
libbpf: sec 'socket/2': found program 'bpf_func_PARSE_MPLS' at insn offset 0 (0 bytes), code size 15 insns (120 bytes)
libbpf: elf: section(10) .relsocket/2, size 16, link 31, flags 0, type=9
libbpf: elf: section(11) socket/0, size 32, link 0, flags 6, type=1
libbpf: sec 'socket/0': found program 'main_prog' at insn offset 0 (0 bytes), code size 4 insns (32 bytes)
libbpf: elf: section(12) license, size 4, link 0, flags 3, type=1
libbpf: license of ./build/samples/bpf/CMakeFiles/sockex3_kern.dir/sockex3_kern.c.o is GPL
libbpf: elf: section(13) .maps, size 96, link 0, flags 3, type=1
libbpf: elf: section(22) .BTF, size 4807, link 0, flags 0, type=1
libbpf: elf: section(24) .BTF.ext, size 2704, link 0, flags 0, type=1
libbpf: elf: section(31) .symtab, size 5904, link 1, flags 0, type=2
libbpf: looking for externs among 246 symbols...
libbpf: failed to find BTF for extern 'unlikely': -2
ERROR: opening BPF object file failed
I am trying to understand how/when this symbol is define. I found the symbol here.
Why libbpf is not finding it? Am I missing anything? FYI, I removed the uapi from the kernel file (sockex3_kern.c) and copied the dependencies (i.e. bpf_legacy.h) to my repository.
Another thing that I cant understand is why the sections (below) of the object file (out of the kernel tree) are different
31 .llvm_addrsig 00000012 0000000000000000 <--- Available in the object out of the tree
when comparing to the object file generated in the kernel tree.
Out-of-tree
$ llvm-objdump -h build/samples/bpf/CMakeFiles/sockex3_kern.dir/sockex3_kern.c.o
build/samples/bpf/CMakeFiles/sockex3_kern.dir/sockex3_kern.c.o: file format elf64-bpf
Sections:
Idx Name Size VMA Type
0 00000000 0000000000000000
1 .strtab 000002c2 0000000000000000
2 .text 00000000 0000000000000000 TEXT
3 socket/3 000004d0 0000000000000000 TEXT
4 .relsocket/3 00000070 0000000000000000
5 socket/4 00000550 0000000000000000 TEXT
6 .relsocket/4 00000070 0000000000000000
7 socket/1 00000100 0000000000000000 TEXT
8 .relsocket/1 00000010 0000000000000000
9 socket/2 00000078 0000000000000000 TEXT
10 .relsocket/2 00000010 0000000000000000
11 socket/0 000000e8 0000000000000000 TEXT
12 .relsocket/0 00000010 0000000000000000
13 license 00000004 0000000000000000 DATA
14 .maps 00000060 0000000000000000 DATA
15 .debug_loc 00000ef1 0000000000000000
16 .rel.debug_loc 00000370 0000000000000000
17 .debug_abbrev 000002b9 0000000000000000
18 .debug_info 00000f1b 0000000000000000
19 .rel.debug_info 000013c0 0000000000000000
20 .debug_ranges 000002e0 0000000000000000
21 .rel.debug_ranges 00000420 0000000000000000
22 .debug_str 000007c2 0000000000000000
23 .BTF 000012e1 0000000000000000
24 .rel.BTF 00000040 0000000000000000
25 .BTF.ext 00000ac0 0000000000000000
26 .rel.BTF.ext 00000a70 0000000000000000
27 .debug_frame 00000088 0000000000000000
28 .rel.debug_frame 000000a0 0000000000000000
29 .debug_line 0000049e 0000000000000000
30 .rel.debug_line 00000050 0000000000000000
31 .llvm_addrsig 00000012 0000000000000000
32 .symtab 00001788 0000000000000000
Kernel tree
$ llvm-objdump -h sockex3_kern.o
sockex3_kern.o: file format elf64-bpf
Sections:
Idx Name Size VMA Type
0 00000000 0000000000000000
1 .strtab 000002b1 0000000000000000
2 .text 00000000 0000000000000000 TEXT
3 socket/3 000004d8 0000000000000000 TEXT
4 .relsocket/3 00000070 0000000000000000
5 socket/4 00000558 0000000000000000 TEXT
6 .relsocket/4 00000070 0000000000000000
7 socket/1 00000100 0000000000000000 TEXT
8 .relsocket/1 00000010 0000000000000000
9 socket/2 00000078 0000000000000000 TEXT
10 .relsocket/2 00000010 0000000000000000
11 socket/0 000000e8 0000000000000000 TEXT
12 .relsocket/0 00000010 0000000000000000
13 license 00000004 0000000000000000 DATA
14 .maps 00000060 0000000000000000 DATA
15 .debug_loc 00000ef1 0000000000000000
16 .rel.debug_loc 00000370 0000000000000000
17 .debug_abbrev 0000029f 0000000000000000
18 .debug_info 00000d4b 0000000000000000
19 .rel.debug_info 000011b0 0000000000000000
20 .debug_ranges 000002e0 0000000000000000
21 .rel.debug_ranges 00000420 0000000000000000
22 .debug_str 0000067d 0000000000000000
23 .BTF 000012c2 0000000000000000
24 .rel.BTF 00000040 0000000000000000
25 .BTF.ext 00000ac0 0000000000000000
26 .rel.BTF.ext 00000a70 0000000000000000
27 .eh_frame 000000b0 0000000000000000 DATA
28 .rel.eh_frame 00000050 0000000000000000
29 .debug_line 0000046b 0000000000000000
30 .rel.debug_line 00000050 0000000000000000
31 .symtab 00001500 0000000000000000
Thank you in advance!
Related
When trying to run the command,
sudo tc filter add dev veth0 egress bpf direct-action obj a.o sec classifier
I'm getting this error,
libbpf: prog 'pdm_main': bad map relo against '.rodata.str1.1' in section '.rodata.str1.1'
ERROR: opening BPF object file failed
Unable to load program
The sections in my object file,
Sections:
Idx Name Size VMA LMA File off Algn
0 .text 00000000 0000000000000000 0000000000000000 00000040 2**2
CONTENTS, ALLOC, LOAD, READONLY, CODE
1 classifier 00000638 0000000000000000 0000000000000000 00000040 2**3
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
2 .maps 00000020 0000000000000000 0000000000000000 00000678 2**3
CONTENTS, ALLOC, LOAD, DATA
3 .rodata.str1.1 0000002c 0000000000000000 0000000000000000 00000698 2**0
CONTENTS, ALLOC, LOAD, READONLY, DATA
4 .rodata.str1.16 00000036 0000000000000000 0000000000000000 000006d0 2**4
CONTENTS, ALLOC, LOAD, READONLY, DATA
5 license 00000004 0000000000000000 0000000000000000 00000706 2**0
CONTENTS, ALLOC, LOAD, DATA
6 .debug_loclists 00000105 0000000000000000 0000000000000000 0000070a 2**0
CONTENTS, READONLY, DEBUGGING, OCTETS
7 .debug_abbrev 000001c9 0000000000000000 0000000000000000 0000080f 2**0
CONTENTS, READONLY, DEBUGGING, OCTETS
8 .debug_info 0000080f 0000000000000000 0000000000000000 000009d8 2**0
CONTENTS, RELOC, READONLY, DEBUGGING, OCTETS
9 .debug_str_offsets 000002a4 0000000000000000 0000000000000000 000011e7 2**0
CONTENTS, RELOC, READONLY, DEBUGGING, OCTETS
10 .debug_str 000006ec 0000000000000000 0000000000000000 0000148b 2**0
CONTENTS, READONLY, DEBUGGING, OCTETS
11 .debug_addr 00000030 0000000000000000 0000000000000000 00001b77 2**0
CONTENTS, RELOC, READONLY, DEBUGGING, OCTETS
12 .BTF 00001037 0000000000000000 0000000000000000 00001ba8 2**2
CONTENTS, RELOC, READONLY
13 .BTF.ext 00000470 0000000000000000 0000000000000000 00002be0 2**2
CONTENTS, RELOC, READONLY
14 .eh_frame 00000030 0000000000000000 0000000000000000 00003050 2**3
CONTENTS, ALLOC, LOAD, RELOC, READONLY, DATA
15 .debug_line 00000220 0000000000000000 0000000000000000 00003080 2**0
CONTENTS, RELOC, READONLY, DEBUGGING, OCTETS
16 .debug_line_str 000000f8 0000000000000000 0000000000000000 000032a0 2**0
CONTENTS, READONLY, DEBUGGING, OCTETS
How to fix this? When i don't use eBPF map in my code it doesn't give the same error.
I am currently writing a compiler (http://curly-lang.org if you're curious), and have been encountering a strange bug when trying to run the generated ELF binaries on the latest Linux kernel. The same binaries run fine on older kernels (I've tried on several Ubuntu boxes, uname 4.4.0-1049-aws), but on my updated Arch box (uname 4.17.11-arch1), I can't even open them under GDB.
The error message given by GDB is During startup program terminated with signal SIGSEGV, Segmentation fault, which as I understand is indicative of a failure to load the program segments before the first instruction is ever run.
I compiled a minimal ELF executable with GCC/NASM to try and reproduce the problem, but the GCC-produced executable loads without a hitch, whereas my programs definitely do not.
Here are the printouts of readelf -a for both executables, for reference. The first is the program generated by my compiler :
$ readelf -a my-program
ELF Header:
Magic: 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00
Class: ELF64
Data: 2's complement, little endian
Version: 1 (current)
OS/ABI: UNIX - System V
ABI Version: 0
Type: EXEC (Executable file)
Machine: Advanced Micro Devices X86-64
Version: 0x1
Entry point address: 0x400040
Start of program headers: 2400 (bytes into file)
Start of section headers: 2568 (bytes into file)
Flags: 0x0
Size of this header: 64 (bytes)
Size of program headers: 56 (bytes)
Number of program headers: 3
Size of section headers: 64 (bytes)
Number of section headers: 6
Section header string table index: 1
Section Headers:
[Nr] Name Type Address Offset
Size EntSize Flags Link Info Align
[ 0] NULL 0000000000000000 00000000
0000000000000000 0000000000000000 0 0 0
[ 1] STRTAB 0000000000000000 00000b88
000000000000009e 0000000000000000 0 0 0
[ 2] .init PROGBITS 0000000000400040 00000040
000000000000006b 0000000000000000 AX 0 0 0
[ 3] .text PROGBITS 00000000004000ab 000000ab
0000000000000824 0000000000000000 AX 0 0 0
[ 4] .data PROGBITS 00000000008008cf 000008cf
0000000000000091 0000000000000000 WA 0 0 0
[ 5] .symtab SYMTAB 0000000000000000 00000c26
00000000000000c0 0000000000000018 1 8 0
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),
l (large), p (processor specific)
There are no section groups in this file.
Program Headers:
Type Offset VirtAddr PhysAddr
FileSiz MemSiz Flags Align
LOAD 0x0000000000000040 0x0000000000400040 0x0000000000000000
0x000000000000006b 0x000000000000006b R E 0x1000
LOAD 0x00000000000000ab 0x00000000004000ab 0x0000000000000000
0x0000000000000824 0x0000000000000824 R E 0x1000
LOAD 0x00000000000008cf 0x00000000008008cf 0x0000000000000000
0x0000000000000091 0x0000000000000091 RW 0x1000
Section to Segment mapping:
Segment Sections...
00 .init
01 .text
02 .data
There is no dynamic section in this file.
There are no relocations in this file.
The decoding of unwind sections for machine type Advanced Micro Devices X86-64 is not currently supported.
Symbol table '.symtab' contains 8 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 00000000004004e0 0 NOTYPE LOCAL HIDDEN 3 .text.argument
1: 00000000004005a0 0 NOTYPE LOCAL HIDDEN 3 .text.constant
2: 0000000000400270 0 NOTYPE LOCAL HIDDEN 3 .text.memextend-page
3: 0000000000400210 0 NOTYPE LOCAL HIDDEN 3 .text.memextend-pool-32
4: 00000000004002b0 0 NOTYPE LOCAL HIDDEN 3 .text.unit
5: 00000000004005f0 0 NOTYPE LOCAL HIDDEN 3 .text.write
6: 00000000008008d0 0 NOTYPE LOCAL HIDDEN 4 .data.brkaddr
7: 0000000000400040 0 NOTYPE LOCAL HIDDEN 2 .init.brkaddr-init
No version information found in this file.
And for the GCC-generated program :
$ readelf -a gcc-program
ELF Header:
Magic: 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00
Class: ELF64
Data: 2's complement, little endian
Version: 1 (current)
OS/ABI: UNIX - System V
ABI Version: 0
Type: EXEC (Executable file)
Machine: Advanced Micro Devices X86-64
Version: 0x1
Entry point address: 0x400110
Start of program headers: 64 (bytes into file)
Start of section headers: 336 (bytes into file)
Flags: 0x0
Size of this header: 64 (bytes)
Size of program headers: 56 (bytes)
Number of program headers: 3
Size of section headers: 64 (bytes)
Number of section headers: 5
Section header string table index: 4
Section Headers:
[Nr] Name Type Address Offset
Size EntSize Flags Link Info Align
[ 0] NULL 0000000000000000 00000000
0000000000000000 0000000000000000 0 0 0
[ 1] .note.gnu.build-i NOTE 00000000004000e8 000000e8
0000000000000024 0000000000000000 A 0 0 4
[ 2] .text PROGBITS 0000000000400110 00000110
0000000000000010 0000000000000000 AX 0 0 16
[ 3] .data PROGBITS 0000000000600120 00000120
0000000000000001 0000000000000000 WA 0 0 4
[ 4] .shstrtab STRTAB 0000000000000000 00000121
000000000000002a 0000000000000000 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),
l (large), p (processor specific)
There are no section groups in this file.
Program Headers:
Type Offset VirtAddr PhysAddr
FileSiz MemSiz Flags Align
LOAD 0x0000000000000000 0x0000000000400000 0x0000000000400000
0x0000000000000120 0x0000000000000120 R E 0x200000
LOAD 0x0000000000000120 0x0000000000600120 0x0000000000600120
0x0000000000000001 0x0000000000000001 RW 0x200000
NOTE 0x00000000000000e8 0x00000000004000e8 0x00000000004000e8
0x0000000000000024 0x0000000000000024 R 0x4
Section to Segment mapping:
Segment Sections...
00 .note.gnu.build-id .text
01 .data
02 .note.gnu.build-id
There is no dynamic section in this file.
There are no relocations in this file.
The decoding of unwind sections for machine type Advanced Micro Devices X86-64 is not currently supported.
No version information found in this file.
Displaying notes found in: .note.gnu.build-id
Owner Data size Description
GNU 0x00000014 NT_GNU_BUILD_ID (unique build ID bitstring)
Build ID: 1a3e678b08996ee6a9d289c3f76c7c52cd4a30aa
As you can see, I've tried to mirror GCC's segment placement (~0x400000 for the code, and ~0x800000 for the data), and the two ELF headers are strictly identical. The only meaningful difference I can think of is that my custom binaries have two LOAD segments (one for the initialization code, one for the rest) that share the same page, whereas GCC only produces a single code LOAD segment. That shouldn't pose a problem, though, since they both share the same permissions and don't overlap.
Other than that, I do not see what could possibly keep the first program from loading correctly. If anyone well-versed in the arcanes of the Linux ELF loader could enlighten me, that would be greatly appreciated.
Thank you for your attention,
Nevermind everyone, it was the page-sharing segments that were causing the problem all along.
Thinking the problem was probably in the kernel loader, I should have thought about running dmesg much earlier, where I would have noticed the following message, clear as day :
[54178.211348] 12766 (my-program): Uhuuh, elf segment at 0000000000400000 requested but the memory is mapped already
Apparently, some benevolent mastermind decided 3 months ago that it would be good to actually catch double-mapping errors instead of just letting them go silently as we always did in the ELF loader.
It's not that my binaries used to be correct, it's that the error they were causing wasn't caught before. I don't know if I should be proud or ashamed for my bugs to have eluded detection all this time.
Anyway, I leave this answer to warn anyone foolish enough to map multiple segments on a single page in an ELF binary : do not. There is no try.
PS: #rodrigo: Thanks for your answer, I didn't even notice the PhysAddr before you pointed them out. The manual says that they're used "on systems where physical addressing is relevant", which doesn't seem to be the case here, but I'll remember to keep a lookout for them next time.
Background
"OS": Stripped down Linux, very customized, no internet access (no yum, apt-get, etc)
Kernel: 2.6.19.1
Target: 32-bit, armv5te
Current LibC: 2.3.6
Target LibC: 2.6.1
Issue
Received an .ipk from a 3rd party vendor containing an updated version of glibc. Started by investigating the compatibility of the shared objects contained within the .ipk package by placing them on the target platform and attempting to run the ld-2.6.1.so directly (chose this library because my understanding is that it has no dynamic linking to other objects).
Running this shared object library directly results in "Illegal Instruction". My initial thought was that ld was built for the wrong architecture, however, review of the readelf output appears to indicate it was set up correctly:
[root#blg_g34_z2_03 lib]# readelf -a ld-2.6.1.so
ELF Header:
Magic: 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00
Class: ELF32
Data: 2's complement, little endian
Version: 1 (current)
OS/ABI: UNIX - System V
ABI Version: 0
Type: DYN (Shared object file)
Machine: ARM
Version: 0x1
Entry point address: 0x800
Start of program headers: 52 (bytes into file)
Start of section headers: 116488 (bytes into file)
Flags: 0x4000002, has entry point, Version4 EABI
Size of this header: 52 (bytes)
Size of program headers: 32 (bytes)
Number of program headers: 6
Size of section headers: 40 (bytes)
Number of section headers: 26
Section header string table index: 25
Section Headers:
[Nr] Name Type Addr Off Size ES Flg Lk Inf Al
[ 0] NULL 00000000 000000 000000 00 0 0 0
[ 1] .hash HASH 000000f4 0000f4 0000c4 04 A 3 0 4
[ 2] .gnu.hash GNU_HASH 000001b8 0001b8 0000e0 04 A 3 0 4
[ 3] .dynsym DYNSYM 00000298 000298 0001e0 10 A 4 3 4
[ 4] .dynstr STRTAB 00000478 000478 0001ac 00 A 0 0 1
[ 5] .gnu.version VERSYM 00000624 000624 00003c 02 A 3 0 2
[ 6] .gnu.version_d VERDEF 00000660 000660 00005c 00 A 4 3 4
[ 7] .rel.dyn REL 000006bc 0006bc 0000b8 08 A 3 0 4
[ 8] .rel.plt REL 00000774 000774 000030 08 A 3 9 4
[ 9] .plt PROGBITS 000007a4 0007a4 00005c 04 AX 0 0 4
[10] .text PROGBITS 00000800 000800 017324 00 AX 0 0 16
[11] __libc_freeres_fn PROGBITS 00017b24 017b24 000148 00 AX 0 0 4
[12] .rodata PROGBITS 00017c6c 017c6c 003828 00 A 0 0 4
[13] .ARM.extab PROGBITS 0001b494 01b494 000048 00 A 0 0 4
[14] .ARM.exidx ARM_EXIDX 0001b4dc 01b4dc 000078 00 AL 10 0 4
[15] .eh_frame_hdr PROGBITS 0001b554 01b554 00001c 00 A 0 0 4
[16] .eh_frame PROGBITS 0001b570 01b570 00007c 00 A 0 0 4
[17] .data.rel.ro PROGBITS 00023db0 01bdb0 000194 00 WA 0 0 8
[18] .dynamic DYNAMIC 00023f44 01bf44 0000b8 08 WA 4 0 4
[19] .got PROGBITS 00024000 01c000 00005c 04 WA 0 0 4
[20] .data PROGBITS 00024060 01c060 000580 00 WA 0 0 8
[21] __libc_subfreeres PROGBITS 000245e0 01c5e0 000004 00 WA 0 0 4
[22] .bss NOBITS 000245e4 01c5e4 0000e4 00 WA 0 0 4
[23] .ARM.attributes ARM_ATTRIBUTES 00000000 01c5e4 000019 00 0 0 1
[24] .gnu_debuglink PROGBITS 00000000 01c5fd 000010 00 0 0 1
[25] .shstrtab STRTAB 00000000 01c60d 0000f8 00 0 0 1
Key to Flags:
W (write), A (alloc), X (execute), M (merge), S (strings)
I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown)
O (extra OS processing required) o (OS specific), p (processor specific)
There are no section groups in this file.
Program Headers:
Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
EXIDX 0x01b4dc 0x0001b4dc 0x0001b4dc 0x00078 0x00078 R 0x4
LOAD 0x000000 0x00000000 0x00000000 0x1b5ec 0x1b5ec R E 0x8000
LOAD 0x01bdb0 0x00023db0 0x00023db0 0x00834 0x00918 RW 0x8000
DYNAMIC 0x01bf44 0x00023f44 0x00023f44 0x000b8 0x000b8 RW 0x4
GNU_EH_FRAME 0x01b554 0x0001b554 0x0001b554 0x0001c 0x0001c R 0x4
GNU_RELRO 0x01bdb0 0x00023db0 0x00023db0 0x00250 0x00250 R 0x1
Section to Segment mapping:
Segment Sections...
00 .ARM.exidx
01 .hash .gnu.hash .dynsym .dynstr .gnu.version .gnu.version_d .rel.dyn .rel.plt .plt .text __libc_freeres_fn .rodata .ARM.extab .ARM.exidx .eh_frame_hdr .eh_frame
02 .data.rel.ro .dynamic .got .data __libc_subfreeres .bss
03 .dynamic
04 .eh_frame_hdr
05 .data.rel.ro .dynamic
Dynamic section at offset 0x1bf44 contains 19 entries:
Tag Type Name/Value
0x0000000e (SONAME) Library soname: [ld-linux.so.3]
0x00000004 (HASH) 0xf4
0x6ffffef5 (GNU_HASH) 0x1b8
0x00000005 (STRTAB) 0x478
0x00000006 (SYMTAB) 0x298
0x0000000a (STRSZ) 428 (bytes)
0x0000000b (SYMENT) 16 (bytes)
0x00000003 (PLTGOT) 0x24000
0x00000002 (PLTRELSZ) 48 (bytes)
0x00000014 (PLTREL) REL
0x00000017 (JMPREL) 0x774
0x00000011 (REL) 0x6bc
0x00000012 (RELSZ) 184 (bytes)
0x00000013 (RELENT) 8 (bytes)
0x6ffffffc (VERDEF) 0x660
0x6ffffffd (VERDEFNUM) 3
0x6ffffff0 (VERSYM) 0x624
0x6ffffffa (RELCOUNT) 20
0x00000000 (NULL) 0x0
Relocation section '.rel.dyn' at offset 0x6bc contains 23 entries:
Offset Info Type Sym.Value Sym. Name
00023e8c 00000017 R_ARM_RELATIVE
00023e90 00000017 R_ARM_RELATIVE
00023e94 00000017 R_ARM_RELATIVE
00023e98 00000017 R_ARM_RELATIVE
00023e9c 00000017 R_ARM_RELATIVE
00023ea0 00000017 R_ARM_RELATIVE
00023ea4 00000017 R_ARM_RELATIVE
00023ea8 00000017 R_ARM_RELATIVE
00024024 00000017 R_ARM_RELATIVE
00024028 00000017 R_ARM_RELATIVE
00024030 00000017 R_ARM_RELATIVE
00024038 00000017 R_ARM_RELATIVE
0002403c 00000017 R_ARM_RELATIVE
00024040 00000017 R_ARM_RELATIVE
00024044 00000017 R_ARM_RELATIVE
00024048 00000017 R_ARM_RELATIVE
0002404c 00000017 R_ARM_RELATIVE
00024050 00000017 R_ARM_RELATIVE
00024054 00000017 R_ARM_RELATIVE
000245e0 00000017 R_ARM_RELATIVE
0002402c 00001b15 R_ARM_GLOB_DAT 00023f0c __stack_chk_guard
00024034 00001815 R_ARM_GLOB_DAT 00014c84 malloc
00024058 00000b15 R_ARM_GLOB_DAT 000246b4 _r_debug
Relocation section '.rel.plt' at offset 0x774 contains 6 entries:
Offset Info Type Sym.Value Sym. Name
0002400c 00000e16 R_ARM_JUMP_SLOT 00014b50 __libc_memalign
00024010 00001816 R_ARM_JUMP_SLOT 00014c84 malloc
00024014 00001016 R_ARM_JUMP_SLOT 00014d38 calloc
00024018 00000916 R_ARM_JUMP_SLOT 00014c90 realloc
0002401c 00000716 R_ARM_JUMP_SLOT 000086d4 _dl_cache_libcmp
00024020 00000816 R_ARM_JUMP_SLOT 00014b08 free
Unwind table index '.ARM.exidx' at offset 0x1b4dc contains 15 entries:
0x8ed4: 0x80b0b0b0
Compact model index: 0
0xb0 finish
0xb0 finish
0xb0 finish
0x8f0c: 0x8000abb0
Compact model index: 0
0x00 vsp = vsp + 4
0xab pop {r4, r5, r6, r7, r14}
0xb0 finish
0x8ff0: 0x8000abb0
Compact model index: 0
0x00 vsp = vsp + 4
0xab pop {r4, r5, r6, r7, r14}
0xb0 finish
0x91b0: 0x800eafb0
Compact model index: 0
0x0e vsp = vsp + 60
0xaf pop {r4, r5, r6, r7, r8, r9, r10, r11, r14}
0xb0 finish
0x9574: #0x1b494
Compact model index: 1
0x9b vsp = r11
0x49 vsp = vsp - 40
0x86 0xff pop {r4, r5, r6, r7, r8, r9, r10, r11, r13, r14}
0xb0 finish
0xb0 finish
0xcf44: 0x800aafb0
Compact model index: 0
0x0a vsp = vsp + 44
0xaf pop {r4, r5, r6, r7, r8, r9, r10, r11, r14}
0xb0 finish
0xd060: 0x8014afb0
Compact model index: 0
0x14 vsp = vsp + 84
0xaf pop {r4, r5, r6, r7, r8, r9, r10, r11, r14}
0xb0 finish
0xd5c0: 0x8006afb0
Compact model index: 0
0x06 vsp = vsp + 28
0xaf pop {r4, r5, r6, r7, r8, r9, r10, r11, r14}
0xb0 finish
0x15380: #0x1b4a0
Compact model index: 1
0x01 vsp = vsp + 8
0x80 0x08 pop {r7}
0xb1 0x0e pop {r1, r2, r3}
0xb0 finish
0x158c0: #0x1b4ac
Compact model index: 1
0x02 vsp = vsp + 12
0xb1 0x0f pop {r0, r1, r2, r3}
0x8f 0xff pop {r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15}
0xb0 finish
0x158d8: #0x1b4b8
Compact model index: 1
0x07 vsp = vsp + 32
0xb1 0x0f pop {r0, r1, r2, r3}
0x8f 0xff pop {r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15}
0xb0 finish
0x158e8: #0x1b4c4
Compact model index: 1
0x29 vsp = vsp + 168
0xb1 0x0f pop {r0, r1, r2, r3}
0x8f 0xff pop {r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15}
0xb0 finish
0x158f8: #0x1b4d0
Compact model index: 1
0x27 vsp = vsp + 160
0xb1 0x0f pop {r0, r1, r2, r3}
0x8f 0xff pop {r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15}
0xb0 finish
0x1704c: 0x8004afb0
Compact model index: 0
0x04 vsp = vsp + 20
0xaf pop {r4, r5, r6, r7, r8, r9, r10, r11, r14}
0xb0 finish
0x17580: 0x8002afb0
Compact model index: 0
0x02 vsp = vsp + 12
0xaf pop {r4, r5, r6, r7, r8, r9, r10, r11, r14}
0xb0 finish
Symbol table '.dynsym' contains 30 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 00000000 0 NOTYPE LOCAL DEFAULT UND
1: 00000800 0 SECTION LOCAL DEFAULT 10
2: 00023db0 0 SECTION LOCAL DEFAULT 17
3: 000103d4 44 FUNC GLOBAL DEFAULT 10 _dl_get_tls_static_info##GLIBC_PRIVATE
4: 00023f10 4 OBJECT GLOBAL DEFAULT 17 __pointer_chk_guard##GLIBC_PRIVATE
5: 00000000 0 OBJECT GLOBAL DEFAULT ABS GLIBC_PRIVATE
6: 00000000 0 OBJECT GLOBAL DEFAULT ABS GLIBC_2.4
7: 000086d4 260 FUNC GLOBAL DEFAULT 10 _dl_cache_libcmp##GLIBC_PRIVATE
8: 00014b08 72 FUNC WEAK DEFAULT 10 free##GLIBC_2.4
9: 00014c90 168 FUNC WEAK DEFAULT 10 realloc##GLIBC_2.4
10: 00010ed8 40 FUNC GLOBAL DEFAULT 10 _dl_allocate_tls##GLIBC_PRIVATE
11: 000246b4 20 OBJECT GLOBAL DEFAULT 22 _r_debug##GLIBC_2.4
12: 00023f3c 4 OBJECT GLOBAL DEFAULT 17 __libc_stack_end##GLIBC_2.4
13: 0001063c 160 FUNC GLOBAL DEFAULT 10 _dl_tls_get_addr_soft##GLIBC_PRIVATE
14: 00014b50 308 FUNC WEAK DEFAULT 10 __libc_memalign##GLIBC_2.4
15: 00010920 192 FUNC GLOBAL DEFAULT 10 _dl_deallocate_tls##GLIBC_PRIVATE
16: 00014d38 92 FUNC WEAK DEFAULT 10 calloc##GLIBC_2.4
17: 000245e4 4 OBJECT GLOBAL DEFAULT 22 _dl_argv##GLIBC_PRIVATE
18: 0000f474 1384 FUNC GLOBAL DEFAULT 10 _dl_mcount##GLIBC_2.4
19: 0001117c 204 FUNC GLOBAL DEFAULT 10 _dl_tls_setup##GLIBC_PRIVATE
20: 0000e598 4 FUNC GLOBAL DEFAULT 10 _dl_debug_state##GLIBC_PRIVATE
21: 00024060 1408 OBJECT GLOBAL DEFAULT 20 _rtld_global##GLIBC_PRIVATE
22: 00010ce4 272 FUNC GLOBAL DEFAULT 10 __tls_get_addr##GLIBC_2.4
23: 00011404 188 FUNC GLOBAL DEFAULT 10 _dl_make_stack_executable##GLIBC_PRIVATE
24: 00014c84 12 FUNC WEAK DEFAULT 10 malloc##GLIBC_2.4
25: 000106dc 540 FUNC GLOBAL DEFAULT 10 _dl_allocate_tls_init##GLIBC_PRIVATE
26: 00023db0 264 OBJECT GLOBAL DEFAULT 17 _rtld_global_ro##GLIBC_PRIVATE
27: 00023f0c 4 OBJECT GLOBAL DEFAULT 17 __stack_chk_guard##GLIBC_2.4
28: 00023f38 4 OBJECT GLOBAL DEFAULT 17 __libc_enable_secure##GLIBC_PRIVATE
29: 00007bc0 456 FUNC GLOBAL DEFAULT 10 _dl_rtld_di_serinfo##GLIBC_PRIVATE
Histogram for bucket list length (total of 17 buckets):
Length Number % of total Coverage
0 2 ( 11.8%)
1 6 ( 35.3%) 22.2%
2 6 ( 35.3%) 66.7%
3 3 ( 17.6%) 100.0%
Histogram for `.gnu.hash' bucket list length (total of 17 buckets):
Length Number % of total Coverage
0 2 ( 11.8%)
1 8 ( 47.1%) 29.6%
2 3 ( 17.6%) 51.9%
3 3 ( 17.6%) 85.2%
4 1 ( 5.9%) 100.0%
Version symbols section '.gnu.version' contains 30 entries:
Addr: 0000000000000624 Offset: 0x000624 Link: 3 (.dynsym)
000: 0 (*local*) 0 (*local*) 0 (*local*) 3 (GLIBC_PRIVATE)
004: 3 (GLIBC_PRIVATE) 3 (GLIBC_PRIVATE) 2 (GLIBC_2.4) 3 (GLIBC_PRIVATE)
008: 2 (GLIBC_2.4) 2 (GLIBC_2.4) 3 (GLIBC_PRIVATE) 2 (GLIBC_2.4)
00c: 2 (GLIBC_2.4) 3 (GLIBC_PRIVATE) 2 (GLIBC_2.4) 3 (GLIBC_PRIVATE)
010: 2 (GLIBC_2.4) 3 (GLIBC_PRIVATE) 2 (GLIBC_2.4) 3 (GLIBC_PRIVATE)
014: 3 (GLIBC_PRIVATE) 3 (GLIBC_PRIVATE) 2 (GLIBC_2.4) 3 (GLIBC_PRIVATE)
018: 2 (GLIBC_2.4) 3 (GLIBC_PRIVATE) 3 (GLIBC_PRIVATE) 2 (GLIBC_2.4)
01c: 3 (GLIBC_PRIVATE) 3 (GLIBC_PRIVATE)
Version definition section '.gnu.version_d' contains 3 entries:
Addr: 0x0000000000000660 Offset: 0x000660 Link: 4 (.dynstr)
000000: Rev: 1 Flags: BASE Index: 1 Cnt: 1 Name: ld-linux.so.3
0x001c: Rev: 1 Flags: none Index: 2 Cnt: 1 Name: GLIBC_2.4
0x0038: Rev: 1 Flags: none Index: 3 Cnt: 2 Name: GLIBC_PRIVATE
0x0054: Parent 1: GLIBC_2.4
Attribute Section: aeabi
File Attributes
Tag_CPU_name: "5TE"
Tag_CPU_arch: v5TE
Tag_ARM_ISA_use: Yes
My next thought was that I know glibc provides an interface to the kernel, so perhaps it was expecting a kernel version different from 2.6.19.1. However I am not sure how to determine what version of the kernel ld is targeting.
I can post more information as its requested, open to any and all ideas. Thanks in advance.
My next thought was that I know glibc provides an interface to the kernel, so perhaps it was expecting a kernel version different from 2.6.19.1. However I am not sure how to determine what version of the kernel ld is targeting.
You can find out what kernel this build requires with readelf -n libc.so.6, which will produce something like:
Notes at offset 0x00000254 with length 0x00000020:
Owner Data size Description
GNU 0x00000010 NT_GNU_ABI_TAG (ABI version tag)
OS: Linux, ABI: 2.6.15 <--- this is the minimal kernel version
That said, the ld-linux should not crash with SIGILL when running on a too-old kernel. It actually tried to execute illegal instruction, and your next step should be to try to figure out which instruction that is.
gdb ./ld-2.6.1.so
(gdb) run
... wait for SIGILL
(gdb) x/i $pc <--- this will show the instruction causing SIGILL
(gdb) where <--- this will show how you got to that instruction.
Running this shared object library directly
Does any other dynamically linked binary work on this system when using this build of GLIBC?
While running ld-linux directly should work, it's not how it normally runs, so if everything else works fine, maybe you don't actually have a problem.
I'm trying to drop a C program down to a size < 1kb. I'm getting close, but I'm stuck on editing my ELF executable. My program, main.c looks like:
#include<unistd.h>
#include<sys/syscall.h>
void _start() {
const char msg [] = "Hello World!";
syscall(SYS_write, 0, msg, sizeof(msg)-1);
syscall(SYS_exit, 0);
}
I'm compiling it with
gcc -nostdlib -s -O3 -o main main.c /usr/lib/path/to/libc.a
Then I strip it. But If I did an objdump on it before stripping it I see
main: file format elf64-x86-64
SYMBOL TABLE:
0000000000400158 l d .note.gnu.build-id 0000000000000000 .note.gnu.build-id
0000000000400180 l d .text 0000000000000000 .text
0000000000400214 l d .eh_frame_hdr 0000000000000000 .eh_frame_hdr
0000000000400238 l d .eh_frame 0000000000000000 .eh_frame
0000000000601000 l d .tbss 0000000000000000 .tbss
0000000000000000 l d .comment 0000000000000000 .comment
0000000000000000 l df *ABS* 0000000000000000 main.c
0000000000000000 l df *ABS* 0000000000000000
00000000004001d0 g F .text 0000000000000026 syscall
0000000000000000 g .tbss 0000000000000004 errno
0000000000400203 g .text 0000000000000000 __syscall_error_1
0000000000400180 g F .text 0000000000000048 _start
0000000000000000 g .tbss 0000000000000004 __libc_errno
0000000000400200 g F .text 0000000000000013 __syscall_error
0000000000601000 g .eh_frame 0000000000000000 __bss_start
0000000000601000 g .eh_frame 0000000000000000 _edata
0000000000000000 *UND* 0000000000000000 _GLOBAL_OFFSET_TABLE_
0000000000601000 g .eh_frame 0000000000000000 _end
It seems like there's some stuff I can remove to manually reduce the size of the executable? note: I know this is not something I'd actually do, but I'm simply trying to remove any boilerplate existing.
What would I remove from the executable, main, to reduce it's size? And how could I do that?
side note: I've already read this and this article. No need to link them. I am purposely choosing to stay with C
Simple stuff
You can remove quite a few useless bits with:
-fno-asynchronous-unwind-tables -Qn;
using a custom linker script -rlinker_script.
I get a working binary of 992 bytes with this (after strip).
Linker script
Let's look at the sections (before stripping):
[Nr] Name Type Address Offset
Size EntSize Flags Link Info Align
[ 0] NULL 0000000000000000 00000000
0000000000000000 0000000000000000 0 0 0
[ 1] .note.gnu.build-i NOTE 0000000000400120 00000120
0000000000000024 0000000000000000 A 0 0 4
[ 2] .text PROGBITS 0000000000400150 00000150
0000000000000090 0000000000000000 AX 0 0 16
[ 3] .eh_frame PROGBITS 00000000004001e0 000001e0
0000000000000048 0000000000000000 A 0 0 8
[ 4] .tbss NOBITS 0000000000601000 00000228
0000000000000004 0000000000000000 WAT 0 0 4
[ 5] .shstrtab STRTAB 0000000000000000 000003e7
0000000000000044 0000000000000000 0 0 1
[ 6] .symtab SYMTAB 0000000000000000 00000228
0000000000000168 0000000000000018 7 6 8
[ 7] .strtab STRTAB 0000000000000000 00000390
0000000000000057 0000000000000000
From program header 5, everything is stripped but we gave two comparatively useless sections which are not stripped: .note.gnu.build-id and .eh_frame. The .eh_frame was disabled in the compiler but some .eh_frame is contributed from the static libc.
We can completely get rid of the .eh_frame and .note.gnu.build-id sections with a custom linker script (gcc -T linker_script).
First, we get the default linker script:
gcc test.c -Wl,--verbose
We remove those lines:
.eh_frame_hdr : { *(.eh_frame_hdr) *(.eh_frame_entry .eh_frame_entry.*) }
.eh_frame : ONLY_IF_RO { KEEP (*(.eh_frame)) *(.eh_frame.*) }
.note.gnu.build-id : { *(.note.gnu.build-id) }
and modify this line:
/DISCARD/ : { *(.note.GNU-stack) *(.gnu_debuglink) *(.gnu.lto_*) *(.note.gnu.build-id) *(.eh_frame_hdr) *(.eh_frame_entry .eh_frame_entry.*) *(.eh_frame) *(.eh_frame.*) }
I get 664 bytes using this.
Additional options
Other solutions for a reduced size:
optimize for size (-Os);
32 bit compilation (-m32).
With all of this, I get a binary with 760 bytes without the custom linker script and 488 bytes with the modified linker script.
Get rid of errno
There are quite few "useless" things remaining (such as errno handling and the TLS) that could be removed.
[Nr] Name Type Addr Off Size ES Flg Lk Inf Al
[ 0] NULL 00000000 000000 000000 00 0 0 0
[ 1] .text PROGBITS 080480a0 0000a0 00008e 00 AX 0 0 16
[ 2] .tbss NOBITS 08049130 000130 000004 00 WAT 0 0 4
[ 3] .shstrtab STRTAB 00000000 000257 000027 00 0 0 1
[ 4] .symtab SYMTAB 00000000 000130 0000d0 10 5 4 4
[ 5] .strtab STRTAB 00000000 000200 000057 00 0 0 1
(Everything beginning with section 3 is stripped.)
By writing our own syscall code we could get rid of errno handling. We would remove:
4 bytes of .symtab;
errno related instructions.
But doing this involves using (inline) assembly.
I was installing a binary Linux application on Ubuntu 9.10 x86_64. The app shipped with an old version of gzip (1.2.4), that was compiled for a much older kernel:
$ file gzip
gzip: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.0.0, stripped
I wasn't able to execute this program. If I tried, this happened:
$ ./gzip
-bash: ./gzip: No such file or directory
ldd was similarly unhappy with this binary:
$ ldd gzip
not a dynamic executable
I'm curious: What's the most likely source of this problem? A corrupted file? Or a binary incompatibility due to being built for a much older {kernel,libc,...}?
Per nos's suggestsions, here's the output of strace ./gzip:
execve("./gzip", ["./gzip"], [/* 24 vars */]) = -1 ENOENT (No such file or directory)
dup(2) = 3
fcntl(3, F_GETFL) = 0x8002 (flags O_RDWR|O_LARGEFILE)
fstat(3, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 10), ...}) = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fa8c9eee000
lseek(3, 0, SEEK_CUR) = -1 ESPIPE (Illegal seek)
write(3, "strace: exec: No such file or di"..., 40strace: exec: No such file or directory
) = 40
close(3) = 0
munmap(0x7fa8c9eee000, 4096) = 0
exit_group(1) = ?
Here's the output of readelf -a ./gzip:
ELF Header:
Magic: 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00
Class: ELF32
Data: 2's complement, little endian
Version: 1 (current)
OS/ABI: UNIX - System V
ABI Version: 0
Type: EXEC (Executable file)
Machine: Intel 80386
Version: 0x1
Entry point address: 0x8048d20
Start of program headers: 52 (bytes into file)
Start of section headers: 46852 (bytes into file)
Flags: 0x0
Size of this header: 52 (bytes)
Size of program headers: 32 (bytes)
Number of program headers: 6
Size of section headers: 40 (bytes)
Number of section headers: 26
Section header string table index: 25
Section Headers:
[Nr] Name Type Addr Off Size ES Flg Lk Inf Al
[ 0] NULL 00000000 000000 000000 00 0 0 0
[ 1] .interp PROGBITS 080480f4 0000f4 000013 00 A 0 0 1
[ 2] .note.ABI-tag NOTE 08048108 000108 000020 00 A 0 0 4
[ 3] .hash HASH 08048128 000128 000178 04 A 4 0 4
[ 4] .dynsym DYNSYM 080482a0 0002a0 000370 10 A 5 1 4
[ 5] .dynstr STRTAB 08048610 000610 0001ee 00 A 0 0 1
[ 6] .gnu.version VERSYM 080487fe 0007fe 00006e 02 A 4 0 2
[ 7] .gnu.version_r VERNEED 0804886c 00086c 000030 00 A 5 1 4
[ 8] .rel.got REL 0804889c 00089c 000008 08 A 4 20 4
[ 9] .rel.bss REL 080488a4 0008a4 000030 08 A 4 22 4
[10] .rel.plt REL 080488d4 0008d4 000158 08 A 4 12 4
[11] .init PROGBITS 08048a2c 000a2c 00002f 00 AX 0 0 4
[12] .plt PROGBITS 08048a5c 000a5c 0002c0 04 AX 0 0 4
[13] .text PROGBITS 08048d20 000d20 007f4c 00 AX 0 0 16
[14] .fini PROGBITS 08050c6c 008c6c 00001a 00 AX 0 0 4
[15] .rodata PROGBITS 08050ca0 008ca0 001751 00 A 0 0 32
[16] .data PROGBITS 08053400 00a400 000ab4 00 WA 0 0 32
[17] .eh_frame PROGBITS 08053eb4 00aeb4 000004 00 WA 0 0 4
[18] .ctors PROGBITS 08053eb8 00aeb8 000008 00 WA 0 0 4
[19] .dtors PROGBITS 08053ec0 00aec0 000008 00 WA 0 0 4
[20] .got PROGBITS 08053ec8 00aec8 0000bc 04 WA 0 0 4
[21] .dynamic DYNAMIC 08053f84 00af84 0000a0 08 WA 5 0 4
[22] .bss NOBITS 08054040 00b040 050630 00 WA 0 0 32
[23] .comment PROGBITS 00000000 00b040 000487 00 0 0 1
[24] .note NOTE 00000487 00b4c7 00017c 00 0 0 1
[25] .shstrtab STRTAB 00000000 00b643 0000be 00 0 0 1
Key to Flags:
W (write), A (alloc), X (execute), M (merge), S (strings)
I (info), L (link order), G (group), x (unknown)
O (extra OS processing required) o (OS specific), p (processor specific)
There are no section groups in this file.
Program Headers:
Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
PHDR 0x000034 0x08048034 0x08048034 0x000c0 0x000c0 R E 0x4
INTERP 0x0000f4 0x080480f4 0x080480f4 0x00013 0x00013 R 0x1
[Requesting program interpreter: /lib/ld-linux.so.2]
LOAD 0x000000 0x08048000 0x08048000 0x0a3f1 0x0a3f1 R E 0x1000
LOAD 0x00a400 0x08053400 0x08053400 0x00c24 0x51270 RW 0x1000
DYNAMIC 0x00af84 0x08053f84 0x08053f84 0x000a0 0x000a0 RW 0x4
NOTE 0x000108 0x08048108 0x08048108 0x00020 0x00020 R 0x4
Section to Segment mapping:
Segment Sections...
00
01 .interp
02 .interp .note.ABI-tag .hash .dynsym .dynstr .gnu.version .gnu.version_r .rel.got .rel.bss .rel.plt .init .plt .text .fini .rodata
03 .data .eh_frame .ctors .dtors .got .dynamic .bss
04 .dynamic
05 .note.ABI-tag
Dynamic section at offset 0xaf84 contains 20 entries:
Tag Type Name/Value
0x00000001 (NEEDED) Shared library: [libc.so.6]
0x0000000c (INIT) 0x8048a2c
0x0000000d (FINI) 0x8050c6c
0x00000004 (HASH) 0x8048128
0x00000005 (STRTAB) 0x8048610
0x00000006 (SYMTAB) 0x80482a0
0x0000000a (STRSZ) 474 (bytes)
0x0000000b (SYMENT) 16 (bytes)
0x00000015 (DEBUG) 0x0
0x00000003 (PLTGOT) 0x8053ec8
0x00000002 (PLTRELSZ) 344 (bytes)
0x00000014 (PLTREL) REL
0x00000017 (JMPREL) 0x80488d4
0x00000011 (REL) 0x804889c
0x00000012 (RELSZ) 56 (bytes)
0x00000013 (RELENT) 8 (bytes)
0x6ffffffe (VERNEED) 0x804886c
0x6fffffff (VERNEEDNUM) 1
0x6ffffff0 (VERSYM) 0x80487fe
0x00000000 (NULL) 0x0
Relocation section '.rel.got' at offset 0x89c contains 1 entries:
Offset Info Type Sym.Value Sym. Name
08053f80 00000106 R_386_GLOB_DAT 00000000 __gmon_start__
Relocation section '.rel.bss' at offset 0x8a4 contains 6 entries:
Offset Info Type Sym.Value Sym. Name
08054040 00000505 R_386_COPY 08054040 stdout
08054044 00002705 R_386_COPY 08054044 stderr
08054048 00000805 R_386_COPY 08054048 __ctype_b
0805404c 00001f05 R_386_COPY 0805404c stdin
08054050 00001005 R_386_COPY 08054050 optarg
08054054 00001e05 R_386_COPY 08054054 optind
Relocation section '.rel.plt' at offset 0x8d4 contains 43 entries:
Offset Info Type Sym.Value Sym. Name
08053ed4 00000307 R_386_JUMP_SLOT 08048a6c chown
08053ed8 00003407 R_386_JUMP_SLOT 08048a7c __register_frame_info
08053edc 00001907 R_386_JUMP_SLOT 08048a8c write
08053ee0 00002e07 R_386_JUMP_SLOT 08048a9c fileno
08053ee4 00002607 R_386_JUMP_SLOT 08048aac strcmp
08053ee8 00003507 R_386_JUMP_SLOT 08048abc close
08053eec 00000d07 R_386_JUMP_SLOT 08048acc perror
08053ef0 00001a07 R_386_JUMP_SLOT 08048adc fprintf
08053ef4 00000907 R_386_JUMP_SLOT 08048aec getenv
08053ef8 00002007 R_386_JUMP_SLOT 08048afc signal
08053efc 00001207 R_386_JUMP_SLOT 08048b0c fflush
08053f00 00002407 R_386_JUMP_SLOT 08048b1c unlink
08053f04 00002a07 R_386_JUMP_SLOT 08048b2c __errno_location
08053f08 00001407 R_386_JUMP_SLOT 08048b3c chmod
08053f0c 00000e07 R_386_JUMP_SLOT 08048b4c malloc
08053f10 00001d07 R_386_JUMP_SLOT 08048b5c __deregister_frame_inf
08053f14 00002907 R_386_JUMP_SLOT 08048b6c __xstat
08053f18 00000b07 R_386_JUMP_SLOT 08048b7c fgets
08053f1c 00002c07 R_386_JUMP_SLOT 08048b8c __fxstat
08053f20 00001507 R_386_JUMP_SLOT 08048b9c __lxstat
08053f24 00000a07 R_386_JUMP_SLOT 08048bac __strtol_internal
08053f28 00002207 R_386_JUMP_SLOT 08048bbc strncmp
08053f2c 00003007 R_386_JUMP_SLOT 08048bcc __libc_start_main
08053f30 00001c07 R_386_JUMP_SLOT 08048bdc strcat
08053f34 00000407 R_386_JUMP_SLOT 08048bec printf
08053f38 00001307 R_386_JUMP_SLOT 08048bfc lseek
08053f3c 00000c07 R_386_JUMP_SLOT 08048c0c memcpy
08053f40 00001607 R_386_JUMP_SLOT 08048c1c strrchr
08053f44 00001b07 R_386_JUMP_SLOT 08048c2c ctime
08053f48 00000707 R_386_JUMP_SLOT 08048c3c getopt_long
08053f4c 00003207 R_386_JUMP_SLOT 08048c4c closedir
08053f50 00002507 R_386_JUMP_SLOT 08048c5c opendir
08053f54 00003107 R_386_JUMP_SLOT 08048c6c open
08053f58 00002b07 R_386_JUMP_SLOT 08048c7c exit
08053f5c 00001807 R_386_JUMP_SLOT 08048c8c calloc
08053f60 00002d07 R_386_JUMP_SLOT 08048c9c _IO_putc
08053f64 00003607 R_386_JUMP_SLOT 08048cac free
08053f68 00000607 R_386_JUMP_SLOT 08048cbc utime
08053f6c 00000f07 R_386_JUMP_SLOT 08048ccc isatty
08053f70 00002307 R_386_JUMP_SLOT 08048cdc strncpy
08053f74 00001107 R_386_JUMP_SLOT 08048cec readdir
08053f78 00002107 R_386_JUMP_SLOT 08048cfc read
08053f7c 00000207 R_386_JUMP_SLOT 08048d0c strcpy
There are no unwind sections in this file.
Symbol table '.dynsym' contains 55 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 00000000 0 NOTYPE LOCAL DEFAULT UND
1: 00000000 0 NOTYPE WEAK DEFAULT UND __gmon_start__
2: 08048d0c 34 FUNC GLOBAL DEFAULT UND strcpy#GLIBC_2.0 (3)
3: 08048a6c 136 FUNC GLOBAL DEFAULT UND chown#GLIBC_2.1 (2)
4: 08048bec 41 FUNC GLOBAL DEFAULT UND printf#GLIBC_2.0 (3)
5: 08054040 4 OBJECT GLOBAL DEFAULT 22 stdout#GLIBC_2.0 (3)
6: 08048cbc 59 FUNC GLOBAL DEFAULT UND utime#GLIBC_2.0 (3)
7: 08048c3c 43 FUNC GLOBAL DEFAULT UND getopt_long#GLIBC_2.0 (3)
8: 08054048 4 OBJECT GLOBAL DEFAULT 22 __ctype_b#GLIBC_2.0 (3)
9: 08048aec 224 FUNC GLOBAL DEFAULT UND getenv#GLIBC_2.0 (3)
10: 08048bac 1106 FUNC GLOBAL DEFAULT UND __strtol_internal#GLIBC_2.0 (3)
11: 08048b7c 202 FUNC WEAK DEFAULT UND fgets#GLIBC_2.0 (3)
12: 08048c0c 62 FUNC GLOBAL DEFAULT UND memcpy#GLIBC_2.0 (3)
13: 08048acc 111 FUNC GLOBAL DEFAULT UND perror#GLIBC_2.0 (3)
14: 08048b4c 338 FUNC WEAK DEFAULT UND malloc#GLIBC_2.0 (3)
15: 08048ccc 46 FUNC WEAK DEFAULT UND isatty#GLIBC_2.0 (3)
16: 08054050 4 OBJECT GLOBAL DEFAULT 22 optarg#GLIBC_2.0 (3)
17: 08048cec 142 FUNC WEAK DEFAULT UND readdir#GLIBC_2.0 (3)
18: 08048b0c 152 FUNC WEAK DEFAULT UND fflush#GLIBC_2.0 (3)
19: 08048bfc 61 FUNC WEAK DEFAULT UND lseek#GLIBC_2.0 (3)
20: 08048b3c 59 FUNC WEAK DEFAULT UND chmod#GLIBC_2.0 (3)
21: 08048b9c 314 FUNC GLOBAL DEFAULT UND __lxstat#GLIBC_2.0 (3)
22: 08048c1c 441 FUNC GLOBAL DEFAULT UND strrchr#GLIBC_2.0 (3)
23: 0804f608 29 FUNC GLOBAL DEFAULT 13 basename
24: 08048c8c 563 FUNC WEAK DEFAULT UND calloc#GLIBC_2.0 (3)
25: 08048a8c 61 FUNC WEAK DEFAULT UND write#GLIBC_2.0 (3)
26: 08048adc 36 FUNC GLOBAL DEFAULT UND fprintf#GLIBC_2.0 (3)
27: 08048c2c 35 FUNC GLOBAL DEFAULT UND ctime#GLIBC_2.0 (3)
28: 08048bdc 49 FUNC GLOBAL DEFAULT UND strcat#GLIBC_2.0 (3)
29: 08048b5c 162 FUNC WEAK DEFAULT UND __deregister_frame_info#GLIBC_2.0 (3)
30: 08054054 4 OBJECT GLOBAL DEFAULT 22 optind#GLIBC_2.0 (3)
31: 0805404c 4 OBJECT GLOBAL DEFAULT 22 stdin#GLIBC_2.0 (3)
32: 08048afc 181 FUNC WEAK DEFAULT UND signal#GLIBC_2.0 (3)
33: 08048cfc 61 FUNC WEAK DEFAULT UND read#GLIBC_2.0 (3)
34: 08048bbc 148 FUNC GLOBAL DEFAULT UND strncmp#GLIBC_2.0 (3)
35: 08048cdc 147 FUNC GLOBAL DEFAULT UND strncpy#GLIBC_2.0 (3)
36: 08048b1c 55 FUNC WEAK DEFAULT UND unlink#GLIBC_2.0 (3)
37: 08048c5c 412 FUNC WEAK DEFAULT UND opendir#GLIBC_2.0 (3)
38: 08048aac 58 FUNC GLOBAL DEFAULT UND strcmp#GLIBC_2.0 (3)
39: 08054044 4 OBJECT GLOBAL DEFAULT 22 stderr#GLIBC_2.0 (3)
40: 0804f7fc 40 FUNC GLOBAL DEFAULT 13 error
41: 08048b6c 314 FUNC GLOBAL DEFAULT UND __xstat#GLIBC_2.0 (3)
42: 08048b2c 27 FUNC WEAK DEFAULT UND __errno_location#GLIBC_2.0 (3)
43: 08048c7c 200 FUNC GLOBAL DEFAULT UND exit#GLIBC_2.0 (3)
44: 08048b8c 314 FUNC GLOBAL DEFAULT UND __fxstat#GLIBC_2.0 (3)
45: 08048c9c 150 FUNC GLOBAL DEFAULT UND _IO_putc#GLIBC_2.0 (3)
46: 08048a9c 53 FUNC GLOBAL DEFAULT UND fileno#GLIBC_2.0 (3)
47: 08050ca4 4 OBJECT GLOBAL DEFAULT 15 _IO_stdin_used
48: 08048bcc 261 FUNC GLOBAL DEFAULT UND __libc_start_main#GLIBC_2.0 (3)
49: 08048c6c 61 FUNC WEAK DEFAULT UND open#GLIBC_2.0 (3)
50: 08048c4c 112 FUNC WEAK DEFAULT UND closedir#GLIBC_2.0 (3)
51: 0804f824 66 FUNC GLOBAL DEFAULT 13 warn
52: 08048a7c 116 FUNC WEAK DEFAULT UND __register_frame_info#GLIBC_2.0 (3)
53: 08048abc 55 FUNC WEAK DEFAULT UND close#GLIBC_2.0 (3)
54: 08048cac 202 FUNC WEAK DEFAULT UND free#GLIBC_2.0 (3)
Histogram for bucket list length (total of 37 buckets):
Length Number % of total Coverage
0 10 ( 27.0%)
1 14 ( 37.8%) 25.9%
2 4 ( 10.8%) 40.7%
3 4 ( 10.8%) 63.0%
4 5 ( 13.5%) 100.0%
Version symbols section '.gnu.version' contains 55 entries:
Addr: 00000000080487fe Offset: 0x0007fe Link: 4 (.dynsym)
000: 0 (*local*) 0 (*local*) 3 (GLIBC_2.0) 2 (GLIBC_2.1)
004: 3 (GLIBC_2.0) 3 (GLIBC_2.0) 3 (GLIBC_2.0) 3 (GLIBC_2.0)
008: 3 (GLIBC_2.0) 3 (GLIBC_2.0) 3 (GLIBC_2.0) 3 (GLIBC_2.0)
00c: 3 (GLIBC_2.0) 3 (GLIBC_2.0) 3 (GLIBC_2.0) 3 (GLIBC_2.0)
010: 3 (GLIBC_2.0) 3 (GLIBC_2.0) 3 (GLIBC_2.0) 3 (GLIBC_2.0)
014: 3 (GLIBC_2.0) 3 (GLIBC_2.0) 3 (GLIBC_2.0) 1 (*global*)
018: 3 (GLIBC_2.0) 3 (GLIBC_2.0) 3 (GLIBC_2.0) 3 (GLIBC_2.0)
01c: 3 (GLIBC_2.0) 3 (GLIBC_2.0) 3 (GLIBC_2.0) 3 (GLIBC_2.0)
020: 3 (GLIBC_2.0) 3 (GLIBC_2.0) 3 (GLIBC_2.0) 3 (GLIBC_2.0)
024: 3 (GLIBC_2.0) 3 (GLIBC_2.0) 3 (GLIBC_2.0) 3 (GLIBC_2.0)
028: 1 (*global*) 3 (GLIBC_2.0) 3 (GLIBC_2.0) 3 (GLIBC_2.0)
02c: 3 (GLIBC_2.0) 3 (GLIBC_2.0) 3 (GLIBC_2.0) 1 (*global*)
030: 3 (GLIBC_2.0) 3 (GLIBC_2.0) 3 (GLIBC_2.0) 1 (*global*)
034: 3 (GLIBC_2.0) 3 (GLIBC_2.0) 3 (GLIBC_2.0)
Version needs section '.gnu.version_r' contains 1 entries:
Addr: 0x000000000804886c Offset: 0x00086c Link: 5 (.dynstr)
000000: Version: 1 File: libc.so.6 Cnt: 2
0x0010: Name: GLIBC_2.0 Flags: none Version: 3
0x0020: Name: GLIBC_2.1 Flags: none Version: 2
Notes at offset 0x00000108 with length 0x00000020:
Owner Data size Description
GNU 0x00000010 NT_GNU_ABI_TAG (ABI version tag)
Notes at offset 0x0000b4c7 with length 0x0000017c:
Owner Data size Description
01.01 0x00000000 NT_VERSION (version)
01.01 0x00000000 NT_VERSION (version)
01.01 0x00000000 NT_VERSION (version)
01.01 0x00000000 NT_VERSION (version)
01.01 0x00000000 NT_VERSION (version)
01.01 0x00000000 NT_VERSION (version)
01.01 0x00000000 NT_VERSION (version)
01.01 0x00000000 NT_VERSION (version)
01.01 0x00000000 NT_VERSION (version)
01.01 0x00000000 NT_VERSION (version)
01.01 0x00000000 NT_VERSION (version)
01.01 0x00000000 NT_VERSION (version)
01.01 0x00000000 NT_VERSION (version)
01.01 0x00000000 NT_VERSION (version)
01.01 0x00000000 NT_VERSION (version)
01.01 0x00000000 NT_VERSION (version)
01.01 0x00000000 NT_VERSION (version)
01.01 0x00000000 NT_VERSION (version)
01.01 0x00000000 NT_VERSION (version)
The answer is in this line of the output of readelf -a in the original question
[Requesting program interpreter: /lib/ld-linux.so.2]
I was missing the /lib/ld-linux.so.2 file, which is needed to run 32-bit apps. The Ubuntu package that has this file is libc6-i386.
Old question, but hopefully this'll help someone else.
In my case I was using a toolchain on Ubuntu 12.04 that was built on Ubuntu 10.04 (requires GCC 4.1 to build). As most of the libraries have moved to multiarch dirs, it couldn't find ld.so. So, make a symlink for it.
Check required path:
$ readelf -a arm-linux-gnueabi-gcc | grep interpreter:
[Requesting program interpreter: /lib/ld-linux-x86-64.so.2]
Create symlink:
$ sudo ln -s /lib/x86_64-linux-gnu/ld-linux-x86-64.so.2 /lib/ld-linux-x86-64.so.2
If you're on 32bit, it'll be i386-linux-gnu and not x86_64-linux-gnu.
You get this error when you try to run a 32-bit build on your 64-bit Linux.
Also contrast what file had to say on the binary you tried (ie: 32-bit) with what you get for your /bin/gzip:
$ file /bin/gzip
/bin/gzip: ELF 64-bit LSB executable, x64-64, version 1 (SYSV), \
dynamically linked (uses shared libs), for GNU/Linux 2.6.15, stripped
which is what I get on Ubuntu 9.10 for amd64 aka x86_64.
Edit: Your expanded post shows that as the readelf output also reflects a 32-bit build.
I think you're x86-64 install does not have the i386 runtime linker. The ENOENT is probably due to the OS looking for something like /lib/ld.so.1 or similar. This is typically part of the 32-bit glibc runtime, and while I'm not directly familiar with Ubuntu, I would assume they have some sort of 32-bit compatibility package to install. Fortunately gzip only depends on the C library, so that's probably all you'll need to install.
readelf -a xxx
INTERP
0x0000000000000238 0x0000000000400238 0x0000000000400238
0x000000000000001c 0x000000000000001c R 1
[Requesting program interpreter: /lib64/ld-linux-x86-64.so.2]
I also had problems because my program interpreter was /lib/ld-linux.so.2 however it was on an embedded device, so I solved the problem by asking gcc to use ls-uClibc instead as follows:
-Wl,--dynamic-linker=/lib/ld-uClibc.so.0
It is possible that the executable is statically linked and that is why ldd gzip does not see any links - because it isn't. I don't know much about things that far back so I don't know if there would be incompatibilities if libraries are linked in statically. I might expect there to be.
I know it's the most obvious thing going and I'm sure you've done it, but chmod +x ./gzip, yes? No such file or directory is a classic symptom of that not being done, that's why I mention it.
Well another possible cause of this can be simple line break at end of each line and shebang line
If you have been coding in windows IDE its possible that windows has added its own line break at the end of each line and when you try to run it on linux the line break cause problems
You can see execve return ENOENT . Then search ENOENT in execve man.
The file pathname or a script or ELF interpreter does not exist.
The gzip file exist, and is a ELF file. So check whether ELF interpreter exist or not. According the man again:
If the executable is a dynamically linked ELF executable, the
interpreter named in the PT_INTERP segment is used to load the needed
shared objects. This interpreter is typically /lib/ld-linux.so.2 for
binaries linked with glibc .
We can find the ELF interpreter path with readelf as #Lorin Hochstein said:
$ readelf -l <filename> |grep -i interp
...
[Requesting program interpreter: /lib/ld-linux.so.2]
The ELF interpreter should not exist here.