+#ifdef __linux
+ // Summary: the GNU build ID is stored in a ("GNU, NT_GNU_BUILD_ID) note
+ // found in a PT_NOTE entry in the program header table.
+
+ size_t phnum;
+ if (elf_getphdrnum (elf, &phnum) != 0)
+ xbt_die("Could not read program headers");
+
+ // Iterate over the program headers and find the PT_NOTE ones:
+ for (size_t i = 0; i < phnum; ++i) {
+ GElf_Phdr phdr_temp;
+ GElf_Phdr *phdr = gelf_getphdr(elf, i, &phdr_temp);
+ if (phdr->p_type != PT_NOTE)
+ continue;
+
+ Elf_Data* data = elf_getdata_rawchunk(elf, phdr->p_offset, phdr->p_filesz, ELF_T_NHDR);
+
+ // Iterate over the notes and find the NT_GNU_BUILD_ID one:
+ size_t pos = 0;
+ while (pos < data->d_size) {
+ GElf_Nhdr nhdr;
+ // Location of the name within Elf_Data:
+ size_t name_pos;
+ size_t desc_pos;
+ pos = gelf_getnote(data, pos, &nhdr, &name_pos, &desc_pos);
+ // A build ID note is identified by the pair ("GNU", NT_GNU_BUILD_ID)
+ // (a namespace and a type within this namespace):
+ if (nhdr.n_type == NT_GNU_BUILD_ID
+ && nhdr.n_namesz == sizeof("GNU")
+ && memcmp((char*) data->d_buf + name_pos, "GNU", sizeof("GNU")) == 0) {
+ XBT_DEBUG("Found GNU/NT_GNU_BUILD_ID note");
+ char* start = (char*) data->d_buf + desc_pos;
+ char* end = (char*) start + nhdr.n_descsz;
+ return std::vector<char>(start, end);
+ }
+ }
+
+ }
+#endif
+ return std::vector<char>();