Methodology

Every number these tools display comes from a documented field in the file. Nothing is guessed, inferred from a filename, or downloaded from a database. This page states the rules so any result can be checked with the real tool.

Where the file goes

Nowhere. Files are opened with the browser's File API and parsed with DataView over slices of the file. There is no upload request — you can confirm this in the network panel of your developer tools, where you will see no request carrying the file. Only the byte ranges needed are read: the ELF header, the two header tables, the string tables, the dynamic section, the symbol tables and the version-needs section.

Structures read

What is shownSourceEquivalent command
Class, endianness, OS ABIe_ident[0..8]readelf -h
Type, machine, entry, flagsElf_Ehdrreadelf -h
Section listsection header table + .shstrtabreadelf -S
Segment listprogram header tablereadelf -l
Symbols.symtab, .dynsym + linked string tablereadelf -s
NEEDED / SONAME / RPATH / RUNPATH.dynamic (SHT_DYNAMIC)readelf -d
Required symbol versions.gnu.version_r (verneed/vernaux)readelf -V
InterpreterPT_INTERPreadelf -l | grep interpreter
Build ID.note.gnu.build-idreadelf -n

Derived verdicts, and the rule behind each

  • PIE — e_type == ET_DYN and (DT_FLAGS_1 & DF_1_PIE or a PT_INTERP segment is present). The second condition is required: shared libraries are also ET_DYN, so type alone cannot separate them.
  • RELRO — full when PT_GNU_RELRO exists and the binary binds now (DT_BIND_NOW, or DT_FLAGS & DF_BIND_NOW, or DF_1_NOW); partial when only the segment exists; none otherwise.
  • NX — read from PT_GNU_STACK: enabled when the execute bit is clear. If the segment is absent the answer is reported as unknown, not as enabled, because that case depends on the kernel's fallback rather than on the file.
  • Stack canary — reported as present when a symbol named __stack_chk_fail is referenced. This is evidence that stack protection was enabled, not proof that every function is protected.
  • FORTIFY — presence of symbols matching __*_chk.
  • Statically linked — no PT_INTERP and an empty DT_NEEDED list.
  • Stripped — absence of a .symtab section. Absence of .dynsym is reported separately, because a dynamically linked binary should always have one.
  • Libc family — derived from the PT_INTERP path: ld-musl-* means musl, ld-linux* or ld64.so* means glibc.

Known limits

  • The demangler is a subset with a strict correctness gate. It covers plain nested names, templates, the common substitutions (St, Sa, Sb, Ss), constructors and destructors, and member-function qualifiers. Anything else — most importantly S_/S0_ references into the substitution table, vtables, typeinfo and thunks — makes it return nothing and the raw symbol is shown instead. A partially decoded name would look authoritative and be wrong, which is worse than no decoding. On libstdc++.so.6 this resolves roughly half the C++ symbols; the rest are shown raw. Empty parameter lists are printed as (void) rather than (), which is deliberate: it distinguishes "no arguments" from a failed parse.
  • No execution, no disassembly. The tools never run the file and never interpret instructions. "Executable segment" is a flag, not a claim about what the code does.
  • Symbol output is capped. Large libraries are truncated at a few thousand entries for the inspector (twenty thousand for the string/symbol extractor), with the true count always reported alongside.
  • Malformed files. Offsets are bounds-checked before every read, so a truncated or hostile file produces a warning rather than a crash. In that case trust readelf on the same file before trusting anything here.
  • Non-ELF files are identified, not parsed. Mach-O, PE, ar archives, gzip streams and Java class files are recognised by magic bytes and named, but their internals are not read.

Verifying a result

Pick any field and reproduce it. For example, the hardening summary:

readelf -lW ./app | grep -E 'GNU_RELRO|GNU_STACK|interpreter'
readelf -dW ./app | grep -E 'BIND_NOW|FLAGS'
readelf -hW ./app | grep -E 'Type|Machine'

If a value here disagrees with readelf from binutils on the same file, that is a bug — please report it via the contact page with both outputs.