How can I print the build version of the program (located in the .note.gnu.build-id elf section) from the program itself?
You need to read the
ElfW(Ehdr)
(at the beginning of the file) to find program headers in your binary (.e_phoff
and.e_phnum
will tell you where program headers are, and how many of them to read).You then read program headers, until you find
PT_NOTE
segment of your program. That segment will tell you offset to the beginning of all the notes in your binary.You then need to read the
ElfW(Nhdr)
and skip the rest of the note (total size of the note issizeof(Nhdr) + .n_namesz + .n_descsz
, properly aligned), until you find a note with.n_type == NT_GNU_BUILD_ID
.Once you find
NT_GNU_BUILD_ID
note, skip past its.n_namesz
, and read the.n_descsz
bytes to read the actual build-id.
You can verify that you are reading the right data by comparing what you read with the output of readelf -n a.out
.
P.S.
If you are going to go through the trouble to decode build-id as above, and if your executable is not stripped, it may be better for you to just decode and print symbol names instead (i.e. to replicate what backtrace_symbols
does) -- it's actually easier to do than decoding ELF notes, because the symbol table contains fixed-sized entries.