If I run the attached test program on the file
/usr/lib/debug/usr/bin/bsdiff.debug from the Fedora package
bsdiff-debuginfo-4.3-12.fc20.x86_64, I get the following output:
Compilation unit at offset 0, tag 17:
name (format 0xe): "bsdiff.c"
comp_dir (format 0x1f21) present with error 36: no alternative debug
link found
producer (format 0x1f21) present with error 36: no alternative debug
link found
How can I obtain these attributes?
--
Florian Weimer / Red Hat Product Security Team
#define _GNU_SOURCE
#include <err.h>
#include <fcntl.h>
#include <stdbool.h>
#include <stdio.h>
#include <dwarf.h>
#include <elfutils/libdw.h>
static void doit(Dwarf_Off cu_offset, Dwarf_Die *die);
int
main(int argc, char **argv)
{
if (argc != 2) {
fprintf(stderr, "usage: %s FILE\n", argv[0]);
return 2;
}
int fd = open64(argv[1], O_RDONLY | O_CLOEXEC);
if (fd < 0) {
err(1, "open64(%s)", argv[1]);
}
Dwarf *dwarf = dwarf_begin(fd, DWARF_C_READ);
if (dwarf == NULL) {
errx(1, "dwarf_begin: %s", dwarf_errmsg(dwarf_errno()));
}
Dwarf_Off off;
Dwarf_Off next_off = 0;
size_t header_size;
Dwarf_Off abbrev_offset;
uint8_t address_size;
uint8_t offset_size;
while (true) {
off = next_off;
next_off = 0;
if (dwarf_nextcu(dwarf, off, &next_off, &header_size, &abbrev_offset,
&address_size, &offset_size) == 0) {
Dwarf_Off die_offset = off + header_size;
Dwarf_Die die;
if (dwarf_offdie(dwarf, die_offset, &die) == NULL) {
errx(1, "dwarf_offdie(%lu): %s", off, dwarf_errmsg(dwarf_errno()));
}
doit(off, &die);
} else {
if (next_off != (Dwarf_Off) -1) {
errx(1, "dwarf_nextcu(%lu): %s", off, dwarf_errmsg(dwarf_errno()));
}
break;
}
}
return 0;
}
static void
report_string_attribute
(Dwarf_Die *die, unsigned int name, const char *name_str)
{
Dwarf_Attribute attr;
if (dwarf_attr(die, name, &attr) == NULL) {
printf(" %s not present\n", name_str);
return;
}
const char *ptr = dwarf_formstring(&attr);
if (ptr == NULL) {
int code = dwarf_errno();
printf(" %s (format 0x%x) present with error %d: %s\n",
name_str, dwarf_whatform(&attr), code, dwarf_errmsg(code));
return;
}
printf(" %s (format 0x%x): \"", name_str, dwarf_whatform(&attr));
for (; *ptr; ++ptr) {
unsigned char ch = *ptr;
if (ch == '\'' || ch == '"') {
putchar('\\');
putchar(ch);
} else if (' ' <= ch && ch <= '~') {
putchar(ch);
} else {
printf("\\%03o", ch);
}
}
puts("\"");
}
static void doit(Dwarf_Off cu_offset, Dwarf_Die *die)
{
printf("Compilation unit at offset %lu, tag %d:\n",
cu_offset, dwarf_tag(die));
report_string_attribute(die, DW_AT_name, "name");
report_string_attribute(die, DW_AT_comp_dir, "comp_dir");
report_string_attribute(die, DW_AT_producer, "producer");
}