Home / Alt manpages / x86_64-w64-mingw32-readelf(1)

  • x86_64-w64-mingw32-readelf(1)
  • User command
  • linux

Inspect ELF Files with the MinGW-w64 readelf Command

You will finish with a small, repeatable set of commands for examining an ELF file: its identity, loadable segments, sections, symbols and diagnostics. The commands are read-only. They do not rewrite the file, require root, or change a service.

This guide uses x86_64-w64-mingw32-readelf from binutils-mingw-w64-x86-64, package version 2.41.90.20240122-1ubuntu1+11.4 on this machine. The x86_64-w64-mingw32ucrt-readelf name is an alias for the same readelf purpose. Allow about ten minutes. You need a shell and a path to an ELF file.

Checkpoint

Start here if you are returning to the guide.

1. Confirm the binary and the input format

Check which executable the shell will run, then record its version. This is an ordinary command:

$ command -v x86_64-w64-mingw32-readelf
/usr/bin/x86_64-w64-mingw32-readelf
$ x86_64-w64-mingw32-readelf --version
GNU readelf (GNU Binutils) 2.41.90.20240122

Despite its MinGW-w64 prefix, this program reads ELF object files. The prefix identifies the binutils target build; it does not turn readelf into a PE or Windows executable inspector. Replace /bin/true in the examples with your own ELF file, object file or archive. If you are unsure, use the system file command first:

$ file /bin/true
/bin/true: ELF 64-bit LSB pie executable, x86-64, ...

Do not treat a file's name or extension as proof of its format. A non-ELF input produces an error. Reading an untrusted file can still consume time and memory, especially with large or unusual debug data, so inspect files in a suitable account and environment.

2. Read the ELF file header

Use -h, also spelled --file-header, for the file's top-level identity:

$ x86_64-w64-mingw32-readelf -h /bin/true
ELF Header:
  Magic:   7f 45 4c 46 02 01 01 00 ...
  Class:                             ELF64
  Data:                              2's complement, little endian
  Type:                              DYN (Position-Independent Executable file)
  Machine:                           Advanced Micro Devices X86-64
  Number of section headers:         30

The exact addresses, counts and type depend on the file. The useful checks are the ELF class, byte order, machine architecture and type. A 32-bit file and a 64-bit file can both be valid ELF inputs, but they are not interchangeable build artefacts.

Checkpoint

If you only need to answer "what is this ELF?", -h is usually enough. Stop before using -a; broad output is harder to search and can include a large amount of debug information.

3. Compare segments with sections

Sections describe information such as code, data, symbols and debug data. Use -S to list them. The -W option keeps each 64-bit row on one line instead of wrapping it for an 80-column terminal:

$ x86_64-w64-mingw32-readelf -W -S /bin/true
There are 30 section headers, starting at offset 0x61b8:

Section Headers:
  [Nr] Name              Type      Address          Off    Size ES Flg Lk Inf Al
  [ 1] .interp           PROGBITS  0000000000000318 000318 00001c 00   A  0   0  1
  [ 6] .dynsym           DYNSYM    00000000000003d8 0003d8 000450 18   A  7   1  8

Use -l for program headers, also called segments. These describe the portions the loader maps or uses at runtime:

$ x86_64-w64-mingw32-readelf -W -l /bin/true

Elf file type is DYN (Position-Independent Executable file)
Entry point 0x19f0
There are 13 program headers, starting at offset 64

Use -e when you specifically want the file header, program headers and section headers together. It is equivalent to -h -l -S. Neither command changes the file.

4. Inspect symbols and relocations

Use -s or --symbols for the ordinary symbol table. Use --dyn-syms for the dynamic symbol table, which is often the useful view for a dynamically linked executable:

$ x86_64-w64-mingw32-readelf -W --dyn-syms /bin/true
Symbol table '.dynsym' contains 46 entries:
   Num:    Value          Size Type    Bind   Vis      Ndx Name
     0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND
     1: 0000000000000000     0 OBJECT  GLOBAL DEFAULT  UND __progname@GLIBC_2.2.5

Names may include symbol-version suffixes such as @GLIBC_2.2.5. That is metadata in the file, not a command option. -D changes symbol and relocation display to use the dynamic section's information, so add it only when that is the view you need. Use -r for relocation entries.

Long C++ names remain mangled by default. Add -C or --demangle when readable C++ names help. Keep the default when you need to compare the exact stored names. The demangler has a recursion limit enabled by default. Disabling that limit with --no-recurse-limit can allow stack exhaustion on hostile or extremely complicated names, so leave it enabled for routine inspection.

5. Dump one section deliberately

First obtain a section name with -S, then ask for only that section. -p prints printable strings; -x prints hexadecimal bytes; -R prints relocated bytes:

$ x86_64-w64-mingw32-readelf -p .interp /bin/true
String dump of section '.interp':
  [     0]  /lib64/ld-linux-x86-64.so.2
$ x86_64-w64-mingw32-readelf -x .interp /bin/true
Hex dump of section '.interp':
  0x00000318 2f6c6962 36342f6c 642d6c69 6e75782d /lib64/ld-linux-
  ...

A section can also be selected by its numeric index. Do not guess the index from another file: section numbering is file-specific. If the selected section is compressed, add -z to request decompression before a hex, relocated or string dump.

6. Diagnose instead of guessing

-L, also spelled --lint, asks readelf to report possible problems. On its own it examines the file's contents:

$ x86_64-w64-mingw32-readelf -L /bin/true
ELF Header:
  Magic:   7f 45 4c 46 02 01 01 00 ...

The warnings are the useful part when a file is malformed or inconsistent. A quiet-looking run is not a proof that an executable is safe or compatible; it only means this checker found no reportable issue in the material it examined.

For an absent path, expect a non-zero status and an error on standard error:

$ x86_64-w64-mingw32-readelf -h /tmp/does-not-exist-readelf
readelf: Error: '/tmp/does-not-exist-readelf': No such file

Check the path, permissions and format before reaching for sudo. No example in this guide needs elevated privileges. If you dump DWARF data with -w, remember that separate debug links may be followed by default on this build. Use -wN when you want to prevent following those links, and avoid unexpected network lookups from debuginfod-enabled builds.

Done means

  • You confirmed the installed MinGW-w64 readelf version and the input is ELF.
  • You can read identity with -h, sections with -S and segments with -l.
  • You know when to use --dyn-syms, -r, -p and -x.
  • You use exact section names from the file instead of guessing indexes.
  • You have kept the inspection read-only and have not changed the binary or system.