Dump debug_loc section from executable - linux

How do I dump debug_loc section from an executable on Linux if default options (-g) are provided to GCC while compiling a C file? I use readelf linux utility.
GCC by default produces DWARF info in DWARF4 format, so if I pass -g-dwarf2 I can see .debug_loc section but how do inspect that section if info is generated with default options as I don't see the section in dump?

Do you use a recent version of binutils? On Ubuntu 14.04 I can build executable with "gcc -g test.c -o test".
With "readelf --debug-dump=info test" I can confirm it's using DWARF 4.
After that, you have (at least) two ways to dump the contents of .debug_line section.
readelf --debug-dump=decodedline test
This will dump decoded line number information. You get line==address mappings directly.
There is also:
readelf --debug-dump=rawline test
This gets you raw debug_line contents.

Usually, .debug_loc is generated for optimized code. Try optimizing your code using compiler flags.

Related

Could resolving debug symbols with gdb give different results depending on the OS

I have a stack trace from an application that was built and run on CentOS 5.4. The application was built without debug so there are no symbols or line numbers in the stack trace, but only addresses, like so:
/opt/app/bin/myApp [0x22ec09e]
/opt/app/bin/myApp [0x1fcdf31]
/opt/app/bin/myApp [0x22ebbcb]
...
I also have the same application, but built with debug (-g). So I am able to open this binary with gdb and find out the corresponding source files, function names and line numbers corresponding to these addresses.
My question is, having this binary built with debug on CentOS 5.4, does it matter on which OS I am using gdb to resolve the symbols? If I open it with gdb on CentOS 5.4 and use info line or list, could the result differ from when doing the same on say Fedora 16? I have done a few tests doing this on CentOS 5.4 and Fedora 16 which indicates that there is no difference. However, can I trust that this is always so or could I one day find out that there could be differences under certain circumstances?
Notes: Application was written in C++ and built with g++. Please let me know if any additional information is needed to answer this question.
does it matter on which OS I am using gdb to resolve the symbols?
No: the mapping of addresses to line numbers is fixed at binary link time. Once the binary is linked, you can perform the mapping on any OS you wish.
I also have the same application, but built with debug (-g).
Note that the mapping does change depending on optimization flags you used. This would work:
# original application build
g++ -O2 foo.cc bar.cc -o app
# same with debug symbols:
g++ -O2 -g foo.cc bar.cc -o app_g
This would not work (symbols between app and app_g2 will not match):
g++ -g foo.cc bar.cc -o app_g2

linux application get Killed

