Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to find out *.c and *.h files that were used to build a binary?

Tags:

c

linux

gcc

build

I am building a project that builds multiple shared libraries and executable files. All the source files that are used to build these binaries are in a single /src directory. So it is not obvious to figure out which source files were used to build each of the binaries (there is many-to-many relation).

My goal is to write a script that would parse a set of C files for each binary and make sure that only the right functions are called from them.

One option seems to be to try to extract this information from Makefile. But this does not work well with generated files and headers (due to dependence on Includes).

Another option could be to simply browse call graphs, but this would get complicated, because a lot of functions are called by using function pointers.

Any other ideas?

like image 756
user389238 Avatar asked Aug 29 '12 21:08

user389238


People also ask

Where does C look for header files?

GCC looks for headers requested with #include " file " first in the directory containing the current file, then in the directories as specified by -iquote options, then in the same places it would have looked for a header requested with angle brackets.

Which option in GCC is used to specify the location of the .h files?

gcc -I adds include directory of header files.

Do .h files get compiled?

Only source files are passed to the compiler (to preprocess and compile it). Header files aren't passed to the compiler. Instead, they are included from source files.

Where are header files in Linux?

The C library's header files include the kernel header files from the “linux” subdirectory. The system's libc headers are usually installed at the default location /usr/include and the kernel headers in subdirectories under that (most notably /usr/include/linux and /usr/include/asm).


2 Answers

You can first compile your project with debug information (gcc -g) and use objdump to get which source files were included.

objdump -W <some_compiled_binary>

Dwarf format should contain the information you are looking for.

 <0><b>: Abbrev Number: 1 (DW_TAG_compile_unit)
    < c>   DW_AT_producer    : (indirect string, offset: 0x5f): GNU C 4.4.3 
    <10>   DW_AT_language    : 1    (ANSI C)
    <11>   DW_AT_name        : (indirect string, offset: 0x28): test_3.c    
    <15>   DW_AT_comp_dir    : (indirect string, offset: 0x36): /home/auselen/trials    
    <19>   DW_AT_low_pc      : 0x82f0   
    <1d>   DW_AT_high_pc     : 0x8408   
    <21>   DW_AT_stmt_list   : 0x0  

In this example, I've compiled object file from test_3, and it was located in .../trials directory. Then of course you need to write some script around this to collect related source file names.

like image 159
auselen Avatar answered Nov 09 '22 23:11

auselen


First you need to separate the debug symbols from the binary you just compiled. check this question on how to do so: How to generate gcc debug symbol outside the build target?

Then you can try to parse this file on your own. I know how to do so for Visual Studio but as you are using GCC I won't be able to help you further.

like image 43
Mahmoud Fayez Avatar answered Nov 09 '22 23:11

Mahmoud Fayez