I use embedded system. After the C source code building I get many files. The file name is the same, but the extension is different:
.s37
.elf
.hex
.sig
What is the differences between them? Mainly what is the differences between .s37 and .elf?
Those are just different executable formats.
.s37 is one variant of SREC format, it's ascii/line fixed text including hex (binary)
This format is well known by flash/upload software in most embedded targets.
.elf is an executable & linkable file, product of a linker like gcc or other commercial compilers (Windriver, CodeWarrior...).
.elf format is hardly uploadable on embedded targets without conversion to .SREC with objcopy first.
One of the main differences in contents is that .elf format can contain debugging symbols, whereas .srec/.s37 cannot.
My guess is that your toolchain does it all: link: .elf, then objcopy to convert .elf to .s3 for target upload (losing symbol information if any, which requires you to keep the .elf file handy when debugging your application on the target, the SREC file contains only code & data, no debug).
S3 format can't contain symbols. They're discarded, even using a simple objcopy command. That format is only useful to contain code/data to upload on a target.
Related
I have builded the U-boot for minnowboard max. I am seeing the files like uboot.rom uboot.bin etc.
what is the difference between uboot.rom and uboot.bin ? Which files I should flash to SPI NOR flash.
This is explained in doc/README.x86. In short, if you are going to be writing U-Boot to SPI NOR then you need to ensure that you have the correct binary blobs in the correct locations AND use BUILD_ROM=y so that u-boot.rom is generated as this is the file that is required on x86 to run on bare metal (rather than say as a coreboot payload).
Edit to address the comment:
The file 'u-boot' is the ELF object that is the result of building all of the U-Boot sources and linking them. This includes all of the extra sections and information an ELF file can contain. This is also by and large not bootable. The u-boot.bin file is the ELF u-boot but passed via objcopy to strip out (by and large, see the Makefile for the various flags or build with V=1) everything except for text/data sections so that we have only what is required to boot. Then u-boot.rom is the combination of objects and formatting that the x86 architecture requires in order to execute and run an image. Building with V=1 will show all of the details here.
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.
This may be compiler specific, in which case I am using the IAR EWARM 5.50 compiler (firmware development for the STM32 chip).
Our project consists of a bunch of C-code libraries that we compile first, and then the main application which compiles its C-code and then links in those libraries (pretty standard stuff).
However, if I use a hex editor and open up any of the library object files produced or the final application binary, I find a whole bunch of plain text references inside the output binary to the file paths of the C files that were compiled. (eg. I see "C:\Development\trunk\Common\Encryption\SHA_1.c")
Two issues with this:
we don't really want the file paths being easily readable as that indicates our design some what
the size of the binary grows if you have your C-files located in a long subdirectory (the binary contains the full path, not just the name)...this is especially important when we're dealing with firmware that has a limited amount of code space (256KB).
Any thoughts on this? I've tried all the switches in the compiler I can think of to "remove debug information", etc., but those paths are still in there.
"The command-line option --no_path_in_file_macros has been added. It removes the path leaving only the filename for the symbols FILE and BASE_FILE."
It is defined in the release notes if IAR.
http://supp.iar.com/FilesPublic/UPDINFO/005832/arm/doc/infocenter/iccarm_history.ENU.html
Or you can look for FILE and BASE_FILE macros and remove it you do not want to use the flag.
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.
When I'm linking .o files with the LD linker using MinGW on Windows, it gives me the error "file.o: File not recognized: file format not recognized". I've tried to do it with cygwin instread, but the same thing happens. Any suggestions?
Most likely you have a object file in a format that the linker does not understand. There are lots of different formats out there: COFF, OMF, ELF (the list goes on..)
Fortunately there is a free tool that lets you convert from one format to another. It also lets you take a look into the internals of the object format and tells you in which format a object file is encoded.
http://www.agner.org/optimize/#objconv
That little command line utility solved all the object format problems I ever had. It can even disassemble libs, object files, DLLs and executables.