I have a "Seagate Central" NAS with an embedded linux on it
$ cat /etc/*release
MontaVista Linux 6, (.dev-snapshot-20130726)
When I try to run my own application on this NAS, it will be "Killed"
without any notifications on dmesg or /var/log/messages
$ cat /proc/cpuinfo
Processor : ARMv6-compatible processor rev 4 (v6l)
BogoMIPS : 279.34
Features : swp half thumb fastmult vfp edsp java
CPU implementer : 0x41
CPU architecture: 7
CPU variant : 0x0
CPU part : 0xb02
CPU revision : 4
Hardware : Cavium Networks CNS3420 Validation Board
Revision : 0000
Serial : 0000000000000000
My toolchain is
Sourcery_CodeBench_Lite_for_ARM_GNU_Linux/arm-none-linux-gnueabi
and my compile switches are
-march=armv6k -mcpu=mpcore -mfloat-abi=softfp -mfpu=vfp
How can I find out which process is killing my application, or what setting I have to change?
PS: I have created a simple HelloWorld application which is also not working !
$ ldd Hello
$ not a dynamic executable
readelf -a Hello
=> http://pastebin.com/kT9FvkjE
readelf -a zip
=> http://pastebin.com/3V6kqA9b
UPDATE 1
I have comiled a new binary with hard float
Readelf output
http://pastebin.com/a87bKksY
But no success ;(
I guess it is really a "lock" topic, which is blocking my application to execute. How can I find out what application kills mine ?
Or how can I disable such kind of function ?
Use these compiler switches:
-march=armv6k -Wl,-z,max-page-size=0x10000,-z,common-page-size=0x10000,-Ttext-segment=0x10000
See also this link regarding the toolchain.
You can run readelf -a against one of the built-in binaries (e.g. /usr/bin/nano) to see the proper text-segment offset in the section headers and page size / alignment in the program headers. The above compiler flags make self-compiled programs match the structure of built in binaries, and have been tested to work. It seems the Seagate Central NAS uses a page size / offset of 0x10000 while the default for ARM gcc is 0x8000.
Edit: I see you ran readelf already. Your pastebin shows
HelloWorld:[ 1] .interp PROGBITS 00008134 000134 000013 00 A 0 0 1
zip:[ 1] .interp PROGBITS 00010134 000134 000013 00 A 0 0 1
The value 10134-134=10000 (hex) yields the correct text-segment linker option. Further down (LOAD...) are the alignment specifiers, which are 0x8000 for your HelloWorld, but 0x10000 for the zip built-in. In my experience, soft-float has not caused problems.
Do you see any output at all?
Is your application dynamically linked?
If so, run the dynamic linker with the verbose option (you'll have to figure out the name of the dynamic linker on your platform, for Arch linux, it is ldd):
ldd --verbose 'your_program_name'
That will tell you if you're missing any dependencies (shared libs etc)
Run readelf -a 'your_program_name'
Make sure the file mentioned in Requesting program interpreter: /lib/ld-linux.so.2 exists. In this case, that filename is /lib/ld-linux.so.2
If this fails to help you figure out the problem, post the complete output of ldd --verbose 'your_program_name' and readelf -a 'your_program_name' in your question.
Another issue may be that the NAS software just kills foreign programs. I'm not sure why it would, but we're talking about a big corporation here (Seagate) and they have odd ideas of how the world works at times...
Edit, after looking at the pastebin of readelf:
From what I see, your Hello executable differs in 2 ways from the zip executable:
It is not dynamically linked, so that throws out a whole load of problems to look for.
There's a difference in how the 2 programs are built. zip does not use softfloats and Hello does. I suspect the soft-float dependency is due to one or both of these compiler switches: -mfloat-abi=softfp -mfpu=vfp
Hello Flags: 0x5000202, has entry point, Version5 EABI, soft-float ABI
zip Flags: 0x5000002, has entry point, Version5 EABI
I'd start with either:
Removing the soft-float option from the Hello build or:
make sure the soft-float emulation libraries are on the machine. I don't know what libs this would depend on, but I do remember MontaVista supplying them the last time I touched their software. It's been 8+ years since I touched MontaVista so it's clouded in a bit of old-memory fog.
This is an old thread, but I just wanted to add that I succeeded in compiling a "hello world" for this old NAS today.
Running ld-linux.so.3 <app> told me that
ELF load command alignment not page-aligned
Googling this, I found this: https://github.com/JuliaLang/julia/issues/33293, which pointed me to linker-options:
-Wl,-z,max-page-size=0x10000
Compiling with these options yielded en ELF that actually did work!
Are you sure your compilation options are correct ?
Try the following :
strace your application (if strace is present on the NAS)
downloas one of the NAS binary and run arm-none-linux-gnueabi-readelf -a on it, do the same on your helloworld program and see if the abi tag differ.
It looks like an illegal instruction issue, a floating point issue or an incompatible libc issue.
Edit : according to readelf output, nas program are compiled without soft float, you should try that.

Objdump -S does not show the source code listing of Linux kernel module

I am trying to debug a crash from one of my kernel module ; I am trying to get source code listing along with output of objdump but it is not listing. Is there something I am missing ?
mips-linux-objdump -S <filename.o> > temp
Most likely either a) all debugging information was stripped off the kernel module object file at some point during the build or b) even if the debugging information is there, objdump can't locate the source code files, in which case you might try to cd to where the source files are before running objdump.
You need to compile your kernel module with the debug information to have the interleaved source code in the dumped output. Recompile your kernel module with -g -ggdb for CFLAGS.

Debug assembly code using Kdbg

I have a project with one .c C source code and one .S assembly source code. Once compiled and linked, is there any way to debug .S code using Kdbg? I am calling one .S function from .c file but no code loads in Kdbg.
Add a .file directive in your source, like: .file "sourceasm.s". Kdbg will then use it as expected.
I I just tried kdbg (the KDE front-end for gdb, not the Linux kernel debugger kgdb of almost the same name).
It doesn't seem to have a proper disassembly mode like regular gdb's layout asm. You can set the "memory" window to disassembly and the address to $pc (and it updates as you single step), but that ties up the memory window and isn't very flexible for setting breakpoints or scrolling backwards to instructions before the current RIP/EIP.
Even if you're debugging asm source, you sometimes want to have the debugger show you the real disassembly, as well / instead of the asm source. For example in code that uses macros, or NASM %rep to repeat blocks.
AFAICT, kdbg is not a very good choice for asm debugging. text-mode GDB with layout asm / layout reg is ok; see the bottom of the x86 tag wiki for tips. I've also tried https://github.com/cs01/gdbgui. It has a disassembly mode, but it's not very nice.
As #ivan says, kgdb will let you do source level debugging of asm source files if you add enough metadata for it to know what source file the object came from.
gcc: Build with gcc -g foo.S
NASM: Assemble with nasm -felf64 -g -Fdwarf to include DWARF debug info. (The NASM default is STABS debug info, which also works.)
YASM: Assemble with yasm -felf64 -gdwarf2.
See Assembling 32-bit binaries on a 64-bit system (GNU toolchain) for more about building static / dynamic binaries from asm source.

Using objdump for ARM architecture: Disassembling to ARM

I have an object file and am trying to disassemble it. When I use:
objdump -d example.o
I get an assembly in code in the file format of elf64-x86-64.
I am trying to disassemble this into ARM, how do I go about doing this?
If you want to do disassemble of ARM code, you'd better have an ARM tool chain, this is what I got:
http://bb.osmocom.org/trac/wiki/toolchain
After you have this, you can use arm-elf-objdump instead of objdump.
The command I used is
arm-elf-objdump -D -b binary -marm binaryfile.dat
If you look the manpage, you will find "-b" is followed by the file type. Sorry I don't know how to tell -b you want to analyze a .o file. "-marm" will tell the cpu is ARM.
Hope this can help you.
Compile binutils with the right target(s) to get binutils objdump binary that knows how to disassemble ARM.
http://www.gnu.org/software/binutils/
./configure --enable-targets=all for example.
Pick your targets, make and use the new objdump binary that is your-target-aware. See the binutils/README file for more information on targeting.
objdump -D t3c # stock binary
objdump: t3c: File format not recognized
vs.
./../../binutils-2.22/binutils/objdump -D t3c # latest compiled from source with all targets
In archive t3c:
t3c:arm: file format mach-o-le
Disassembly of section .text:
00002d94 <start>:
2d94: e59d0000 ldr r0, [sp]
...
Before disassembling the binary, check the filetype via "file", for example:
file dnslookup.o
dnslookup.o: ELF 32-bit LSB relocatable, ARM, EABI5 version 1 (SYSV),
not stripped
So now we know it is an ARM object or ELF file.
To disassemble arm object file use
arm-linux-gnueabi-objdump. In Ubuntu, "arm-linux-gnueabi-objdump" is the default disassembler for ARM binaries - no compilation is needed.
To install it, just do:
sudo apt-get install binutils-arm-linux-gnueabi
There are also other binaries inside this package that can further analyze the ARM binaries for you.
Install the ELDK and use arm-linux-objdump. You're trying to disassemble ARM instructions using a program that only knows x86.

Resources