Notgnoshi / elf-interrogation

Material for a presentation on ELF file interrogation inspired by Matt Godbolt's cppcon talk "The bits between the bits"

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

ELF Interrogation

Material for a presentation on ELF file interrogation inspired by Matt Godbolt's cppcon talk "The bits between the bits"

Why does it matter?

It's fascinating! And also useful!

Deepening my understanding of

  • The compilation process
  • The binary compilation artifacts
  • How processes start (specifically w.r.t. dynamic symbol resolution)

has increased my confidence, and enabled me to answer more challenging questions with less information available. I've been able to figure out tricky linker issues, debug DSO search paths, troubleshoot static global initialization ordering, troubleshoot versioned symbol conflicts, debug crashes on process startup, etc.

Interrogation tools

There are a host of binutils, elfutils, llvm-tools and other tools for interrogating ELF files. I've used (or otherwise poked at) the following:

Specific questions about ELF files

The compilation process, binary artifacts thereof, process runtime (startup, dynamic symbol resolution, debugging, stack unwinding, coredumps, etc) are all somewhat interconnected, and difficult to give enough of a summary to be dangerous, because of the sheer amount of information needed to cover it all.

Thus, despite my preference to build understanding from the bottom up in the general case, I think it makes most sense to ask (and answer) specific questions in this particular case.

  • What's an ELF file?

  • How are processes loaded into memory?

  • TODO - What is the compilation process?

    for traditional Linux GCC / LLVM builds and ARM Keil builds (I bet they're remarkably similar, but get nitty gritty with scatter files (linker scripts), axf, map, and ihex file pipeline)

  • TODO - What is linking?

    what do linkers do? How? Why?

  • TODO - How is main() executed?

    Lots of complexity provided by libc to do global initialization/deinitialization, exception handling, etc. before main() is actually invoked. Should cover the GCC default linker script, and .init_array.

  • TODO - How are dynamic symbols resolved?

    and how to debug dynamic symbol resolution?

  • TODO - How do ELF files differ between different compilers?

    https://godbolt.org for comparing disassembly.

  • TODO - How are debug symbols used?

    TIL about llvm-dwarfdump

  • TODO - How are coredumps generated?

    Include gcore in GDB

  • TODO - How do exceptions work?

    and Rust panics?

  • TODO - libstdc++, libcxx, libcxxabi, compiler-rt, libunwind, libgcc, libgcc_s, libatomic, libsupc++

    https://clang.llvm.org/docs/Toolchain.html

  • TODO - How does code coverage work?

  • TODO - Why are Rust binaries so large?

    Compiling an empty binary that returns 0 is several megabytes, despite there being nothing to statically link...

Resources

About

Material for a presentation on ELF file interrogation inspired by Matt Godbolt's cppcon talk "The bits between the bits"

License:MIT License