The final images produced by compliers contain both bin file and extended loader format ELf file ,what is the difference between the two , especially the utility of ELF file.
-
[This is what NASM has to say](http://www.nasm.us/doc/nasmdoc7.html#section-7.1). Not ARM specific, but likely to be the same concept. E.g., if you compile a file containing just `NOP` without `-f` (or `-fbin`), it compiles to a single byte `0x90`, instead of a 400 byte ELF container with `-felf32`. So just the raw code, no container metadata. NASM says it is mostly used for MS-DOS .COM and [.SYS](https://en.wikipedia.org/wiki/.sys) files. `section` directives are mostly ignored and only generate alignment. – Ciro Santilli OurBigBook.com Apr 29 '15 at 09:54
-
This is one way in which bin files can be useful: to make a boot sector to deploy operating systems: http://stackoverflow.com/a/32483545/895245 – Ciro Santilli OurBigBook.com Sep 17 '15 at 17:57
6 Answers
A Bin file is a pure binary file with no memory fix-ups or relocations, more than likely it has explicit instructions to be loaded at a specific memory address. Whereas....
ELF files are Executable Linkable Format which consists of a symbol look-ups and relocatable table, that is, it can be loaded at any memory address by the kernel and automatically, all symbols used, are adjusted to the offset from that memory address where it was loaded into. Usually ELF files have a number of sections, such as 'data', 'text', 'bss', to name but a few...it is within those sections where the run-time can calculate where to adjust the symbol's memory references dynamically at run-time.

- 34,087
- 8
- 78
- 110
-
"more than likely it has explicit instructions to be loaded at a specific memory address": does this mean the bin file generation process adds additional code for loading data to specific address? – Penghe Geng May 28 '14 at 14:44
-
1As far I has learned is the bin file is like running the program from offset 0 and the data segment is embedded within. If this is wrong please correct me. – Martin Kersten Apr 09 '15 at 01:26
-
-
1@t0mm13b So .elf files can be burned onto a micro-controller just like a regular .hex file but it takes more flash memory, and every time the micro is reset, the sections addresses changes? – Aelgawad Jan 16 '16 at 20:17
-
@BlackyDucky, I do not believe that is possible. If a microcontroller tried to execute ELF data directly it would misinterpret the headers and other data as instructions, right? – jacobq Aug 18 '16 at 23:45
-
@Aelgawad gdb will burn only the binary portions of the .elf onto a microcontroller with the 'load' command. It takes the same amount of flash, but with debug information for gdb on the host. The elf metadata also says where in the microcontroller's memory to load each section. Elf does not have to be relocatable, on a micro each section will be loaded at a fixed location. – joeforker Jul 28 '17 at 19:32
-
"does this mean the bin file generation process adds additional code for loading data to specific address" - He means that the device will require you to load the binary into RAM at a specific address in its memory to be executed. This is common for microcontrollers. They might have a specific area of memory on the device designated as flash memory for flashing the device ROM. – ajxs Sep 07 '19 at 09:53
A bin file is just the bits and bytes that go into the rom or a particular address from which you will run the program. You can take this data and load it directly as is, you need to know what the base address is though as that is normally not in there.
An elf file contains the bin information but it is surrounded by lots of other information, possible debug info, symbols, can distinguish code from data within the binary. Allows for more than one chunk of binary data (when you dump one of these to a bin you get one big bin file with fill data to pad it to the next block). Tells you how much binary you have and how much bss data is there that wants to be initialised to zeros (gnu tools have problems creating bin files correctly).
The elf file format is a standard, arm publishes its enhancements/variations on the standard. I recommend everyone writes an elf parsing program to understand what is in there, dont bother with a library, it is quite simple to just use the information and structures in the spec. Helps to overcome gnu problems in general creating .bin files as well as debugging linker scripts and other things that can help to mess up your bin or elf output.
-
Clear explanation! So how would the loader know where to load the bin ? If we take the case of a simple bin that would print some ascii onto the VGA display on X86, should we compile the elf with a linker that has its _start set to something like 0x7C00 ? What I understand from the answer is the linker could set the start to any value which we lose while converting the elf to a bin. It is the BIOS loader which has probably hardcoded load address 0x7C00 which does the job of loading to the proper address. Could you correct me if I'm wrong ? – RohitMat Jun 15 '20 at 13:10
-
10x7C00 sounds like a bootloader thing which doesnt use elf necessarily. this is a generic question. an operating system would have rules for the (virtual) address spaces, the toolchain would need to be targetted at that operating systems rules, then the file format would indicate loadable items with addresses plus an entry point once loaded, plus other things. elf is just a container, like a box, you have to pack it right for the targetted use case. – old_timer Jun 15 '20 at 16:51
-
1if you want to print some ascii to the vga, you write a *program* to do that which has some data or mathmatically generates the data on the fly or some combination, then you load that program into the operating system defined code space, and then run it. you dont generally shove data right into a physical peripheral, and its the rare operating system that would let you do that anyway, or allow its loader to do that. – old_timer Jun 15 '20 at 16:51
-
sorry for the confusion. I think I did not give the context to my question. I was trying to do some bare metal programming on x86. Your answer helped me understand what elf and bin are. In general for meta data stripped bins, there should be a seperate entity that has details on where to load it ? Like in my case the bios loads the MBR where we have the bin ? On microcontrollers, are bins directly programmed to the reset vector as a start ? – RohitMat Jun 15 '20 at 18:24
-
1for bare metal, esp if this elf file is the bootloader and/or first program run, then the entry point and _start are not relevant as you use the elf file as a stepping stone to either a tool that programs the flash (like openocd over jtag) or through whatever-whatever-objcopy -O binary file.elf file.bin and then that file is somehow loaded into the flash. Not gone and tried a bootloader on x86 but assume that the bios cant parse elf files so it would need to be a memory image as well. so a -O binary type bin file – old_timer Jun 16 '20 at 04:06
-
1the separate entity is the hardware/logic or other design. for operating systems then the operating system makes the rules, for a microcontroller the chip/processor design makes the rules. for example if there is a vector table and then the vectors point to the handlers you have to roll all of that into your linker script, etc so that the loadable data is destined for the flash that the thing boots off of. – old_timer Jun 16 '20 at 04:08
-
and for your 0x7C00 thing if that is the address of the first instruction lets say then you need to build the binary including telling the linker that 0x7C00 is where your first instruction is and that is at the front of the memory image the .bin file if you will. then whatever tools you use to get that image on a usb or cdrom or dvd or hard disk will want some file format to move that data there, probably .bin not .elf you tell me... – old_timer Jun 16 '20 at 04:10
-
1To broaden that your target has rules be it an operating system or a processor or a multi-stage bootloader, etc. And you need to build your "binary" based on those rules, the bootstrap and linkerscript being most important. Then it is very broad as to each target and how you apply that binary and what file formats are supported. Assuming gnu on a number of host development platforms the elf file format is the default output and then you use tools as needed (if the target specific utilities/loaders) to extract or convert from elf to something else. – old_timer Jun 16 '20 at 04:17
-
1Many of those something elses are also called a "binary" but in a different file format. Some have address and data information some like the objcopy -O binary output are data only and the user or target specific tool needs to know or be told the address as the file format doesnt contain that information. – old_timer Jun 16 '20 at 04:18
-
some resources:
- ELF for the ARM architecture
http://infocenter.arm.com/help/topic/com.arm.doc.ihi0044d/IHI0044D_aaelf.pdf - ELF from wiki
http://en.wikipedia.org/wiki/Executable_and_Linkable_Format
ELF format is generally the default output of compiling. if you use GNU tool chains, you can translate it to binary format by using objcopy, such as:
arm-elf-objcopy -O binary [elf-input-file] [binary-output-file]
or using fromELF utility(built in most IDEs such as ADS though):
fromelf -bin -o [binary-output-file] [elf-input-file]

- 673
- 1
- 6
- 16
-
6This was added after the bin file detail was answered, and *does* add-on a practically useful technique. +1 for that. – erbdex May 31 '15 at 23:48
bin is the final way that the memory looks before the CPU starts executing it.
ELF is a cut-up/compressed version of that, which the CPU/MCU thus can't run directly.
The (dynamic) linker first has to sufficiently reverse that (and thus modify offsets back to the correct positions).
But there is no linker/OS on the MCU, hence you have to flash the bin instead.
Moreover, Ahmed Gamal is correct.
Compiling and linking are separate stages; the whole process is called "building", hence the GNU Compiler Collection has separate executables:
One for the compiler (which technically outputs assembly), another one for the assembler (which outputs object code in the ELF format), then one for the linker (which combines several object files into a single ELF file), and finally, at runtime, there is the dynamic linker, which effectively turns an elf into a bin, but purely in memory, for the CPU to run.
Note that it is common to refer to the whole process as "compiling" (as in GCC's name itself), but that then causes confusion when the specifics are discussed,
such as in this case, and Ahmed was clarifying.
It's a common problem due to the inexact nature of human language itself.
To avoid confusion, GCC outputs object code (after internally using the assembler) using the ELF format. The linker simply takes several of them (with an .o extension), and produces a single combined result, probably even compressing them (into "a.out").
But all of them, even ".so" are ELF. It is like several Word documents, each ending in ".chapter", all being combined into a final ".book", where all files technically use the same standard/format and hence could have had ".docx" as the extension.
The bin is then kind of like converting the book into a ".txt" file while adding as many whitespace as necessary to be equivalent to the size of the final book (printed on a single spool), with places for all the pictures to be overlaid.
-
-
Wouldn't say "cut-up" since ELF is much bigger then the pure binary. – Angelo Dureghello Aug 03 '23 at 08:01
I just want to correct a point here. ELF file is produced by the Linker, not the compiler.
The Compiler mission ends after producing the object files (*.o) out of the source code files. Linker links all .o files together and produces the ELF.

- 55
- 2
-
1Downvoted because it's not answering the question nor necessarily correct. Broadly defined, compilation includes linking. Quoted from the [`ld` documentation](https://sourceware.org/binutils/docs-2.34/ld/Overview.html#Overview): _Usually the last step in compiling a program is to run ld._ – bzeaman May 12 '20 at 21:38
-
Downvoted because wrong info was given. `.o` are also ELF files, of type _relocatable_. There are other two types: _executable_ and _shared object_. So yes, the assembler produces ELF files, as well as the linker does. – SenhorLucas Apr 18 '23 at 05:42
Pure binary is a sequence of executable opcodes to be executed from his 0 offset, ** but not only **.
Pure binaries are generally used on microcontrollers, bare metal programming and initial boots, where there is no "laoder" except the ROM loader.
Pure binaries includes .bss and .data, that from binaries that are read from flash memory as in a microcontroller, have to be relocated somewhere in ram. A binary file can include a vector table, symbol tables for "rel" or "rela" relocation (see -fPIC), got table and so on. All this additional data are obtained from the ELF->binary conversion, since the addresses of this specific tables are obtained from the ELF.
Another important point for the binary production are "linker scripts", they produce section offsets, and different addresses used in the absolute jumps depending of the declared sections.
Final note: pure binaries code (.text) is also often relocated to ram, since cpu internal sram is generally not too big. For this, such relocation tables comes into use.

- 154
- 1
- 6