tstellar / rpms / lld

Forked from rpms/lld 5 years ago
Clone
Blob Blame History Raw
From 2a5f3345e72b2c1a66d3714eaae37e7b05ef5c65 Mon Sep 17 00:00:00 2001
From: Alex Brachet <abrachet@google.com>
Date: Mon, 8 Aug 2022 21:31:58 +0000
Subject: [PATCH] [ELF] Support --package-metadata

This was recently introduced in GNU linkers and it makes sense for
ld.lld to have the same support. This implementation omits checking if
the input string is valid json to reduce size bloat.

Differential Revision: https://reviews.llvm.org/D131439
---
 lld/ELF/Config.h                |  1 +
 lld/ELF/Driver.cpp              |  1 +
 lld/ELF/Options.td              |  2 ++
 lld/ELF/SyntheticSections.cpp   | 14 ++++++++++++++
 lld/ELF/SyntheticSections.h     | 11 +++++++++++
 lld/ELF/Writer.cpp              |  5 +++++
 lld/docs/ReleaseNotes.rst       |  2 ++
 lld/test/ELF/package-metadata.s | 19 +++++++++++++++++++
 8 files changed, 55 insertions(+)
 create mode 100644 lld/test/ELF/package-metadata.s

diff --git a/lld/ELF/Config.h b/lld/ELF/Config.h
index 72b7be8165e0..38545d257a2b 100644
--- a/lld/ELF/Config.h
+++ b/lld/ELF/Config.h
@@ -281,6 +281,7 @@ struct Configuration {
   StringRef thinLTOJobs;
   unsigned timeTraceGranularity;
   int32_t splitStackAdjustSize;
+  StringRef packageMetadata;
 
   // The following config options do not directly correspond to any
   // particular command line options.
diff --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp
index 54b487bdc243..39adc5d707d7 100644
--- a/lld/ELF/Driver.cpp
+++ b/lld/ELF/Driver.cpp
@@ -1092,6 +1092,7 @@ static void readConfigs(opt::InputArgList &args) {
   config->optimize = args::getInteger(args, OPT_O, 1);
   config->orphanHandling = getOrphanHandling(args);
   config->outputFile = args.getLastArgValue(OPT_o);
+  config->packageMetadata = args.getLastArgValue(OPT_package_metadata);
   config->pie = args.hasFlag(OPT_pie, OPT_no_pie, false);
   config->printIcfSections =
       args.hasFlag(OPT_print_icf_sections, OPT_no_print_icf_sections, false);
diff --git a/lld/ELF/Options.td b/lld/ELF/Options.td
index cf2013a5f820..52f5485af1f4 100644
--- a/lld/ELF/Options.td
+++ b/lld/ELF/Options.td
@@ -505,6 +505,8 @@ def z: JoinedOrSeparate<["-"], "z">, MetaVarName<"<option>">,
 def visual_studio_diagnostics_format : FF<"vs-diagnostics">,
 HelpText<"Format diagnostics for Visual Studio compatibility">;
 
+def package_metadata: JJ<"package-metadata=">, HelpText<"Emit package metadata note">;
+
 // Aliases
 def: Separate<["-"], "f">, Alias<auxiliary>, HelpText<"Alias for --auxiliary">;
 def: F<"call_shared">, Alias<Bdynamic>, HelpText<"Alias for --Bdynamic">;
diff --git a/lld/ELF/SyntheticSections.cpp b/lld/ELF/SyntheticSections.cpp
index 7778ae5f78e6..5e5495540215 100644
--- a/lld/ELF/SyntheticSections.cpp
+++ b/lld/ELF/SyntheticSections.cpp
@@ -3844,6 +3844,20 @@ void InStruct::reset() {
   symTabShndx.reset();
 }
 
+void PackageMetadataNote::writeTo(uint8_t *buf) {
+  write32(buf, 4);
+  write32(buf + 4, config->packageMetadata.size() + 1);
+  write32(buf + 8, 0xcafe1a7e);
+  memcpy(buf + 12, "FDO", 4);
+  memcpy(buf + 16, config->packageMetadata.data(),
+         config->packageMetadata.size());
+}
+
+size_t PackageMetadataNote::getSize() const {
+  return sizeof(llvm::ELF::Elf64_Nhdr) + 4 +
+         alignTo(config->packageMetadata.size() + 1, 4);
+}
+
 InStruct elf::in;
 
 std::vector<Partition> elf::partitions;
diff --git a/lld/ELF/SyntheticSections.h b/lld/ELF/SyntheticSections.h
index 3161785988f6..7b31b5e97731 100644
--- a/lld/ELF/SyntheticSections.h
+++ b/lld/ELF/SyntheticSections.h
@@ -1185,6 +1185,16 @@ public:
   void writeTo(uint8_t *buf) override;
 };
 
+
+class PackageMetadataNote : public SyntheticSection {
+public:
+  PackageMetadataNote()
+      : SyntheticSection(llvm::ELF::SHF_ALLOC, llvm::ELF::SHT_NOTE,
+                         /*alignment=*/4, ".note.package") {}
+  void writeTo(uint8_t *buf) override;
+  size_t getSize() const override;
+};
+
 InputSection *createInterpSection();
 MergeInputSection *createCommentSection();
 template <class ELFT> void splitSections();
@@ -1215,6 +1225,7 @@ struct Partition {
   std::unique_ptr<EhFrameSection> ehFrame;
   std::unique_ptr<GnuHashTableSection> gnuHashTab;
   std::unique_ptr<HashTableSection> hashTab;
+  std::unique_ptr<PackageMetadataNote> packageMetadataNote;
   std::unique_ptr<RelocationBaseSection> relaDyn;
   std::unique_ptr<RelrBaseSection> relrDyn;
   std::unique_ptr<VersionDefinitionSection> verDef;
diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp
index 5794f048c990..fa6353db8c6d 100644
--- a/lld/ELF/Writer.cpp
+++ b/lld/ELF/Writer.cpp
@@ -417,6 +417,11 @@ template <class ELFT> void elf::createSyntheticSections() {
       part.armExidx = std::make_unique<ARMExidxSyntheticSection>();
       add(*part.armExidx);
     }
+
+    if (!config->packageMetadata.empty()) {
+      part.packageMetadataNote = std::make_unique<PackageMetadataNote>();
+      add(*part.packageMetadataNote);
+    }
   }
 
   if (partitions.size() != 1) {
diff --git a/lld/docs/ReleaseNotes.rst b/lld/docs/ReleaseNotes.rst
index 672759fdf6b3..b94b73c4aea7 100644
--- a/lld/docs/ReleaseNotes.rst
+++ b/lld/docs/ReleaseNotes.rst
@@ -25,6 +25,8 @@ Non-comprehensive list of changes in this release
 
 ELF Improvements
 ----------------
+* ``--package-metadata=`` has been added to create package metadata notes
+  (`D131439 <https://reviews.llvm.org/D131439>`_)
 
 * ``--export-dynamic-symbol-list`` has been added.
   (`D107317 <https://reviews.llvm.org/D107317>`_)
diff --git a/lld/test/ELF/package-metadata.s b/lld/test/ELF/package-metadata.s
new file mode 100644
index 000000000000..29df499d7e98
--- /dev/null
+++ b/lld/test/ELF/package-metadata.s
@@ -0,0 +1,19 @@
+# REQUIRES: x86
+
+# RUN: llvm-mc -filetype=obj -triple=x86_64 %s -o %t.o
+
+# RUN: ld.lld %t.o -o %t --package-metadata='{}'
+# RUN: llvm-readelf -n %t | FileCheck %s --check-prefixes=NOTE,FIRST
+
+# RUN: ld.lld %t.o -o %t --package-metadata='{"abc":123}'
+# RUN: llvm-readelf -n %t | FileCheck %s --check-prefixes=NOTE,SECOND
+
+# NOTE: .note.package
+# NOTE-NEXT: Owner
+# NOTE-NEXT: FDO 0x{{.*}} Unknown note type: (0xcafe1a7e)
+# FIRST-NEXT: description data: 7b 7d 00
+# SECOND-NEXT: description data: 7b 22 61 62 63 22 3a 31 32 33 7d 00
+
+.globl _start
+_start:
+  ret
-- 
2.37.1