Skip to content

Instantly share code, notes, and snippets.

@bluca
Created March 26, 2021 16:08
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bluca/fd55ca204c25e4840b68443595a09479 to your computer and use it in GitHub Desktop.
Save bluca/fd55ca204c25e4840b68443595a09479 to your computer and use it in GitHub Desktop.
Get custom note out of core file
#include <dwarf.h>
#include <elfutils/libdwelf.h>
#include <elfutils/libdwfl.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <assert.h>
#include <errno.h>
#include <stdio.h>
#include <inttypes.h>
#include <string.h>
static int module_callback (Dwfl_Module *mod, void **userdata, const char *name, Dwarf_Addr start, void *arg)
{
const unsigned char *id;
GElf_Addr id_vaddr;
int id_len;
assert(mod);
GElf_Addr bias;
Elf *elf = dwfl_module_getelf(mod, &bias);
if (!elf) {
printf("elf_begin() failed: %s\n", elf_errmsg(-1));
return DWARF_CB_ABORT;
}
size_t n_program_headers;
int r = elf_getphdrnum(elf, &n_program_headers);
if (r < 0) {
printf("Could not parse number of program headers in core file: %s\n", elf_errmsg(-1));
elf_end(elf);
return DWARF_CB_ABORT;
}
for (size_t i = 0; i < n_program_headers; ++i) {
GElf_Phdr mem;
GElf_Phdr *header = gelf_getphdr (elf, i, &mem);
if (header == NULL || header->p_type != PT_NOTE)
continue;
Elf_Data *data = elf_getdata_rawchunk(elf,
header->p_offset,
header->p_filesz,
header->p_align == 8 ? ELF_T_NHDR8 : ELF_T_NHDR);
GElf_Nhdr note_header;
size_t offset = 0;
size_t name_offset, desc_offset;
while (offset < data->d_size && (offset = gelf_getnote(data, offset, &note_header, &name_offset, &desc_offset)) > 0) {
const char *nname = note_header.n_namesz == 0 ? "" : (const char *)data->d_buf + name_offset;
const char *desc = (const char *)data->d_buf + desc_offset;
if (note_header.n_namesz == 0)
continue;
if (memcmp(nname, "TBD", 3) == 0)
printf("Fount TBD note with payload: %s\n", desc);
}
}
return DWARF_CB_OK;
}
int main(int argc, char **argv) {
static const Dwfl_Callbacks callbacks = {
.find_elf = dwfl_build_id_find_elf,
.section_address = dwfl_offline_section_address,
.find_debuginfo = dwfl_standard_find_debuginfo,
};
Dwfl *dwfl = NULL;
Elf *elf = NULL;
int r;
int fd;
assert(argc > 1);
fd = open(argv[1], O_CLOEXEC|O_RDONLY);
if (fd < 0)
return -1;
elf_version(EV_CURRENT);
elf = elf_begin(fd, ELF_C_READ_MMAP, NULL);
if (!elf) {
r = -EINVAL;
goto finish;
}
dwfl = dwfl_begin(&callbacks);
if (!dwfl) {
r = -EINVAL;
goto finish;
}
if (dwfl_core_file_report(dwfl, elf, NULL) < 0) {
r = -EINVAL;
goto finish;
}
if (dwfl_report_end(dwfl, NULL, NULL) != 0) {
r = -EINVAL;
goto finish;
}
if (dwfl_getmodules(dwfl, &module_callback, NULL, 0) < 0) {
r = -EINVAL;
goto finish;
}
r = 0;
finish:
if (dwfl)
dwfl_end(dwfl);
if (elf)
elf_end(elf);
close(fd);
return r;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment