I'm using IAR toolchain to compile few source files and then link generated .o files.
However, I'm running into linking errors like below:
Error[Li005]: no definition for "main" [referenced from cmain.o(rt7M_tl.a)]
Error[Lc036]: no block or place matches the
pattern "ro code section .intvec in vector_table_M.o(rt7M_tl.a)"
As I understand, ILINK linker is trying to link object files as an executable image and in the process adding dependencies from standard libraries[ i.e looking for main() and interrupt vector table ].
What I'm looking for :
How to configure linker to not to add these system-library dependencies like main/start/interrupt-vector-table etc. ?
How to configure linker to output a non-executable image from bunch of object files - if that at all is possible ?
You can think of this non-executable image sort of configuration-table image which will be put in persistent memory to be read/write by main application image.
If you tell the linker that you don't have an entry point with the command line option '--no_entry' you will get rid of the reference to main and the .intvec data.
However you do need to tell the linker what it should keep.
--keep and/or __root can help you with that.
I could see lib/asm-offset.c file in u-boot(2014.07) source(another file at arch/arm/lib/asm-offsets.c), main function is defined in these files. Initially I got doubht who will call this main function, I checked Makefile, but no entry for this file in Makefile also. After build there is no object file for this. I could see only asm-offsets.s and asm-offsets.su files after build. asm-offsets.s is around 1000 lines and asm-offsets.su is having only one line - asm-offsets.c:19:5:main 0 static. From the asm-offsets.c source, it seems it is declaring some variables. Can you please help to understand how this source is embedded in U-boot bin
lib/asm-offsets.c file is used to generate header file with definitions for global data size, board info size etc..., These definitions will be used in assembly files.
We can see following lines while building u-boot.
CC lib/asm-offsets.s
GEN include/generated/generic-asm-offsets.h
similarly for arch/arm/lib/asm-offsets.c
CC arch/arm/lib/asm-offsets.s
GEN include/generated/asm-offsets.h
Is there anyway i can look into the values of a structure after compilation? objdump -td gives the function definitions and only the address where the structure is stored. The problem is i am getting a wrong address for one of the threads/functions in a structure when i run a program. The target mcu is lpc1347 (ARM Cortex-m3).
objdump parses object files (products of the compiler), which are relocatable (not executable) ELF files. At this stage, there is no such notion as the memory address these compiled pieces will run at.
You have the following possibilities:
Link your *.obj files into the final non-stripped (-g passed to compiler) executable ELF image and parse it using readelf.
Generate the linker map file by adding -Wl,-Map,file.map to your LDFLAGS and see the output sections and addresses your data is located at in the map file.
Use a debugger/gdb.
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?
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.
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.
Here is an idea, need to refine based on your specific build. Make a build, log it using script (for example script log.txt make clean all). The last (or one of the last) step should be the linking of object files. (Tip: look for cc -o <your_binary_name>). That line should link all .o files which should have corresponding .c files in your tree. Then grep those .c files for all the included header files.
If you have duplicate names in your .c files in your tree, then we'll need to look at the full path in the linker line or work from the Makefile.
What Mahmood suggests below should work too. If you have an image with symbols, strings <debug_image> | grep <full_path_of_src_directory> should give you a list of C files.
You can use unix nm tool. It shows all symbols that are defined in the object. So you need to:
Run nm on your binary and grab all undefined symbols
Run ldd on your binary to grab list of all its dynamic dependencies (.so files your binary is linked to)
Run nm on each .so file youf found in step 2.
That will give you the full list of dynamic symbols that your binary use.
Example:
nm -C --dynamic /bin/ls
....skipping.....
00000000006186d0 A _edata
0000000000618c70 A _end
U _exit
0000000000410e34 T _fini
0000000000401d88 T _init
U _obstack_begin
U _obstack_newchunk
U _setjmp
U abort
U acl_extended_file
U bindtextdomain
U calloc
U clock_gettime
U closedir
U dcgettext
U dirfd
All those symbols with capital "U" are used by ls command.
If your goal is to analyze C source files, you can do that by customizing the GCC compiler. You could use MELT for that purpose (MELT is a high-level domain specific language to extend GCC) -adding your own analyzing passes coded in MELT inside GCC-, but you should first learn about GCC middle-end internal representations (Gimple, Tree, ...).
Customizing GCC takes several days of work (mostly because GCC internals are quite complex in the details).
Feel free to ask me more about MELT.
how to separate data part of an elf file using a C program
Thanks
You can browse the source code of elfdump or use the elfio library http://elfio.sourceforge.net/