[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
This commit is contained in:
Alex Brachet 2022-08-08 21:31:58 +00:00
parent cc8edbea7a
commit dbd04b853b
9 changed files with 55 additions and 0 deletions

View File

@ -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.

View File

@ -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);

View File

@ -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">;

View File

@ -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;

View File

@ -1176,6 +1176,15 @@ public:
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;

View File

@ -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) {

View File

@ -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
----------------

View File

@ -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

View File

@ -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.