This little guide describes the generation of debug ids across various platforms and how they are being used to find debug information.
Linux object files carry a debug id (occasionally also called Build ID), to identify a particular shared object and uniquely associate its corresponding debug information in case they are stripped and stored in a separate file. The debug id is stored in the notes section of ELF objects and can be queries with various tools, e.g. readelf -n <binary>.
On Linux, the build id is generated by the linker. The GNU ld linker can be instructed to generate different forms of build ids depending on the switch --build-id. It supports generating SHA-1, MD5 or UUID identifiers as well as specifying a custom generated debug id. The default is using the SHA-1 checksum as build id. The computation of the checksums is depending on the platform (CPU architecture etc.) but the code tries to ensure that given same inputs, the same debug id is being generated. This happens by only hashing the ELF headers as well as stable ELF content sections.
Note for Red Hat/Fedora/Centos users:
During creation of RPM packages, rpmbuild's macros will call down to debugedit and cause a regeneration of build ids. This is being done because file paths are affecting the debug id generation and rpmbuild builds in a temporary build root with different paths for each invocation. debugedit ensures that the generated build-ids are stable per invocation. This also helps with reproducible package builds. Debian/Ubuntu might have parallel tools sanitizing build-ids. The above mentioned distribution allow separate installation of debug information packages, which are being commonly indexed under the file hierarchy /usr/lib/debug by hash value.