Frequently it is desirable to compare two ELF files. As someone who makes changes to the link-editor, comparing large numbers of built objects is a vital part of verifying any changes. In addition, determining what objects have changed from one build to another, can reduce object distribution to only those objects that have changed. Often, it is simply enlightening to know "what did I change in this ELF file to make it different?".
Various tools exist to compare ELF files, often being scripts that call upon tools like elfdump(1), dis(1), and od(1), to analyze sections in more detail. These tools can be rather slow and produce voluminous output.
ELF files have an inherent problem when trying to analyze differences — even a small change to a section within an object, ie. code changes to .text, .data or .rodata, can result in offset changes that ripple through the ELF file affecting many sections and the data these sections contain. Trying to extrapolate the underlying cause of a difference between two ELF files, amongst all the differences that exist, can be overwhelming.
elfdiff(1) attempts to analyze two ELF files and diagnose the most important changes. Typically, the most significant changes to an object can be conveyed from changes to the symbol table. Functions and data items get added or deleted, or change size. Most of the time this can be sufficient to know/confirm what has changed.
After providing any symbol information, elfdiff continues to grovel down into individual sections, and indicate what might have changed. The output style of the diagnostics are a mix of dis(1) for function diffs, od(1) for data diffs, and elfdump(1) style for sections that elfdump understands and provides high level formatted displays for.
The output is limited. A handful of symbols are displayed first. Sections report a single line of difference, or a single line of difference for each symbol already diagnosed. The styles of each difference, and the order in which they are displayed is covered in the elfdiff(1) man page.
This is an overview diff, appropriate for answering questions such as "What are the high level differences between two nightly builds". It does not replace lower level tools such as elfdump(1), but rather, provides a higher level analysis that might then be used to guide the use of lower level tools.
Some files may contain sections that always change from one build to another, things like comment or signature sections. These can be ignored with the -i option. Sometimes only one or two sections are of interested. These can be specified with the -s option. If you really want to see all the differences between two files, use the -u option. But be careful, the output can be excessive.
The following provides an example of comparing two versions of a shared object, and is lifted directly from the elfdiff(1) man page.
$ elfdiff -e foo.so.1 foo.so.2 *** symbols: differ <  0x935c0 0x1bd FUNC GLOB D 0 .text device_offline >  0x935c0 0x1f5 FUNC GLOB D 0 .text device_offline --- <  0x111240 0x20 FUNC GLOB D 0 .text new_device_A <  0x111260 0x64 FUNC GLOB D 0 .text new_device_B --- >  0 0 NOTY GLOB D 0 UNDEF __assfailline__13 *** section: .SUNW_cap: shdr information differs < sh_size: 0xe0 sh_type: [ SHT_SUNW_cap ] > sh_size: 0x120 sh_type: [ SHT_SUNW_cap ] *** section: .SUNW_cap: data information differs < 0x80:  CA_SUNW_ID 0x2317 i86pc-clmul > 0x80:  CA_SUNW_ID 0x1f59 i86pc-avx2 *** section: .text: shdr information differs < sh_size: 0x38e205 sh_type: [ SHT_PROGBITS ] > sh_size: 0x38e245 sh_type: [ SHT_PROGBITS ] *** section: .text: data information differs --- <sym>: device_offline() < 0x935d9:<sym>+0x19: 48 8b df movq %rdi,%rbx > 0x935d9:<sym>+0x19: 4c 8b e7 movq %rdi,%r12 --- < <sym>: new_device_A < 0x111240:<sym>: 55 push %rbp --- < <sym>: new_device_B < 0x111260:<sym>: 55 push %rbp *** section: .strtab: shdr information differs < sh_size: 0x642c5 sh_type: [ SHT_STRTAB ] > sh_size: 0x642d9 sh_type: [ SHT_STRTAB ] *** section: .strtab: data information differs < 0x42297: n e _ _ 1 3 8 5 \0 _ _ ... > 0x42297: n e _ _ 1 3 8 4 \0 _ _ ... *** section: .rela.text: shdr information differs < sh_size: 0x36d398 sh_type: [ SHT_RELA ] > sh_size: 0x36d428 sh_type: [ SHT_RELA ] *** section: .rela.text: data information differs < 0x0:  R_AMD64_32S 0x1635f4 0x1638b4 .text > 0x0:  R_AMD64_32S 0x163634 0x1638f4 .text *** section: .SUNW_ctf: shdr information differs < sh_size: 0xb33c sh_type: [ SHT_PROGBITS ] > sh_size: 0xb4e4 sh_type: [ SHT_PROGBITS ] *** section: .SUNW_ctf: data information differs < 0xd: \0 \0 \0 \08 \0 \0 \0 \b2 \03 \0 \0 D ... > 0xd: \0 \0 \0 \08 \0 \0 \0 \ba \03 \0 \0 $ ... *** section: .SUNW_signature: data information differs < 0x73: j o h n d o e \t \93 \ab \ff \fa ... > 0x73: j o h n d o e \c2 \c5 \98 r a ...