spkhaira
spkhaira

Reputation: 819

Object files in an executable in Linux

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

Answers (7)

T.Weaver
T.Weaver

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

beeka
beeka

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

tuxdna
tuxdna

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

Mikel Rychliski
Mikel Rychliski

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

isedev
isedev

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

Marco van de Voort
Marco van de Voort

Reputation: 26401

In addition to nullptr, "shared object" refers to other shared libraries (linked), not to original objects (not linked)

Upvotes: 1

Jase Whatson
Jase Whatson

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

Related Questions