[lld] dbd04b8 - [ELF] Support --package-metadata

Alex Brachet via llvm-commits llvm-commits at lists.llvm.org
Mon Aug 8 14:33:00 PDT 2022


Author: Alex Brachet
Date: 2022-08-08T21:31:58Z
New Revision: dbd04b853b680b0a383e5f58edf3643364f67bdf

URL: https://github.com/llvm/llvm-project/commit/dbd04b853b680b0a383e5f58edf3643364f67bdf
DIFF: https://github.com/llvm/llvm-project/commit/dbd04b853b680b0a383e5f58edf3643364f67bdf.diff

LOG: [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

Added: 
    lld/test/ELF/package-metadata.s

Modified: 
    lld/ELF/Config.h
    lld/ELF/Driver.cpp
    lld/ELF/Options.td
    lld/ELF/SyntheticSections.cpp
    lld/ELF/SyntheticSections.h
    lld/ELF/Writer.cpp
    lld/docs/ReleaseNotes.rst
    llvm/include/llvm/BinaryFormat/ELF.h

Removed: 
    


################################################################################
diff  --git a/lld/ELF/Config.h b/lld/ELF/Config.h
index c29e41d65713..fd9d3b63b2a3 100644
--- a/lld/ELF/Config.h
+++ b/lld/ELF/Config.h
@@ -291,6 +291,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 821cf22df35d..2828caa9fdb0 100644
--- a/lld/ELF/Driver.cpp
+++ b/lld/ELF/Driver.cpp
@@ -1146,6 +1146,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 80c0ff9fe1b8..d9266e595887 100644
--- a/lld/ELF/Options.td
+++ b/lld/ELF/Options.td
@@ -503,6 +503,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 ace70480230a..9ec991267fc0 100644
--- a/lld/ELF/SyntheticSections.cpp
+++ b/lld/ELF/SyntheticSections.cpp
@@ -3876,6 +3876,20 @@ size_t MemtagAndroidNote::getSize() const {
          /*descsz=*/sizeof(uint32_t);
 }
 
+void PackageMetadataNote::writeTo(uint8_t *buf) {
+  write32(buf, 4);
+  write32(buf + 4, config->packageMetadata.size() + 1);
+  write32(buf + 8, FDO_PACKAGING_METADATA);
+  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 5cbe7702fd81..215d1ae644cb 100644
--- a/lld/ELF/SyntheticSections.h
+++ b/lld/ELF/SyntheticSections.h
@@ -1176,6 +1176,15 @@ class MemtagAndroidNote : public SyntheticSection {
   size_t getSize() const 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();
@@ -1208,6 +1217,7 @@ struct Partition {
   std::unique_ptr<GnuHashTableSection> gnuHashTab;
   std::unique_ptr<HashTableSection> hashTab;
   std::unique_ptr<MemtagAndroidNote> memtagAndroidNote;
+  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 858a219ab143..9675eb43e88e 100644
--- a/lld/ELF/Writer.cpp
+++ b/lld/ELF/Writer.cpp
@@ -405,6 +405,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 aedfdfaf2c81..033f76c70d8f 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>`_)
 
 Breaking changes
 ----------------

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

diff  --git a/llvm/include/llvm/BinaryFormat/ELF.h b/llvm/include/llvm/BinaryFormat/ELF.h
index 635ec25c90a6..f193db018e3d 100644
--- a/llvm/include/llvm/BinaryFormat/ELF.h
+++ b/llvm/include/llvm/BinaryFormat/ELF.h
@@ -1598,6 +1598,7 @@ enum {
   NT_GNU_BUILD_ID = 3,
   NT_GNU_GOLD_VERSION = 4,
   NT_GNU_PROPERTY_TYPE_0 = 5,
+  FDO_PACKAGING_METADATA = 0xcafe1a7e,
 };
 
 // Android note types.


        


More information about the llvm-commits mailing list