Reputation: 819
Is there a way to find the object files from which the current executable is generated in Linux (RHEL to be specific). I understand that one can use "nm" to find the exported symbols, "ldd" to find dependent shared object.
But I could not find command to find out the name of object (.o) files of which executable is composed of. Is it possible?
Upvotes: 9
Views: 6824
Reputation: 1
similar to Mikels answer but using a different tool that (may) give you a cleaner output.
In the past I've had the pleasure of working on a debug information analyzer tool called DIVA. It's free and open source and you can find it here:
https://github.com/SNSystems/DIVA
Whilst it's not possible with DIVA to find what object files were linked to produce your executable, you can use it to find out the compile units.
I quickly threw together a small example as follows
a.cpp
int a() {
return 1;
}
a.h
int a();
b.cpp
int b() {
return 2;
}
b.h
int b();
c.cpp
#include "a.h"
#include "b.h"
int main() {
return a + b;
}
Compiled them with clang using the following options
$ clang a.cpp b.cpp c.cpp -o test.elf -g -O0
run DIVA on test.elf with the following options:
$ diva --show-none test.elf
Which should produce the following output
{InputFile} "test.elf"
{CompileUnit} "a.cpp"
{CompileUnit} "b.cpp"
{CompileUnit} "c.cpp"
Upvotes: 0
Reputation: 66
I don't have enough reputation to add a comment, but to expand on the suggestion by Mikel Rychliski to use readelf, you can use awk to extract the paths of the source files:
readelf --debug-dump=info --dwarf-depth=1 hw exe_to_examine | awk '/DW_AT_name/ {file=$8} /DW_AT_comp_dir/ {print $8 "/" file}'
This outputs the full paths to the source files (.cpp files in my case) which are likely to be a close match to the object files (depending on your build system).
Upvotes: 1
Reputation: 8487
An object file translates to an executable after linking. If the linking is shared, then you can get that via shared libraries ( ldd
). However if the linking is static, then there is only way i.e. via debug info. You can install debuginfo packages in RHEL (or Fedora for that matter). Here are the instructions
And then use gdb info sources
as described here:
This would give you a list of Source Files. But to actually get the object files, you need to look deeper into the build tools (rpmbuild
). And to actually run rpmbuild you would need the Source RPM package, which you can obtain using the instructions listed here:
Now you can build the package yourselves, and dissect which .o
file resulted into the executable.
I hope that helps.
Upvotes: 1
Reputation: 3607
The original names of the object files are not stored in the DWARF debugging information.
Each object file has a DW_TAG_compile_unit
entry in the .debug_info
section. This entry contains a reference to the "primary source file
from which the compilation unit was derived", but not the name of the object file. The DWARF standard contains a list of the attributes that can be stored for each compilation unit (section 3.1.1, page number 44, pdf page 58).
You can view the information that is stored with the following command:
$ readelf --debug-dump=info --dwarf-depth=1 hw
Output:
Contents of the .debug_info section:
<some compilation units removed>
Compilation Unit @ offset 0x133:
Length: 0x8b (32-bit)
Version: 4
Abbrev Offset: 0x64
Pointer Size: 4
<0><13e>: Abbrev Number: 1 (DW_TAG_compile_unit)
<13f> DW_AT_producer : (indirect string, offset: 0x131): GNU C11 5.3.0 -mtune=generic -march=pentiumpro -g
<143> DW_AT_language : 12 (ANSI C99)
<144> DW_AT_name : (indirect string, offset: 0x163): hw.c
<148> DW_AT_comp_dir : (indirect string, offset: 0x168): /home/mikel/src/hw
<14c> DW_AT_low_pc : 0x80483db
<150> DW_AT_high_pc : 0x2e
<154> DW_AT_stmt_list : 0xea
<1><158>: ...
<some compilation units removed>
Upvotes: 7
Reputation: 19641
You can also use objdump
(as long as the executable and objects were compiled with debugging information):
# gcc -g -c -o /tmp/some_object.o /tmp/some_object.c
# gcc -g -o /tmp/file /tmp/file.c /tmp/some_object.o
# objdump -g /tmp/file | awk 'BEGIN{out=0} /Directory Table/{out=1} /Line Number Statements/{out=0} {if(out){print $0}}'
The Directory Table (offset 0x1b):
1 /tmp
The File Name Table (offset 0x21):
Entry Dir Time Size Name
1 1 0 0 file.c
The Directory Table (offset 0x5a):
1 /tmp
The File Name Table (offset 0x60):
Entry Dir Time Size Name
1 1 0 0 some_object.c
awk
is used just to extract the relevant info (if you don't use, you'll get the full debug info in the executable and objects).
Upvotes: 3
Reputation: 26401
In addition to nullptr, "shared object" refers to other shared libraries (linked), not to original objects (not linked)
Upvotes: 1
Reputation: 4207
If it has been compiled with debugging infomation yes. Use gdb (man gdb) to find the infomation.
If it hasnt been compiled without debug infomation. You are out of luck.
Upvotes: 6