diff -rup binutils.orig/gold/Makefile.am binutils-2.38/gold/Makefile.am --- binutils.orig/gold/Makefile.am 2022-08-04 11:11:01.788495165 +0100 +++ binutils-2.38/gold/Makefile.am 2022-08-04 11:12:26.124013955 +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 -rup binutils.orig/gold/configure.ac binutils-2.38/gold/configure.ac --- binutils.orig/gold/configure.ac 2022-08-04 11:11:01.783495194 +0100 +++ binutils-2.38/gold/configure.ac 2022-08-04 11:12:26.124013955 +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 -rup binutils.orig/gold/layout.cc binutils-2.38/gold/layout.cc --- binutils.orig/gold/layout.cc 2022-08-04 11:11:01.783495194 +0100 +++ binutils-2.38/gold/layout.cc 2022-08-04 11:12:26.125013949 +0100 @@ -38,6 +38,9 @@ #include #include #endif +#ifdef HAVE_JANSSON +#include +#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 -rup binutils.orig/gold/layout.h binutils-2.38/gold/layout.h --- binutils.orig/gold/layout.h 2022-08-04 11:11:01.788495165 +0100 +++ binutils-2.38/gold/layout.h 2022-08-04 11:12:26.125013949 +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 -rup binutils.orig/gold/options.h binutils-2.38/gold/options.h --- binutils.orig/gold/options.h 2022-08-04 11:11:01.785495182 +0100 +++ binutils-2.38/gold/options.h 2022-08-04 11:12:26.125013949 +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")); diff -rup binutils.orig/elfcpp/elfcpp.h binutils-2.38/elfcpp/elfcpp.h --- binutils.orig/elfcpp/elfcpp.h 2022-08-04 11:11:00.940500003 +0100 +++ binutils-2.38/elfcpp/elfcpp.h 2022-08-04 11:12:26.124013955 +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.