Skip to content

Commit 4e41b06

Browse files
committed
readelf: dump elf note data
Output format is compatible with GNU readelf's handling of unknown note types (modulo a GNU char signedness bug); future changes will add type- specific decoding. Add specific decoding for NT_FREEBSD_ABI_TAG, NT_FREEBSD_ARCH_TAG, and NT_FREEBSD_FEATURE_CTL. Obtained from: FreeBSD r343614, r343669
1 parent 72f7058 commit 4e41b06

File tree

1 file changed

+54
-3
lines changed

1 file changed

+54
-3
lines changed

readelf/readelf.c

+54-3
Original file line numberDiff line numberDiff line change
@@ -304,6 +304,8 @@ static void dump_mips_specific_info(struct readelf *re);
304304
static void dump_notes(struct readelf *re);
305305
static void dump_notes_content(struct readelf *re, const char *buf, size_t sz,
306306
off_t off);
307+
static void dump_notes_data(const char *name, uint32_t type, const char *buf,
308+
size_t sz);
307309
static void dump_svr4_hash(struct section *s);
308310
static void dump_svr4_hash64(struct readelf *re, struct section *s);
309311
static void dump_gnu_hash(struct readelf *re, struct section *s);
@@ -3479,6 +3481,53 @@ dump_notes(struct readelf *re)
34793481
}
34803482
}
34813483

3484+
static struct flag_desc note_feature_ctl_flags[] = {
3485+
{ NT_FREEBSD_FCTL_ASLR_DISABLE, "ASLR_DISABLE" },
3486+
{ 0, NULL }
3487+
};
3488+
3489+
static void
3490+
dump_notes_data(const char *name, uint32_t type, const char *buf, size_t sz)
3491+
{
3492+
size_t i;
3493+
const uint32_t *ubuf;
3494+
3495+
/* Note data is at least 4-byte aligned. */
3496+
if (((uintptr_t)buf & 3) != 0) {
3497+
warnx("bad note data alignment");
3498+
goto unknown;
3499+
}
3500+
ubuf = (const uint32_t *)(const void *)buf;
3501+
3502+
if (strcmp(name, "FreeBSD") == 0) {
3503+
switch (type) {
3504+
case NT_FREEBSD_ABI_TAG:
3505+
if (sz != 4)
3506+
goto unknown;
3507+
printf(" ABI tag: %u\n", ubuf[0]);
3508+
return;
3509+
/* NT_FREEBSD_NOINIT_TAG carries no data, treat as unknown. */
3510+
case NT_FREEBSD_ARCH_TAG:
3511+
if (sz != 4)
3512+
goto unknown;
3513+
printf(" Arch tag: %x\n", ubuf[0]);
3514+
return;
3515+
case NT_FREEBSD_FEATURE_CTL:
3516+
if (sz != 4)
3517+
goto unknown;
3518+
printf(" Features:");
3519+
dump_flags(note_feature_ctl_flags, ubuf[0]);
3520+
printf("\n");
3521+
return;
3522+
}
3523+
}
3524+
unknown:
3525+
printf(" description data:");
3526+
for (i = 0; i < sz; i++)
3527+
printf(" %02x", (unsigned char)buf[i]);
3528+
printf("\n");
3529+
}
3530+
34823531
static void
34833532
dump_notes_content(struct readelf *re, const char *buf, size_t sz, off_t off)
34843533
{
@@ -3495,7 +3544,9 @@ dump_notes_content(struct readelf *re, const char *buf, size_t sz, off_t off)
34953544
return;
34963545
}
34973546
note = (Elf_Note *)(uintptr_t) buf;
3498-
name = (char *)(uintptr_t)(note + 1);
3547+
buf += sizeof(Elf_Note);
3548+
name = buf;
3549+
buf += roundup2(note->n_namesz, 4);
34993550
/*
35003551
* The name field is required to be nul-terminated, and
35013552
* n_namesz includes the terminating nul in observed
@@ -3513,8 +3564,8 @@ dump_notes_content(struct readelf *re, const char *buf, size_t sz, off_t off)
35133564
printf(" %-13s %#010jx", name, (uintmax_t) note->n_descsz);
35143565
printf(" %s\n", note_type(name, re->ehdr.e_type,
35153566
note->n_type));
3516-
buf += sizeof(Elf_Note) + roundup2(note->n_namesz, 4) +
3517-
roundup2(note->n_descsz, 4);
3567+
dump_notes_data(name, note->n_type, buf, note->n_descsz);
3568+
buf += roundup2(note->n_descsz, 4);
35183569
}
35193570
}
35203571

0 commit comments

Comments
 (0)