At first glance, both the executables that a compiler produces, and the libraries that are used during the building process seem like they’re not very accessible. They are these black boxes that make an application go, or make the linker happy when you hand it the ‘right’ library file. There is also a lot to be said for not digging too deeply into either, as normally things will Just Work™ without having to bother with such additional details.
The thing is that both executables and libraries contain a lot of information that normally is just used by the OS, toolchain, debuggers and similar tools. Whether these files are in Windows PE format, old-school Linux
a.out or modern-day
.elf, when things go south during development, sometimes one has to break out the right tools to inspect them in order to make sense of what is happening.
This article will focus primarily on the Linux platform, though most of it also applies to BSD and MacOS, and to some extent Windows.