Blob Blame History Raw
diff -rupN --no-dereference binutils-2.39/elfcpp/elfcpp.h binutils-2.39-new/elfcpp/elfcpp.h
--- binutils-2.39/elfcpp/elfcpp.h	2022-07-08 11:46:47.000000000 +0200
+++ binutils-2.39-new/elfcpp/elfcpp.h	2022-10-30 12:41:39.175023806 +0100
@@ -999,7 +999,9 @@ enum
   // string.
   NT_GNU_GOLD_VERSION = 4,
   // Program property note, as described in "Linux Extensions to the gABI".
-  NT_GNU_PROPERTY_TYPE_0 = 5
+  NT_GNU_PROPERTY_TYPE_0 = 5,
+  // FDO .note.package notes as defined on https://systemd.io/ELF_PACKAGE_METADATA/
+  FDO_PACKAGING_METADATA = 0xcafe1a7e
 };
 
 // The OS values which may appear in word 0 of a NT_GNU_ABI_TAG note.
diff -rupN --no-dereference binutils-2.39/gold/configure.ac binutils-2.39-new/gold/configure.ac
--- binutils-2.39/gold/configure.ac	2022-10-30 12:41:34.538023785 +0100
+++ binutils-2.39-new/gold/configure.ac	2022-10-30 12:41:39.173023806 +0100
@@ -591,6 +591,32 @@ if test "$threads" = "yes"; then
 fi
 AM_CONDITIONAL(THREADS, test "$threads" = "yes")
 
+# Used to validate --package-metadata= input. Disabled by default.
+AC_ARG_ENABLE([jansson],
+  [AS_HELP_STRING([--enable-jansson],
+    [enable jansson [default=no]])],
+  [enable_jansson=$enableval],
+  [enable_jansson="no"])
+
+if test "x$enable_jansson" != "xno"; then
+  PKG_PROG_PKG_CONFIG
+  AS_IF([test -n "$PKG_CONFIG"],
+    [
+      PKG_CHECK_MODULES(JANSSON, [jansson],
+	[
+	  AC_DEFINE(HAVE_JANSSON, 1, [The jansson library is to be used])
+	  AC_SUBST([JANSSON_CFLAGS])
+	  AC_SUBST([JANSSON_LIBS])
+	],
+	[
+	  AC_MSG_ERROR([Cannot find jansson library])
+	])
+    ],
+    [
+      AC_MSG_ERROR([Cannot find pkg-config])
+    ])
+fi
+
 dnl We have to check these in C, not C++, because autoconf generates
 dnl tests which have no type information, and current glibc provides
 dnl multiple declarations of functions like basename when compiling
diff -rupN --no-dereference binutils-2.39/gold/layout.cc binutils-2.39-new/gold/layout.cc
--- binutils-2.39/gold/layout.cc	2022-10-30 12:41:33.405023779 +0100
+++ binutils-2.39-new/gold/layout.cc	2022-10-30 12:41:39.174023806 +0100
@@ -38,6 +38,9 @@
 #include <windows.h>
 #include <rpcdce.h>
 #endif
+#ifdef HAVE_JANSSON
+#include <jansson.h>
+#endif
 
 #include "parameters.h"
 #include "options.h"
@@ -2439,6 +2442,7 @@ Layout::create_notes()
   this->create_gold_note();
   this->create_stack_segment();
   this->create_build_id();
+  this->create_package_metadata();
 }
 
 // Create the dynamic sections which are needed before we read the
@@ -3536,6 +3540,52 @@ Layout::create_build_id()
     }
 }
 
+// If --package-metadata was used, set up the package metadata note.
+// https://systemd.io/ELF_PACKAGE_METADATA/
+
+void
+Layout::create_package_metadata()
+{
+  if (!parameters->options().user_set_package_metadata())
+    return;
+
+  const char* desc = parameters->options().package_metadata();
+  if (strcmp(desc, "") == 0)
+    return;
+
+#ifdef HAVE_JANSSON
+  json_error_t json_error;
+  json_t *json = json_loads(desc, 0, &json_error);
+  if (json)
+    json_decref(json);
+  else
+    {
+      gold_fatal(_("error: --package-metadata=%s does not contain valid "
+		   "JSON: %s\n"),
+		 desc, json_error.text);
+    }
+#endif
+
+  // Create the note.
+  size_t trailing_padding;
+  // Ensure the trailing NULL byte is always included, as per specification.
+  size_t descsz = strlen(desc) + 1;
+  Output_section* os = this->create_note("FDO", elfcpp::FDO_PACKAGING_METADATA,
+					 ".note.package", descsz, true,
+					 &trailing_padding);
+  if (os == NULL)
+    return;
+
+  Output_section_data* posd = new Output_data_const(desc, descsz, 4);
+  os->add_output_section_data(posd);
+
+  if (trailing_padding != 0)
+    {
+      posd = new Output_data_zero_fill(trailing_padding, 0);
+      os->add_output_section_data(posd);
+    }
+}
+
 // If we have both .stabXX and .stabXXstr sections, then the sh_link
 // field of the former should point to the latter.  I'm not sure who
 // started this, but the GNU linker does it, and some tools depend
