What is the difference between ELF files and bin files?

119,713

Solution 1

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.

Solution 2

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.

Solution 3

some resources:

  1. ELF for the ARM architecture
    http://infocenter.arm.com/help/topic/com.arm.doc.ihi0044d/IHI0044D_aaelf.pdf
  2. 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]

Solution 4

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.

Solution 5

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.

Share:
119,713

Related videos on Youtube

Manik Mahajan
Author by

Manik Mahajan

Updated on June 02, 2021

Comments

  • Manik Mahajan
    Manik Mahajan about 3 years

    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.

    • Ciro Santilli OurBigBook.com
      Ciro Santilli OurBigBook.com about 9 years
      This is what NASM has to say. 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 files. section directives are mostly ignored and only generate alignment.
    • Ciro Santilli OurBigBook.com
      Ciro Santilli OurBigBook.com almost 9 years
      This is one way in which bin files can be useful: to make a boot sector to deploy operating systems: stackoverflow.com/a/32483545/895245
  • Penghe Geng
    Penghe Geng about 10 years
    "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?
  • Martin Kersten
    Martin Kersten about 9 years
    As 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.
  • erbdex
    erbdex about 9 years
    This was added after the bin file detail was answered, and does add-on a practically useful technique. +1 for that.
  • t0mm13b
    t0mm13b about 9 years
    @MartinKersten correct, bin files start from offset 0.
  • Aelgawad
    Aelgawad over 8 years
    @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?
  • jacobq
    jacobq almost 8 years
    @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?
  • joeforker
    joeforker almost 7 years
    @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.
  • ajxs
    ajxs almost 5 years
    "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.
  • bzeaman
    bzeaman about 4 years
    Downvoted because it's not answering the question nor necessarily correct. Broadly defined, compilation includes linking. Quoted from the ld documentation: Usually the last step in compiling a program is to run ld.
  • RohitMat
    RohitMat about 4 years
    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 ?
  • old_timer
    old_timer about 4 years
    0x7C00 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
    old_timer about 4 years
    if 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.
  • RohitMat
    RohitMat about 4 years
    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 ?
  • old_timer
    old_timer about 4 years
    for 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
    old_timer about 4 years
    the 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
    old_timer about 4 years
    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
    old_timer about 4 years
    To 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
    old_timer about 4 years
    Many 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.
  • RohitMat
    RohitMat about 4 years
    Thanks a lot old_timer for your insights. Really appreciate it!
  • greybeard
    greybeard about 3 years
    (You misspelled mammary.)