git: c18512056301 - main - readelf: Add support for ELF package metadata note

From: Ed Maste <emaste_at_FreeBSD.org>
Date: Fri, 10 Jul 2026 14:58:34 UTC
The branch main has been updated by emaste:

URL: https://cgit.FreeBSD.org/src/commit/?id=c18512056301fa97dd31c4cc9a78e18f1aa8b2d5

commit c18512056301fa97dd31c4cc9a78e18f1aa8b2d5
Author:     Ed Maste <emaste@FreeBSD.org>
AuthorDate: 2022-04-20 14:12:06 +0000
Commit:     Ed Maste <emaste@FreeBSD.org>
CommitDate: 2026-07-10 14:58:15 +0000

    readelf: Add support for ELF package metadata note
    
    We don't use this note type today, but as a general purpose ELF
    diagnostic tool readelf(1) ought to decode it.
    
    References:
    https://fedoraproject.org/wiki/Changes/Package_information_on_ELF_objects
    https://systemd.io/ELF_PACKAGE_METADATA/
    
    Reviewed by:    fuz
    Sponsored by:   The FreeBSD Foundation
    Differential Revision: https://reviews.freebsd.org/D47524
---
 contrib/elftoolchain/readelf/readelf.c | 38 +++++++++++++++++++++++++++++++++-
 1 file changed, 37 insertions(+), 1 deletion(-)

diff --git a/contrib/elftoolchain/readelf/readelf.c b/contrib/elftoolchain/readelf/readelf.c
index 43585459d82e..d49505756fef 100644
--- a/contrib/elftoolchain/readelf/readelf.c
+++ b/contrib/elftoolchain/readelf/readelf.c
@@ -47,6 +47,7 @@
 #include <string.h>
 #include <time.h>
 #include <unistd.h>
+#include <vis.h>
 #include <zlib.h>
 
 #include <libcasper.h>
@@ -371,6 +372,7 @@ static int loc_at_comparator(const void *la1, const void *la2);
 static const char *mips_abi_fp(uint64_t fp);
 static const char *note_type(const char *note_name, unsigned int et,
     unsigned int nt);
+static const char *note_type_fdo(unsigned int nt);
 static const char *note_type_freebsd(unsigned int nt);
 static const char *note_type_freebsd_core(unsigned int nt);
 static const char *note_type_go(unsigned int nt);
@@ -1150,6 +1152,8 @@ note_type(const char *name, unsigned int et, unsigned int nt)
 			return note_type_freebsd_core(nt);
 		else
 			return note_type_freebsd(nt);
+	else if (strcmp(name, "FDO") == 0 && et != ET_CORE)
+		return note_type_fdo(nt);
 	else if (strcmp(name, "GNU") == 0 && et != ET_CORE)
 		return note_type_gnu(nt);
 	else if (strcmp(name, "Go") == 0 && et != ET_CORE)
@@ -1163,6 +1167,15 @@ note_type(const char *name, unsigned int et, unsigned int nt)
 	return note_type_unknown(nt);
 }
 
+static const char *
+note_type_fdo(unsigned int nt)
+{
+	switch (nt) {
+	case NT_FDO_PACKAGING_METADATA: return "NT_FDO_PACKAGING_METADATA";
+	default: return (note_type_unknown(nt));
+	}
+}
+
 static const char *
 note_type_freebsd(unsigned int nt)
 {
@@ -3819,7 +3832,30 @@ dump_notes_data(struct readelf *re, const char *name, uint32_t type,
 	}
 	ubuf = (const uint32_t *)(const void *)buf;
 
-	if (strcmp(name, "FreeBSD") == 0) {
+	if (strcmp(name, "FDO") == 0) {
+		switch (type) {
+		case NT_FDO_PACKAGING_METADATA:
+		{
+			char *visbuf;
+
+			if (sz > SIZE_MAX / 4 - 1) {
+				warnx("invalid note data");
+				return;
+			}
+			/* Ignore trailing NULs. */
+			while (sz > 0 && buf[sz - 1] == '\0') {
+				sz--;
+			}
+			if ((visbuf = malloc(sz * 4 + 1)) == NULL) {
+				err(1, "malloc");
+			}
+			(void)strvisx(visbuf, buf, sz, VIS_CSTYLE);
+			printf("   Package metadata: %s\n", visbuf);
+			free(visbuf);
+			return;
+		}
+		}
+	} else if (strcmp(name, "FreeBSD") == 0) {
 		switch (type) {
 		case NT_FREEBSD_ABI_TAG:
 			if (sz != 4)