diff -rupN --no-dereference binutils-2.39/gold/layout.h binutils-2.39-new/gold/layout.h
--- binutils-2.39/gold/layout.h	2022-07-08 11:46:48.000000000 +0200
+++ binutils-2.39-new/gold/layout.h	2022-10-30 12:41:39.174023806 +0100
@@ -1107,6 +1107,10 @@ class Layout
   void
   create_build_id();
 
+  // Create a package metadata note if needed.
+  void
+  create_package_metadata();
+
   // Link .stab and .stabstr sections.
   void
   link_stabs_sections();
@@ -1453,6 +1457,8 @@ class Layout
   Gdb_index* gdb_index_data_;
   // The space for the build ID checksum if there is one.
   Output_section_data* build_id_note_;
+  // The space for the package metadata JSON if there is one.
+  Output_section_data* package_metadata_note_;
   // The output section containing dwarf abbreviations
   Output_reduced_debug_abbrev_section* debug_abbrev_;
   // The output section containing the dwarf debug info tree
diff -rupN --no-dereference binutils-2.39/gold/Makefile.am binutils-2.39-new/gold/Makefile.am
--- binutils-2.39/gold/Makefile.am	2022-07-08 11:46:48.000000000 +0200
+++ binutils-2.39-new/gold/Makefile.am	2022-10-30 12:41:39.173023806 +0100
@@ -35,7 +35,7 @@ THREADFLAGS = @PTHREAD_CFLAGS@
 THREADLIBS = @PTHREAD_LIBS@
 
 AM_CFLAGS = $(WARN_CFLAGS) $(LFS_CFLAGS) $(RANDOM_SEED_CFLAGS) $(ZLIBINC) $(THREADFLAGS)
-AM_CXXFLAGS = $(WARN_CXXFLAGS) $(LFS_CFLAGS) $(RANDOM_SEED_CFLAGS) $(ZLIBINC) $(THREADFLAGS)
+AM_CXXFLAGS = $(WARN_CXXFLAGS) $(LFS_CFLAGS) $(RANDOM_SEED_CFLAGS) $(ZLIBINC) $(THREADFLAGS) $(JANSSON_CFLAGS)
 AM_LDFLAGS = $(THREADFLAGS)
 
 AM_CPPFLAGS = \
@@ -187,7 +187,7 @@ libgold_a_LIBADD = $(LIBOBJS)
 sources_var = main.cc
 deps_var = $(TARGETOBJS) libgold.a $(LIBIBERTY) $(LIBINTL_DEP)
 ldadd_var = $(TARGETOBJS) libgold.a $(LIBIBERTY) $(GOLD_LDADD) $(LIBINTL) \
-	 $(THREADLIBS) $(LIBDL) $(ZLIB)
+	 $(THREADLIBS) $(LIBDL) $(ZLIB) $(JANSSON_LIBS)
 ldflags_var = $(GOLD_LDFLAGS)
 
 ld_new_SOURCES = $(sources_var)
@@ -201,12 +201,12 @@ incremental_dump_SOURCES = incremental-d
 incremental_dump_DEPENDENCIES = $(TARGETOBJS) libgold.a $(LIBIBERTY) \
 	$(LIBINTL_DEP)
 incremental_dump_LDADD = $(TARGETOBJS) libgold.a $(LIBIBERTY) $(LIBINTL) \
-	 $(THREADLIBS) $(LIBDL) $(ZLIB)
+	 $(THREADLIBS) $(LIBDL) $(ZLIB) $(JANSSON_LIBS)
 
 dwp_SOURCES = dwp.cc
 dwp_DEPENDENCIES = libgold.a $(LIBIBERTY) $(LIBINTL_DEP)
 dwp_LDADD = libgold.a $(LIBIBERTY) $(GOLD_LDADD) $(LIBINTL) $(THREADLIBS) \
-	$(LIBDL) $(ZLIB)
+	$(LIBDL) $(ZLIB) $(JANSSON_LIBS)
 dwp_LDFLAGS = $(GOLD_LDFLAGS)
 
 CONFIG_STATUS_DEPENDENCIES = $(srcdir)/../bfd/development.sh
diff -rupN --no-dereference binutils-2.39/gold/options.h binutils-2.39-new/gold/options.h
--- binutils-2.39/gold/options.h	2022-07-08 11:46:48.000000000 +0200
+++ binutils-2.39-new/gold/options.h	2022-10-30 12:41:39.175023806 +0100
@@ -1102,6 +1102,10 @@ class General_options
   DEFINE_bool(p, options::ONE_DASH, 'p', false,
 	      N_("Ignored for ARM compatibility"), NULL);
 
+  DEFINE_optional_string(package_metadata, options::TWO_DASHES, '\0', NULL,
+			 N_("Generate package metadata note"),
+			 N_("[=JSON]"));
+
   DEFINE_bool(pie, options::ONE_DASH, '\0', false,
 	      N_("Create a position independent executable"),
 	      N_("Do not create a position independent executable"));