If in ARM32 branch have these opcode: EAFF FFFE, then what would this opcode be in ARM64?
Example:
ARM32:
0000: b $+0
ARM64:
0000: b $+0
The solution from DEFCON: 0x00000014
Related
Currently I'm in a directory which has a file libshared-object.so (name changed for generality).
When I run
$ objdump -p libshared-object.so
I receive the following output:
libshared-object.so: file format elf64-x86-64
Program Header:
LOAD off 0x0000000000000000 vaddr 0x0000000000000000 paddr 0x0000000000000000 align 2**21
filesz 0x00000000000828ee memsz 0x00000000000828ee flags r-x
LOAD off 0x0000000000083768 vaddr 0x0000000000283768 paddr 0x0000000000283768 align 2**21
filesz 0x00000000000048e0 memsz 0x0000000000004af0 flags rw-
DYNAMIC off 0x0000000000084af0 vaddr 0x0000000000284af0 paddr 0x0000000000284af0 align 2**3
filesz 0x00000000000002a0 memsz 0x00000000000002a0 flags rw-
NOTE off 0x00000000000001c8 vaddr 0x00000000000001c8 paddr 0x00000000000001c8 align 2**2
filesz 0x0000000000000024 memsz 0x0000000000000024 flags r--
EH_FRAME off 0x0000000000072c6c vaddr 0x0000000000072c6c paddr 0x0000000000072c6c align 2**2
filesz 0x0000000000002ed4 memsz 0x0000000000002ed4 flags r--
STACK off 0x0000000000000000 vaddr 0x0000000000000000 paddr 0x0000000000000000 align 2**4
filesz 0x0000000000000000 memsz 0x0000000000000000 flags rw-
RELRO off 0x0000000000083768 vaddr 0x0000000000283768 paddr 0x0000000000283768 align 2**0
filesz 0x0000000000001898 memsz 0x0000000000001898 flags r--
Dynamic Section:
NEEDED libQt5Widgets.so.5
NEEDED libQt5Compositor.so.5
NEEDED libQt5Quick.so.5
NEEDED libQt5Qml.so.5
NEEDED libQt5Network.so.5
NEEDED libQt5Gui.so.5
NEEDED libQt5Core.so.5
NEEDED libGL.so.1
NEEDED libpthread.so.0
NEEDED libstdc++.so.6
NEEDED libm.so.6
NEEDED libgcc_s.so.1
NEEDED libc.so.6
SONAME libshared-object.so.1
RPATH /opt/qt5/lib
INIT 0x000000000003fc68
FINI 0x000000000006c234
INIT_ARRAY 0x0000000000283768
INIT_ARRAYSZ 0x00000000000000e8
FINI_ARRAY 0x0000000000283850
FINI_ARRAYSZ 0x0000000000000008
GNU_HASH 0x00000000000001f0
STRTAB 0x00000000000101e8
SYMTAB 0x00000000000036d8
STRSZ 0x0000000000022072
SYMENT 0x0000000000000018
PLTGOT 0x0000000000285000
PLTRELSZ 0x0000000000008df0
PLTREL 0x0000000000000007
JMPREL 0x0000000000036e78
RELA 0x0000000000033458
RELASZ 0x0000000000003a20
RELAENT 0x0000000000000018
VERNEED 0x0000000000033348
VERNEEDNUM 0x0000000000000006
VERSYM 0x000000000003225a
RELACOUNT 0x0000000000000052
Version References:
required from libm.so.6:
0x09691a75 0x00 09 GLIBC_2.2.5
required from libgcc_s.so.1:
0x0b792650 0x00 08 GCC_3.0
required from libc.so.6:
0x06969194 0x00 10 GLIBC_2.14
0x09691a75 0x00 07 GLIBC_2.2.5
required from libQt5Core.so.5:
0x00058a25 0x00 06 Qt_5
required from libQt5Gui.so.5:
0x0dcbd2c9 0x00 12 Qt_5_PRIVATE_API
0x00058a25 0x00 03 Qt_5
required from libstdc++.so.6:
0x0bafd178 0x00 11 CXXABI_1.3.8
0x056bafd3 0x00 05 CXXABI_1.3
0x0297f871 0x00 04 GLIBCXX_3.4.21
0x08922974 0x00 02 GLIBCXX_3.4
Of particular interest is the very last of this information, the Version References:
Version References:
required from libm.so.6:
0x09691a75 0x00 09 GLIBC_2.2.5
required from libgcc_s.so.1:
0x0b792650 0x00 08 GCC_3.0
required from libc.so.6:
0x06969194 0x00 10 GLIBC_2.14
0x09691a75 0x00 07 GLIBC_2.2.5
required from libQt5Core.so.5:
0x00058a25 0x00 06 Qt_5
required from libQt5Gui.so.5:
0x0dcbd2c9 0x00 12 Qt_5_PRIVATE_API
0x00058a25 0x00 03 Qt_5
required from libstdc++.so.6:
0x0bafd178 0x00 11 CXXABI_1.3.8
0x056bafd3 0x00 05 CXXABI_1.3
0x0297f871 0x00 04 GLIBCXX_3.4.21
0x08922974 0x00 02 GLIBCXX_3.4
Question: Where do these version references come from? Take, for example, the line required from libQt5Gui.so.5: .. Qt_5 and Qt_5_PRIVATE_API.
Are references to version Qt_5 and Qt_5_PRIVATE_API coming from the C code that generated libQt5Gui.so.5? Or from some linker option passed to to gcc or ld? Or from something else?
Or from something else?
From something else.
When you build a shared library (say libfoo.so), you can (though don't have to) supply a linker version script giving certain symbols a version tag.
When you later link an executable or a shared library (say libbar.so) against libfoo.so, iff you use a versioned symbol, the version tag of that symbol is recorded in libbar.so (that is what you observed in your question).
This setup allows libfoo.so to change its symbols in ABI-incompatible way, and still support old client programs that were linked against the old symbols.
For example, libc.so.6 on x86_64 has the following versions of memcpy:
0000000000091620 g iD .text 000000000000003d GLIBC_2.14 memcpy
000000000008c420 g iD .text 0000000000000047 (GLIBC_2.2.5) memcpy
Programs that were linked against glibc-2.13 or older will use the GLIBC_2.2.5 version, programs that were linked against glibc-2.14 or newer will use the GLIBC_2.14 version.
If you try to run a program linked against glibc-2.14 on a system with glibc-2.13, you will get an error (missing symbol version), similar to this.
Before the introduction of symbol versioning, changing the ABI of an existing symbol required that you ship an entirely separate library. This is called external library versioning. You can read more about it here.
Compiling a simple HelloWorld.c using Clang/LLVM (arm-none-eabi target) produces a relocation section '.rel.ARM.exidx' but using arm-gcc does not. These LLVM produced unwind table entries are correctly tagged as canunwind. But why are they even produced at all as they are not needed and just cause bloat as you get an entry for every C function in your AXF?
readelf edxidx from HelloWorld.o
Relocation section '.rel.ARM.exidx' at offset 0x580 contains 2 entries:
Offset Info Type Sym.Value Sym. Name
00000000 00000b2a R_ARM_PREL31 00000000 .text
00000008 00000b2a R_ARM_PREL31 00000000 .text
Unwind table index '.ARM.exidx' at offset 0xcc contains 2 entries:
0x0 <print_uart0>: 0x1 [cantunwind]
0x54 <c_entry>: 0x1 [cantunwind]
In testing Clang defaults: If I pass "-funwind-tables" to Clang to force unwinding for even C functions, I get what I would expect had I been writing .cpp functions and "-fno-unwind-tables" results in the same as above.
Relocation section '.rel.ARM.exidx' at offset 0x5a4 contains 4 entries:
Offset Info Type Sym.Value Sym. Name
00000000 00000b2a R_ARM_PREL31 00000000 .text
00000000 00001600 R_ARM_NONE 00000000 __aeabi_unwind_cpp_pr0
00000008 00000b2a R_ARM_PREL31 00000000 .text
00000008 00001600 R_ARM_NONE 00000000 __aeabi_unwind_cpp_pr0
Unwind table index '.ARM.exidx' at offset 0xcc contains 2 entries:
0x0 <print_uart0>: 0x8001b0b0
Compact model index: 0
0x01 vsp = vsp + 8
0xb0 finish
0xb0 finish
0x54 <c_entry>: 0x809b8480
Compact model index: 0
0x9b vsp = r11
0x84 0x80 pop {r11, r14}
1) Is there anyway to turn off the .ARM.exidx section when only using C functions as they will always be flagged as "cantunwind".
2) Anyway to strip this section during linking? (gc-section will not workof course since these table entries reference in-use functions)
3) Why does arm-gcc not create this section (well, it does if you are using new lib, nano, etc... but I use and link no std libs)
I'll answer (2), since that's what I did. Add to your linker script:
/DISCARD/ :
{
*(.ARM.exidx)
}
Background
Found a strange kernel Oops, Googled a lot, found nothing.
Background:
The kernel version is 3.0.8
There are two process let's say p1, p2
p2 have lots of threads(about 30)
p1 continuously calls system(pidof("name of p1"))
The kernel may Oops after running for a few days. the primary reason I found is that unwind_frame got a strange frame->fp(0xFFFFFFFF) from get_wchan
When executing this line
frame->fp = *(unsigned long *)(fp - 12);
The CPU will try to access 0xFFFFFFF3, and cause a paging error.
My question is:
How on earth the fp register saved before context switch becomes 0xFFFFFFFF ?
here is the CPU infomation
# cat /proc/cpuinfo
Processor : ARMv7 Processor rev 0 (v7l)
processor : 0
BogoMIPS : 1849.75
processor : 1
BogoMIPS : 1856.30
Features : swp half thumb fastmult vfp edsp vfpv3 vfpv3d16
CPU implementer : 0x41
CPU architecture: 7
CPU variant : 0x3
CPU part : 0xc09
CPU revision : 0
Here is the Oops and pt registers:
[734212.113136] Unable to handle kernel paging request at virtual address fffffff3
[734212.113154] pgd = 826f0000
[734212.113175] [fffffff3] *pgd=8cdfe821, *pte=00000000, *ppte=00000000
[734212.113199] Internal error: Oops: 17 [#1] SMP
--------------cut--------------
[734212.113464] CPU: 1 Tainted: P (3.0.8 #2)
[734212.113523] PC is at unwind_frame+0x48/0x68
[734212.113538] LR is at get_wchan+0x8c/0x298
[734212.113557] pc : [<8003d120>] lr : [<8003a660>] psr: a0000013
[734212.113561] sp : 845d1cc8 ip : 00000003 fp : 845d1cd4
[734212.113583] r10: 00000001 r9 : 00000000 r8 : 80493c34
[734212.113597] r7 : 00000000 r6 : 00000000 r5 : 83354960 r4 : 845d1cd8
[734212.113613] r3 : 845d1cd8 r2 : ffffffff r1 : 80490000 r0 : 8049003f
[734212.113632] Flags: NzCv IRQs on FIQs on Mode SVC_32 ISA ARM Segment user
[734212.113651] Control: 10c53c7d Table: 826f004a DAC: 00000015
Here is the callstack:
[734212.117027] Backtrace:
[734212.117052] [<8003d0d8>] (unwind_frame+0x0/0x68) from [<8003a660>] (get_wchan+0x8c/0x298)
[734212.117079] [<8003a5d4>] (get_wchan+0x0/0x298) from [<8011f700>] (do_task_stat+0x548/0x5ec)
[734212.117099] r4:00000000
[734212.117118] [<8011f1b8>] (do_task_stat+0x0/0x5ec) from [<8011f7c0>] (proc_tgid_stat+0x1c/0x24)
[734212.117158] [<8011f7a4>] (proc_tgid_stat+0x0/0x24) from [<8011b7f0>] (proc_single_show+0x54/0x98)
[734212.117196] [<8011b79c>] (proc_single_show+0x0/0x98) from [<800e9024>] (seq_read+0x1b4/0x4e4)
[734212.117215] r8:845d1f08 r7:845d1f70 r6:00000001 r5:8ca89d20 r4:866ea540
[734212.117237] r3:00000000
[734212.117264] [<800e8e70>] (seq_read+0x0/0x4e4) from [<800c8c54>] (vfs_read+0xb4/0x19c)
[734212.117289] [<800c8ba0>] (vfs_read+0x0/0x19c) from [<800c8e18>] (sys_read+0x44/0x74)
[734212.117307] r8:00000000 r7:00000003 r6:000003ff r5:7ea00818 r4:8ca89d20
[734212.117340] [<800c8dd4>] (sys_read+0x0/0x74) from [<800393c0>] (ret_fast_syscall+0x0/0x30)
[734212.117358] r9:845d0000 r8:80039568 r6:7ea00c90 r5:0000000e r4:7ea00818
[734212.117388] Code: e3c10d7f e3c0103f e151000c 9afffff6 (e512100c)
[734212.113136] Unable to handle kernel paging request at virtual address fffffff3
[734212.113154] pgd = 826f0000
[734212.113175] [fffffff3] *pgd=8cdfe821, *pte=00000000, *ppte=00000000
[734212.113199] Internal error: Oops: 17 [#1] SMP
This bug was fixed by Konstantin Khlebnikov, details can be found in git commit log.
I have a tool emitting an ELF, which as far as I can tell is compliant to the spec. Readelf output looks fine, but objdump refuses to disassemble anything.
I have simplified the input to a single global var, and "int main(void) { return 0;}" to aid debugging - the tiny section sizes are correct.
In particular, objdump seems unable to find the sections table:
$ arm-none-linux-gnueabi-readelf -S davidm.elf
There are 4 section headers, starting at offset 0x74:
Section Headers:
[Nr] Name Type Addr Off Size ES Flg Lk Inf Al
[ 0] NULL 00000000 000000 000000 00 0 0 0
[ 1] .text NULL ff000000 000034 00001c 00 AX 0 0 4
[ 2] .data NULL ff00001c 000050 000004 00 WA 0 0 4
[ 3] .shstrtab NULL 00000000 000114 000017 00 0 0 0
$ arm-none-linux-gnueabi-objdump -h davidm.elf
davidm.elf: file format elf32-littlearm
Sections:
Idx Name Size VMA LMA File off Algn
I also have another ELF, built from the exact same objects, only produced with regular toolchain use:
$ objdump -h kernel.elf
kernel.elf: file format elf32-littlearm
Sections:
Idx Name Size VMA LMA File off Algn
0 .text 0000001c ff000000 ff000000 00008000 2**2
CONTENTS, ALLOC, LOAD, READONLY, CODE
1 .data 00000004 ff00001c ff00001c 0000801c 2**2
CONTENTS, ALLOC, LOAD, DATA
Even after I stripped .comment and .ARM.attributes sections (incase objdump requires them) from the 'known good' kernel.elf, it still happily lists the sections there, but not in my tool's davidm.elf.
I have confirmed the contents of the sections are identical between the two with readelf -x.
The only thing I can image is that the ELF file layout is different and breaks some expectations of BFD, which could explain why readelf (and my tool) processes it just fine but objdump has troubles.
Full readelf:
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: ARM
Version: 0x1
Entry point address: 0xff000000
Start of program headers: 84 (bytes into file)
Start of section headers: 116 (bytes into file)
Flags: 0x5000002, has entry point, Version5 EABI
Size of this header: 52 (bytes)
Size of program headers: 32 (bytes)
Number of program headers: 1
Size of section headers: 40 (bytes)
Number of section headers: 4
Section header string table index: 3
Section Headers:
[Nr] Name Type Addr Off Size ES Flg Lk Inf Al
[ 0] NULL 00000000 000000 000000 00 0 0 0
[ 1] .text NULL ff000000 000034 00001c 00 AX 0 0 4
[ 2] .data NULL ff00001c 000050 000004 00 WA 0 0 4
[ 3] .shstrtab NULL 00000000 000114 000017 00 0 0 0
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
LOAD 0x000034 0xff000000 0xff000000 0x00020 0x00020 RWE 0x8000
Section to Segment mapping:
Segment Sections...
00 .text .data
There is no dynamic section in this file.
There are no relocations in this file.
There are no unwind sections in this file.
No version information found in this file.
Could the aggressive packing of the on-disk layout be causing troubles? Am I in violation of some bytestream alignment restrictions BFD expects, documented or otherwise?
Lastly - this file is not intended to be mmap'd into an address space, a loader will memcpy segment data into the desired location, so there is no requirement to play mmap-friendly file-alignment tricks. Keeping the ELF small is more important.
Cheers,
DavidM
EDIT: I was asked to upload the file, and/or provide 'objdump -x'. So I've done both:
davidm.elf
$ objdump -x davidm.elf
davidm.elf: file format elf32-littlearm
davidm.elf
architecture: arm, flags 0x00000002:
EXEC_P
start address 0xff000000
Program Header:
LOAD off 0x00000034 vaddr 0xff000000 paddr 0xff000000 align 2**15
filesz 0x00000020 memsz 0x00000020 flags rwx
private flags = 5000002: [Version5 EABI] [has entry point]
Sections:
Idx Name Size VMA LMA File off Algn
SYMBOL TABLE:
no symbols
OK - finally figured it out.
After building and annotating/debugging libbfd (function elf_object_p()) in the context of a little test app, I found why it was not matching on any of BFD supported targets.
I had bad sh_type flags for the section headers: NULL. Emitting STRTAB or PROGBITS (and eventually NOBITS when I get that far) as appropriate and objdump happily walks my image.
Not really surprising, in retrospect - I'm more annoyed I didn't catch this in comparing readelf outputs than anything else :(
Thanks for the help all :)
This is close to Using GCC to produce readable assembly?, but my context here is avr-gcc (and correspondingly, avr-objdump) for Atmel (though, I guess it would apply across the GCC board).
The thing is, I have a project of multiple .c and .cpp files; which ultimately get compiled into an executable, with the same name as the 'master' .cpp file. In this process, I can obtain assembly listing in two ways:
I can instruct gcc to emit assembly listing source (see Linux Assembly and Disassembly an Introduction) using the -S switch; in this case, I get a file, with contents like:
...
loop:
push r14
push r15
push r16
push r17
push r28
push r29
/* prologue: function /
/ frame size = 0 */
ldi r24,lo8(13)
ldi r22,lo8(1)
call digitalWrite
rjmp .L2
.L3:
ldi r24,lo8(MyObj)
ldi r25,hi8(MyObj)
call _ZN16MYOBJ7connectEv
.L2:
ldi r24,lo8(MyObj)
ldi r25,hi8(MyObj)
call _ZN16MYOBJ11isConnectedEv
...
(Haven't tried it yet; but I guess this code is compilable/buildable....)
I can inspect the final executable with, and instruct, objdump to emit assembly listing source using the -S switch; in this case, I get a file, with contents like:
...
0000066a <init>:
void init()
{
// this needs to be called before setup() or some functions won't
// work there
sei();
66a: 78 94 sei
66c: 83 b7 in r24, 0x33 ; 51
66e: 84 60 ori r24, 0x04 ; 4
670: 83 bf out 0x33, r24 ; 51
...
000006be <loop>:
6be: ef 92 push r14
6c0: ff 92 push r15
6c2: 0f 93 push r16
6c4: 1f 93 push r17
6c6: cf 93 push r28
6c8: df 93 push r29
6ca: 8d e0 ldi r24, 0x0D ; 13
6cc: 61 e0 ldi r22, 0x01 ; 1
6ce: 0e 94 23 02 call 0x446 ; 0x446
6d2: 04 c0 rjmp .+8 ; 0x6dc
6d4: 8d ef ldi r24, 0xFD ; 253
6d6: 94 e0 ldi r25, 0x04 ; 4
6d8: 0e 94 25 06 call 0xc4a ; 0xc4a <_ZN16MYOBJ7connectEv>
6dc: 8d ef ldi r24, 0xFD ; 253
6de: 94 e0 ldi r25, 0x04 ; 4
6e0: 0e 94 21 06 call 0xc42 ; 0xc42 <_ZN16MYOBJ11isConnectedEv>
...
(I did try to build this code, and it did fail - it reads the 'line numbers' as labels)
Obviously, both listings (for the loop function, at least) represent the same assembly code; except:
The gcc one (should) compile -- the objdump one does not
The objdump one contains listings of all referred functions, which could be defined in files other than the 'master' (e.g., digitalWrite) -- the gcc one does not
The objdump one contains original C/C++ source lines 'interspersed' with assembly (but only occasionally, and seemingly only for C files?) -- the gcc one does not
So, is there a way to obtain an assembly listing that would be 'compilable', however with all in-linked functions, and where source C/C++ code is (possibly, where appropriate) interspersed as comments (so they don't interfere with compilation of assembly file)? (short of writing a parser for the output of objdump, that is :))
Add the option -fverbose-asm to your gcc command line up there. (This is in the gcc manual, but it's documented under 'Code Gen Options')
The "dependencies" that you talk about often come from libraries or separate object files, so they don't have a source - they're just linked as binary code into the final executable. Since such code is not passed through the assembler, you will have to extract it using other ways - e.g. using objdump.
Maybe you should tell us what you really want to achieve because I don't see much point in such an exercise by itself.
The best I have been able to get is to use -Wa,-ahl=outfile.s instead of -S. It isn't compilable code though, but a listing file for diagnostic purposes; the compiled object file is emitted as usual.