From d9ec4f98122b95a1d80b1d73aa1ab727450c1a2f Mon Sep 17 00:00:00 2001 From: Sivan Shani Date: Tue, 3 Jun 2025 17:06:31 +0100 Subject: [PATCH 1/4] [lld][AArch64][Build Attributes] Add support for AArch64 Build Attributes This patch enables lld to read AArch64 Build Attributes and convert them into GNU Properties. Changes: - Parses AArch64 Build Attributes from input object files. - Converts known attributes into corresponding GNU Properties. - Merges attributes when linking multiple objects. Spec reference: https://github.com/ARM-software/abi-aa/pull/230/files#r1030 --- lld/ELF/InputFiles.cpp | 113 +++++++++++-- lld/ELF/InputFiles.h | 5 + .../ELF/Inputs/aarch64-func3-pac-replace.s | 10 ++ lld/test/ELF/Inputs/aarch64-pac1-replace.s | 13 ++ lld/test/ELF/aarch64-build-attributes-be.s | 50 ++++++ lld/test/ELF/aarch64-build-attributes-err.s | 35 +++++ .../ELF/aarch64-build-attributes-invalid.s | 18 +++ .../ELF/aarch64-build-attributes-malformed.s | 16 ++ lld/test/ELF/aarch64-build-attributes-mixed.s | 62 ++++++++ lld/test/ELF/aarch64-build-attributes.s | 57 +++++-- lld/test/ELF/aarch64-feature-pac-replace.s | 148 ++++++++++++++++++ .../llvm/Support/AArch64AttributeParser.h | 11 ++ llvm/lib/Support/AArch64AttributeParser.cpp | 27 ++++ 13 files changed, 538 insertions(+), 27 deletions(-) create mode 100644 lld/test/ELF/Inputs/aarch64-func3-pac-replace.s create mode 100644 lld/test/ELF/Inputs/aarch64-pac1-replace.s create mode 100644 lld/test/ELF/aarch64-build-attributes-be.s create mode 100644 lld/test/ELF/aarch64-build-attributes-err.s create mode 100644 lld/test/ELF/aarch64-build-attributes-invalid.s create mode 100644 lld/test/ELF/aarch64-build-attributes-malformed.s create mode 100644 lld/test/ELF/aarch64-build-attributes-mixed.s create mode 100644 lld/test/ELF/aarch64-feature-pac-replace.s diff --git a/lld/ELF/InputFiles.cpp b/lld/ELF/InputFiles.cpp index 71e72e7184b9f..55a04c43056c4 100644 --- a/lld/ELF/InputFiles.cpp +++ b/lld/ELF/InputFiles.cpp @@ -21,6 +21,7 @@ #include "llvm/ADT/STLExtras.h" #include "llvm/LTO/LTO.h" #include "llvm/Object/IRObjectFile.h" +#include "llvm/Support/AArch64AttributeParser.h" #include "llvm/Support/ARMAttributeParser.h" #include "llvm/Support/ARMBuildAttributes.h" #include "llvm/Support/Endian.h" @@ -537,6 +538,52 @@ uint32_t ObjFile::getSectionIndex(const Elf_Sym &sym) const { this); } +template +static void +handleAArch64BAAndGnuProperties(ObjFile *file, Ctx &ctx, bool hasGP, + const AArch64BuildAttrSubsections &baInfo, + const GnuPropertiesInfo &gpInfo) { + if (hasGP) { + // Check for data mismatch + if (gpInfo.pauthAbiCoreInfo) { + if (baInfo.Pauth.TagPlatform != gpInfo.pauthAbiCoreInfo->platform || + baInfo.Pauth.TagSchema != gpInfo.pauthAbiCoreInfo->version) + Err(ctx) + << file + << " Pauth Data mismatch: file contains both GNU properties and " + "AArch64 build attributes sections with different Pauth data"; + } + if (baInfo.AndFeatures != gpInfo.andFeatures) + Err(ctx) << file + << " Features Data mismatch: file contains both GNU " + "properties and AArch64 build attributes sections with " + "different And Features data"; + } else { + // Write missing data + // We can only know when Pauth is missing. + // Unlike AArch64 Build Attributes, GNU properties does not give a way to + // distinguish between no-value given to value of '0' given. + if (baInfo.Pauth.TagPlatform || baInfo.Pauth.TagSchema) { + // According to the BuildAttributes specification Build Attributes + // default to a value of 0 when not present. A (TagPlatform, TagSchema) of + // (0, 0) maps to 'no PAuth property present'. A (TagPlatform, TagSchema) + // of (0, 1) maps to an explicit PAuth property of platform = 0, version = + // 0 ('Invalid'). + if (baInfo.Pauth.TagPlatform == 0 && baInfo.Pauth.TagSchema == 1) { + file->aarch64PauthAbiCoreInfo = {0, 0}; + } else { + file->aarch64PauthAbiCoreInfo = {baInfo.Pauth.TagPlatform, + baInfo.Pauth.TagSchema}; + } + } + file->andFeatures = baInfo.AndFeatures; + } +} + +template +static GnuPropertiesInfo readGnuProperty(Ctx &, const InputSection &, + ObjFile &); + template void ObjFile::parse(bool ignoreComdats) { object::ELFFile obj = this->getObj(); // Read a section table. justSymbols is usually false. @@ -552,8 +599,31 @@ template void ObjFile::parse(bool ignoreComdats) { StringRef shstrtab = CHECK2(obj.getSectionStringTable(objSections), this); uint64_t size = objSections.size(); sections.resize(size); + + // For handling AArch64 Build attributes and GNU properties + AArch64BuildAttrSubsections aarch64BAsubSections; + GnuPropertiesInfo gnuProperty; + bool hasAArch64BuildAttributes = false; + bool hasGNUProperties = false; + for (size_t i = 0; i != size; ++i) { const Elf_Shdr &sec = objSections[i]; + // Object files that use processor features such as Intel Control-Flow + // Enforcement (CET) or AArch64 Branch Target Identification BTI, use a + // .note.gnu.property section containing a bitfield of feature bits like the + // GNU_PROPERTY_X86_FEATURE_1_IBT flag. Read a bitmap containing the flag. + if (check(obj.getSectionName(sec, shstrtab)) == ".note.gnu.property") { + gnuProperty = readGnuProperty( + ctx, + InputSection(*this, sec, check(obj.getSectionName(sec, shstrtab))), + *this); + hasGNUProperties = true; + // Since we merge bitmaps from multiple object files to create a new + // .note.gnu.property containing a single AND'ed bitmap, we discard an + // input file's .note.gnu.property section. + sections[i] = &InputSection::discarded; + } + if (LLVM_LIKELY(sec.sh_type == SHT_PROGBITS)) continue; if (LLVM_LIKELY(sec.sh_type == SHT_GROUP)) { @@ -637,13 +707,27 @@ template void ObjFile::parse(bool ignoreComdats) { } break; case EM_AARCH64: - // FIXME: BuildAttributes have been implemented in llvm, but not yet in - // lld. Remove the section so that it does not accumulate in the output - // file. When support is implemented we expect not to output a build - // attributes section in files of type ET_EXEC or ET_SHARED, but ld -r - // ouptut will need a single merged attributes section. - if (sec.sh_type == SHT_AARCH64_ATTRIBUTES) + // At this stage AArch64 Build Attributes does not replace GNU Properties. + // When both exists, their values must match. + // When both exists and contain different attributes, they complement each + // other. Currently attributes are represented in the linked object file + // as GNU properties, which are already supported by the Linux kernel and + // the dynamic loader. In the future, when relocatable linking (`-r` flag) + // is performed, a single merged AArch64 Build Attributes section will be + // emitted. + if (sec.sh_type == SHT_AARCH64_ATTRIBUTES) { + ArrayRef contents = check(obj.getSectionContents(sec)); + AArch64AttributeParser attributes; + StringRef name = check(obj.getSectionName(sec, shstrtab)); + InputSection isec(*this, sec, name); + if (Error e = attributes.parse(contents, ELFT::Endianness)) { + Warn(ctx) << &isec << ": " << std::move(e); + } else { + aarch64BAsubSections = extractBuildAttributesSubsections(attributes); + hasAArch64BuildAttributes = true; + } sections[i] = &InputSection::discarded; + } // Producing a static binary with MTE globals is not currently supported, // remove all SHT_AARCH64_MEMTAG_GLOBALS_STATIC sections as they're unused // medatada, and we don't want them to end up in the output file for @@ -655,6 +739,14 @@ template void ObjFile::parse(bool ignoreComdats) { } } + if (hasAArch64BuildAttributes) { + // Handle AArch64 Build Attributes and GNU properties: + // - Err on mismatched values. + // - Store missing values as GNU properties. + handleAArch64BAAndGnuProperties(this, ctx, hasGNUProperties, + aarch64BAsubSections, gnuProperty); + } + // Read a symbol table. initializeSymbols(obj); } @@ -974,8 +1066,8 @@ static void parseGnuPropertyNote(Ctx &ctx, ELFFileBase &f, // hardware-assisted call flow control; // - AArch64 PAuth ABI core info (16 bytes). template -static void readGnuProperty(Ctx &ctx, const InputSection &sec, - ObjFile &f) { +static GnuPropertiesInfo readGnuProperty(Ctx &ctx, const InputSection &sec, + ObjFile &f) { using Elf_Nhdr = typename ELFT::Nhdr; using Elf_Note = typename ELFT::Note; @@ -992,7 +1084,7 @@ static void readGnuProperty(Ctx &ctx, const InputSection &sec, featureAndType = GNU_PROPERTY_RISCV_FEATURE_1_AND; break; default: - return; + return GnuPropertiesInfo{}; } ArrayRef data = sec.content(); @@ -1007,7 +1099,7 @@ static void readGnuProperty(Ctx &ctx, const InputSection &sec, auto *nhdr = reinterpret_cast(data.data()); if (data.size() < sizeof(Elf_Nhdr) || data.size() < nhdr->getSize(sec.addralign)) - return void(err(data.data()) << "data is too short"); + return (err(data.data()) << "data is too short", GnuPropertiesInfo{}); Elf_Note note(*nhdr); if (nhdr->n_type != NT_GNU_PROPERTY_TYPE_0 || note.getName() != "GNU") { @@ -1023,6 +1115,7 @@ static void readGnuProperty(Ctx &ctx, const InputSection &sec, // Go to next NOTE record to look for more FEATURE_1_AND descriptions. data = data.slice(nhdr->getSize(sec.addralign)); } + return GnuPropertiesInfo{f.andFeatures, f.aarch64PauthAbiCoreInfo}; } template diff --git a/lld/ELF/InputFiles.h b/lld/ELF/InputFiles.h index ba844ad18f637..9d40030f22fcc 100644 --- a/lld/ELF/InputFiles.h +++ b/lld/ELF/InputFiles.h @@ -244,6 +244,11 @@ class ELFFileBase : public InputFile { std::optional aarch64PauthAbiCoreInfo; }; +struct GnuPropertiesInfo { + uint32_t andFeatures = 0; + std::optional pauthAbiCoreInfo; +}; + // .o file. template class ObjFile : public ELFFileBase { LLVM_ELF_IMPORT_TYPES_ELFT(ELFT) diff --git a/lld/test/ELF/Inputs/aarch64-func3-pac-replace.s b/lld/test/ELF/Inputs/aarch64-func3-pac-replace.s new file mode 100644 index 0000000000000..b6133844d07f7 --- /dev/null +++ b/lld/test/ELF/Inputs/aarch64-func3-pac-replace.s @@ -0,0 +1,10 @@ +// Declare file properties exclusively with aarch64 build attributes. + +.aeabi_subsection aeabi_feature_and_bits, optional, uleb128 +.aeabi_attribute Tag_Feature_PAC, 1 + +.text +.globl func3 +.type func3,@function +func3: + ret diff --git a/lld/test/ELF/Inputs/aarch64-pac1-replace.s b/lld/test/ELF/Inputs/aarch64-pac1-replace.s new file mode 100644 index 0000000000000..f763f9de2342a --- /dev/null +++ b/lld/test/ELF/Inputs/aarch64-pac1-replace.s @@ -0,0 +1,13 @@ +// This file replace gnu properties with aarch64 build attributes. + +.aeabi_subsection aeabi_feature_and_bits, optional, uleb128 +.aeabi_attribute Tag_Feature_PAC, 1 + +.text +.globl func2 +.type func2,@function +func2: + .globl func3 + .type func3, @function + bl func3 + ret diff --git a/lld/test/ELF/aarch64-build-attributes-be.s b/lld/test/ELF/aarch64-build-attributes-be.s new file mode 100644 index 0000000000000..985e19348cf66 --- /dev/null +++ b/lld/test/ELF/aarch64-build-attributes-be.s @@ -0,0 +1,50 @@ +// REQUIRES: aarch64 +// RUN: llvm-mc -triple=aarch64_be %s -filetype=obj -o %t.o +// RUN: ld.lld %t.o --shared -o %t.so +// RUN: llvm-readelf -n %t.so | FileCheck %s --check-prefix=NOTE + +/// The Build attributes section appearing in the output of +/// llvm-mc should not appear in the output of lld, because +/// AArch64 build attributes are being transformed into .gnu.properties. + +/// Test mc -> big endian, lld -> little endian +// RUN: llvm-mc -triple=aarch64_be %s -filetype=obj -o %t.o +// RUN: ld.lld %t.o --shared -o %t.so +// RUN: llvm-readelf -n %t.so | FileCheck %s --check-prefix=NOTE +// RUN: ld.lld %t.o -o %t +// RUN: llvm-readelf -n %t.so | FileCheck %s --check-prefix=NOTE +// RUN: ld.lld -r %t.o -o %t2.o +// RUN: llvm-readelf -n %t.so | FileCheck %s --check-prefix=NOTE + +/// Test mc -> little endian, lld -> big endian +// RUN: llvm-mc -triple=aarch64 %s -filetype=obj -o %t.o +// RUN: ld.lld --EB %t.o --shared -o %t.so +// RUN: llvm-readelf -n %t.so | FileCheck %s --check-prefix=NOTE +// RUN: ld.lld --EB %t.o -o %t +// RUN: llvm-readelf -n %t.so | FileCheck %s --check-prefix=NOTE +// RUN: ld.lld --EB -r %t.o -o %t2.o +// RUN: llvm-readelf -n %t.so | FileCheck %s --check-prefix=NOTE + +/// Test mc -> big endian, lld -> big endian +// RUN: llvm-mc -triple=aarch64_be %s -filetype=obj -o %t.o +// RUN: ld.lld --EB %t.o --shared -o %t.so +// RUN: llvm-readelf -n %t.so | FileCheck %s --check-prefix=NOTE +// RUN: ld.lld --EB %t.o -o %t +// RUN: llvm-readelf -n %t.so | FileCheck %s --check-prefix=NOTE +// RUN: ld.lld --EB -r %t.o -o %t2.o +// RUN: llvm-readelf -n %t.so | FileCheck %s --check-prefix=NOTE + +// NOTE: Displaying notes found in: .note.gnu.property +// NOTE-NEXT: Owner Data size Description +// NOTE-NEXT: GNU 0x00000028 NT_GNU_PROPERTY_TYPE_0 (property note) +// NOTE-NEXT: Properties: aarch64 feature: BTI, PAC, GCS +// NOTE-NEXT: AArch64 PAuth ABI core info: platform 0x89abcdef (unknown), version 0x89abcdef + + +.aeabi_subsection aeabi_pauthabi, required, uleb128 +.aeabi_attribute Tag_PAuth_Platform, 81985529216486895 +.aeabi_attribute Tag_PAuth_Schema, 81985529216486895 +.aeabi_subsection aeabi_feature_and_bits, optional, uleb128 +.aeabi_attribute Tag_Feature_BTI, 1 +.aeabi_attribute Tag_Feature_PAC, 1 +.aeabi_attribute Tag_Feature_GCS, 1 diff --git a/lld/test/ELF/aarch64-build-attributes-err.s b/lld/test/ELF/aarch64-build-attributes-err.s new file mode 100644 index 0000000000000..965f13673eb5c --- /dev/null +++ b/lld/test/ELF/aarch64-build-attributes-err.s @@ -0,0 +1,35 @@ +// REQUIRES: aarch64 + +// RUN: llvm-mc -triple=aarch64 %s -filetype=obj -o %t.o +// RUN: not ld.lld %t.o -o /dev/null 2>&1 | FileCheck %s --check-prefix=ERR + +// ERR: Pauth Data mismatch: file contains both GNU properties and AArch64 build attributes sections with different Pauth data +// ERR-NEXT: Features Data mismatch: file contains both GNU properties and AArch64 build attributes sections with different And Features data + +.aeabi_subsection aeabi_pauthabi, required, uleb128 +.aeabi_attribute Tag_PAuth_Platform, 5 +.aeabi_attribute Tag_PAuth_Schema, 5 +.aeabi_subsection aeabi_feature_and_bits, optional, uleb128 +.aeabi_attribute Tag_Feature_BTI, 1 +.aeabi_attribute Tag_Feature_PAC, 1 +.aeabi_attribute Tag_Feature_GCS, 1 + +.section ".note.gnu.property", "a" +.long 4 +.long 0x10 +.long 0x5 +.asciz "GNU" +.long 0xc0000000 // GNU_PROPERTY_AARCH64_FEATURE_1_AND +.long 4 +.long 2 // GNU_PROPERTY_AARCH64_FEATURE_1_PAC +.long 0 + +.section ".note.gnu.property", "a" +.long 4 +.long 24 +.long 5 +.asciz "GNU" +.long 0xc0000001 +.long 16 +.quad 305419896 // platform +.quad 2271560481 // version diff --git a/lld/test/ELF/aarch64-build-attributes-invalid.s b/lld/test/ELF/aarch64-build-attributes-invalid.s new file mode 100644 index 0000000000000..7cd4723087de2 --- /dev/null +++ b/lld/test/ELF/aarch64-build-attributes-invalid.s @@ -0,0 +1,18 @@ +// REQUIRES: aarch64 + +// RUN: llvm-mc -triple=aarch64 -filetype=obj %s -o %t.o +// RUN: ld.lld -r %t.o -o %t.invalid.o +// RUN: llvm-readelf -n %t.invalid.o | FileCheck %s + +/// According to the BuildAttributes specification Build Attributes +/// A (TagPlatform, TagSchema)of (0, 1) maps to an explicit PAuth property +/// of platform = 0, version = 0 ('Invalid'). + +// CHECK: Displaying notes found in: .note.gnu.property +// CHECK-NEXT: Owner Data size Description +// CHECK-NEXT: GNU 0x00000018 NT_GNU_PROPERTY_TYPE_0 (property note) +// CHECK-NEXT: Properties: AArch64 PAuth ABI core info: platform 0x0 (invalid), version 0x0 + +.aeabi_subsection aeabi_pauthabi, required, uleb128 +.aeabi_attribute Tag_PAuth_Platform, 0 +.aeabi_attribute Tag_PAuth_Schema, 1 diff --git a/lld/test/ELF/aarch64-build-attributes-malformed.s b/lld/test/ELF/aarch64-build-attributes-malformed.s new file mode 100644 index 0000000000000..7787f6e2dbf4d --- /dev/null +++ b/lld/test/ELF/aarch64-build-attributes-malformed.s @@ -0,0 +1,16 @@ +# RUN: llvm-mc -triple=aarch64 -filetype=obj %s -o %t.o +# RUN: ld.lld %t.o /dev/null 2>&1 | FileCheck %s + +# CHECK: (.ARM.attributes): unexpected end of data at offset 0x3f while reading [0x3d, 0x41) + +.section .ARM.attributes,"",%0x70000003 +.byte 0x41 // Tag 'A' (format version) +.long 0x00000019 // Subsection length +.asciz "aeabi_pauthabi" // Subsection name +.byte 0x00, 0x00 // Optionality and Type +.byte 0x01, 0x01, 0x02, 0x01 // PAuth_Platform and PAuth_Schema +.long 0x00000023 // Subsection length +.asciz "aeabi_feature_and_bits" // Subsection name +.byte 0x01, 0x00 // Optionality and Type +.byte 0x00, 0x01, 0x01, 0x01, 0x02, 0x01 // BTI, PAC, GCS +.byte 0x00, 0x00 // This is the malformation, data is too long. diff --git a/lld/test/ELF/aarch64-build-attributes-mixed.s b/lld/test/ELF/aarch64-build-attributes-mixed.s new file mode 100644 index 0000000000000..729aebcef8d75 --- /dev/null +++ b/lld/test/ELF/aarch64-build-attributes-mixed.s @@ -0,0 +1,62 @@ +// RUN: rm -rf %t && split-file %s %t && cd %t + +// RUN: llvm-mc -triple=aarch64 -filetype=obj %s -o %t11.o +// RUN: llvm-mc -triple=aarch64 -filetype=obj merged-mixed-2.s -o %t12.o +// RUN: llvm-mc -triple=aarch64 -filetype=obj merged-mixed-3.s -o %t13.o +// RUN: ld.lld -r %t11.o %t12.o %t13.o -o %t.merged1.o +// RUN: llvm-readelf -n %t.merged1.o | FileCheck %s --check-prefix=NOTE-MIXED + +// NOTE-MIXED: Displaying notes found in: .note.gnu.property +// NOTE-MIXED-NEXT: Owner Data size Description +// NOTE-MIXED-NEXT: GNU 0x00000028 NT_GNU_PROPERTY_TYPE_0 (property note) +// NOTE-MIXED-NEXT: Properties: aarch64 feature: BTI, PAC +// NOTE-MIXED-NEXT: AArch64 PAuth ABI core info: platform 0x31 (unknown), version 0x13 + +/// The Build attributes section appearing in the output of +/// llvm-mc should not appear in the output of lld, because +/// AArch64 build attributes are being transformed into .gnu.properties. + +// CHECK: .note.gnu.property +// CHECK-NOT: .ARM.attributes + +.aeabi_subsection aeabi_pauthabi, required, uleb128 +.aeabi_attribute Tag_PAuth_Platform, 49 +.aeabi_attribute Tag_PAuth_Schema, 19 +.aeabi_subsection aeabi_feature_and_bits, optional, uleb128 +.aeabi_attribute Tag_Feature_BTI, 1 +.aeabi_attribute Tag_Feature_PAC, 1 +.aeabi_attribute Tag_Feature_GCS, 1 + + +//--- merged-mixed-2.s +.section ".note.gnu.property", "a" + .long 4 // Name length is always 4 ("GNU") + .long end - begin // Data length + .long 5 // Type: NT_GNU_PROPERTY_TYPE_0 + .asciz "GNU" // Name + .p2align 3 +begin: + .long 0xc0000000 // GNU_PROPERTY_AARCH64_FEATURE_1_AND + .long 4 + .long 7 // GNU_PROPERTY_AARCH64_FEATURE_1_BTI, PAC and GCS + .long 0 + // PAuth ABI property note + .long 0xc0000001 // Type: GNU_PROPERTY_AARCH64_FEATURE_PAUTH + .long 16 // Data size + .quad 49 // PAuth ABI platform + .quad 19 // PAuth ABI version + .p2align 3 // Align to 8 byte for 64 bit +end: + +//--- merged-mixed-3.s +.section .note.gnu.property, "a" + .align 4 + .long 4 // namesz + .long 0x10 // descsz + .long 5 // type (NT_GNU_PROPERTY_TYPE_0) + .asciz "GNU" // name (null-terminated) + .align 4 + .long 0xc0000000 // pr_type (GNU_PROPERTY_AARCH64_FEATURE_1_AND) + .long 4 // pr_datasz + .long 7 // pr_data: BTI (1), PAC (2), GCS (4) = 0b111 = 7 + .long 0 // padding or next property diff --git a/lld/test/ELF/aarch64-build-attributes.s b/lld/test/ELF/aarch64-build-attributes.s index 24e15f94e3d4a..90a68959a7b23 100644 --- a/lld/test/ELF/aarch64-build-attributes.s +++ b/lld/test/ELF/aarch64-build-attributes.s @@ -1,26 +1,49 @@ // REQUIRES: aarch64 -// RUN: llvm-mc -triple=aarch64 %s -filetype=obj -o %t.o -// RUN: ld.lld %t.o --shared -o %t.so -// RUN: llvm-readelf --sections %t.so | FileCheck %s -// RUN: ld.lld %t.o -o %t -// RUN: llvm-readelf --sections %t | FileCheck %s -// RUN: ld.lld -r %t.o -o %t2.o -// RUN: llvm-readelf --sections %t2.o | FileCheck %s - -/// File has a Build attributes section. This should not appear in -/// ET_EXEC or ET_SHARED files as there is no requirement for it to -/// do so. FIXME, the ld -r (relocatable link) should output a single -/// merged build attributes section. When full support is added in -/// ld.lld this test should be updated. +// RUN: rm -rf %t && split-file %s %t && cd %t +// RUN: llvm-mc -triple=aarch64 -filetype=obj %s -o %t1.o +// RUN: llvm-mc -triple=aarch64 -filetype=obj merged-2.s -o %t2.o +// RUN: llvm-mc -triple=aarch64 -filetype=obj merged-3.s -o %t3.o +// RUN: ld.lld -r %t1.o %t2.o %t3.o -o %t.merged.o +// RUN: llvm-readelf -n %t.merged.o | FileCheck %s --check-prefix=NOTE + +// NOTE: Displaying notes found in: .note.gnu.property +// NOTE-NEXT: Owner Data size Description +// NOTE-NEXT: GNU 0x00000028 NT_GNU_PROPERTY_TYPE_0 (property note) +// NOTE-NEXT: Properties: aarch64 feature: BTI +// NOTE-NEXT: AArch64 PAuth ABI core info: platform 0x31 (unknown), version 0x13 + +/// The Build attributes section appearing in the output of +/// llvm-mc should not appear in the output of lld, because +/// AArch64 build attributes are being transformed into .gnu.properties. + +// CHECK: .note.gnu.property // CHECK-NOT: .ARM.attributes +.aeabi_subsection aeabi_pauthabi, required, uleb128 +.aeabi_attribute Tag_PAuth_Platform, 49 +.aeabi_attribute Tag_PAuth_Schema, 19 .aeabi_subsection aeabi_feature_and_bits, optional, uleb128 .aeabi_attribute Tag_Feature_BTI, 1 .aeabi_attribute Tag_Feature_PAC, 1 .aeabi_attribute Tag_Feature_GCS, 1 -.global _start -.type _start, %function -_start: -ret + +//--- merged-2.s +.aeabi_subsection aeabi_pauthabi, required, uleb128 +.aeabi_attribute Tag_PAuth_Platform, 49 +.aeabi_attribute Tag_PAuth_Schema, 19 +.aeabi_subsection aeabi_feature_and_bits, optional, uleb128 +.aeabi_attribute Tag_Feature_BTI, 1 +.aeabi_attribute Tag_Feature_PAC, 0 +.aeabi_attribute Tag_Feature_GCS, 1 + + +//--- merged-3.s +.aeabi_subsection aeabi_pauthabi, required, uleb128 +.aeabi_attribute Tag_PAuth_Platform, 49 +.aeabi_attribute Tag_PAuth_Schema, 19 +.aeabi_subsection aeabi_feature_and_bits, optional, uleb128 +.aeabi_attribute Tag_Feature_BTI, 1 +.aeabi_attribute Tag_Feature_PAC, 1 +.aeabi_attribute Tag_Feature_GCS, 0 diff --git a/lld/test/ELF/aarch64-feature-pac-replace.s b/lld/test/ELF/aarch64-feature-pac-replace.s new file mode 100644 index 0000000000000..c60a430ed850f --- /dev/null +++ b/lld/test/ELF/aarch64-feature-pac-replace.s @@ -0,0 +1,148 @@ + +### This file replace .note.gnu.property with aarch64 build attributes in order to confirm +### interoperability. +### (Still using gnu properties in the helper files) + +# REQUIRES: aarch64 +# RUN: llvm-mc -filetype=obj -triple=aarch64-linux-gnu %s -o %t.o +# RUN: llvm-mc -filetype=obj -triple=aarch64-linux-gnu %p/Inputs/aarch64-pac1.s -o %t1.o +# RUN: llvm-mc -filetype=obj -triple=aarch64-linux-gnu %p/Inputs/aarch64-pac1-replace.s -o %t1-ba.o +# RUN: llvm-mc -filetype=obj -triple=aarch64-linux-gnu %p/Inputs/aarch64-func3.s -o %t2.o +# RUN: llvm-mc -filetype=obj -triple=aarch64-linux-gnu %p/Inputs/aarch64-func3-pac.s -o %t3.o +# RUN: llvm-mc -filetype=obj -triple=aarch64-linux-gnu %p/Inputs/aarch64-func3-pac-replace.s -o %t3-ba.o +# RUN: llvm-mc -filetype=obj -triple=aarch64-linux-gnu %p/Inputs/aarch64-func2.s -o %tno.o + +## We do not add PAC support when the inputs don't have the .note.gnu.property +## field. + +# RUN: ld.lld %tno.o %t3.o --shared -o %tno.so +# RUN: ld.lld %tno.o %t3-ba.o --shared -o %tno-ba.so +# RUN: llvm-objdump --no-print-imm-hex -d --mattr=+v8.3a --no-show-raw-insn %tno.so | FileCheck --check-prefix=NOPAC %s +# RUN: llvm-objdump --no-print-imm-hex -d --mattr=+v8.3a --no-show-raw-insn %tno-ba.so | FileCheck --check-prefix=NOPAC %s +# RUN: llvm-readelf -x .got.plt %tno.so | FileCheck --check-prefix SOGOTPLT %s +# RUN: llvm-readelf -x .got.plt %tno-ba.so | FileCheck --check-prefix SOGOTPLT %s +# RUN: llvm-readelf --dynamic-table %tno.so | FileCheck --check-prefix NOPACDYN %s +# RUN: llvm-readelf --dynamic-table %tno-ba.so | FileCheck --check-prefix NOPACDYN %s + +# NOPAC: 00000000000102b8 : +# NOPAC-NEXT: 102b8: bl 0x102f0 +# NOPAC-NEXT: ret +# NOPAC: Disassembly of section .plt: +# NOPAC: 00000000000102d0 <.plt>: +# NOPAC-NEXT: 102d0: stp x16, x30, [sp, #-16]! +# NOPAC-NEXT: adrp x16, 0x30000 +# NOPAC-NEXT: ldr x17, [x16, #960] +# NOPAC-NEXT: add x16, x16, #960 +# NOPAC-NEXT: br x17 +# NOPAC-NEXT: nop +# NOPAC-NEXT: nop +# NOPAC-NEXT: nop +# NOPAC: 00000000000102f0 : +# NOPAC-NEXT: 102f0: adrp x16, 0x30000 +# NOPAC-NEXT: ldr x17, [x16, #968] +# NOPAC-NEXT: add x16, x16, #968 +# NOPAC-NEXT: br x17 + +# SOGOTPLT: Hex dump of section '.got.plt': +# SOGOTPLT-NEXT: 0x000303b0 00000000 00000000 00000000 00000000 +# SOGOTPLT-NEXT: 0x000303c0 00000000 00000000 d0020100 00000000 + +# NOPACDYN-NOT: 0x0000000070000001 (AARCH64_BTI_PLT) +# NOPACDYN-NOT: 0x0000000070000003 (AARCH64_PAC_PLT) + + +# RUN: ld.lld %t1.o %t3.o --shared --soname=t.so -o %t.so +# RUN: ld.lld %t1-ba.o %t3-ba.o --shared --soname=t.so -o %t-ba.so +# RUN: llvm-readelf -n %t.so | FileCheck --check-prefix PACPROP %s +# RUN: llvm-readelf -n %t-ba.so | FileCheck --check-prefix PACPROP %s +# RUN: llvm-objdump --no-print-imm-hex -d --mattr=+v8.3a --no-show-raw-insn %t.so | FileCheck --check-prefix PACSO %s +# RUN: llvm-objdump --no-print-imm-hex -d --mattr=+v8.3a --no-show-raw-insn %t-ba.so | FileCheck --check-prefix PACSO %s +# RUN: llvm-readelf -x .got.plt %t.so | FileCheck --check-prefix SOGOTPLT2 %s +# RUN: llvm-readelf -x .got.plt %t-ba.so | FileCheck --check-prefix SOGOTPLT2 %s +# RUN: llvm-readelf --dynamic-table %t.so | FileCheck --check-prefix PACDYN %s +# RUN: llvm-readelf --dynamic-table %t-ba.so | FileCheck --check-prefix PACDYN %s + +# PACPROP: Properties: aarch64 feature: PAC + +# PACSO: Disassembly of section .text: +# PACSO: 0000000000010348 : +# PACSO-NEXT: 10348: bl 0x10380 +# PACSO-NEXT: 1034c: ret +# PACSO: 0000000000010350 : +# PACSO-NEXT: 10350: ret +# PACSO: Disassembly of section .plt: +# PACSO: 0000000000010360 <.plt>: +# PACSO-NEXT: 10360: stp x16, x30, [sp, #-16]! +# PACSO-NEXT: 10364: adrp x16, 0x30000 +# PACSO-NEXT: 10368: ldr x17, [x16, #1120] +# PACSO-NEXT: 1036c: add x16, x16, #1120 +# PACSO-NEXT: 10370: br x17 +# PACSO-NEXT: 10374: nop +# PACSO-NEXT: 10378: nop +# PACSO-NEXT: 1037c: nop +# PACSO: 0000000000010380 : +# PACSO-NEXT: 10380: adrp x16, 0x30000 +# PACSO-NEXT: 10384: ldr x17, [x16, #1128] +# PACSO-NEXT: 10388: add x16, x16, #1128 +# PACSO-NEXT: 1038c: br x17 + +# SOGOTPLT2: Hex dump of section '.got.plt': +# SOGOTPLT2-NEXT: 0x00030450 00000000 00000000 00000000 00000000 +# SOGOTPLT2-NEXT: 0x00030460 00000000 00000000 60030100 00000000 + +# PACDYN-NOT: 0x0000000070000001 (AARCH64_BTI_PLT) +# PACDYN-NOT: 0x0000000070000003 (AARCH64_PAC_PLT) + + +# RUN: ld.lld %t.o %t2.o -z pac-plt %t.so -o %tpacplt.exe 2>&1 | FileCheck -DFILE=%t2.o --check-prefix WARN %s +# RUN: ld.lld %t.o %t2.o -z pac-plt %t-ba.so -o %tpacplt-ba.exe 2>&1 | FileCheck -DFILE=%t2.o --check-prefix WARN %s + +# WARN: warning: [[FILE]]: -z pac-plt: file does not have GNU_PROPERTY_AARCH64_FEATURE_1_PAC property and no valid PAuth core info present for this link job + + +# RUN: llvm-readelf -n %tpacplt.exe | FileCheck --check-prefix=PACPROP %s +# RUN: llvm-readelf -n %tpacplt-ba.exe | FileCheck --check-prefix=PACPROP %s +# RUN: llvm-readelf --dynamic-table %tpacplt.exe | FileCheck --check-prefix PACDYN2 %s +# RUN: llvm-readelf --dynamic-table %tpacplt-ba.exe | FileCheck --check-prefix PACDYN2 %s +# RUN: llvm-objdump --no-print-imm-hex -d --mattr=+v8.3a --no-show-raw-insn %tpacplt.exe | FileCheck --check-prefix PACPLT %s +# RUN: llvm-objdump --no-print-imm-hex -d --mattr=+v8.3a --no-show-raw-insn %tpacplt-ba.exe | FileCheck --check-prefix PACPLT %s + +# PACDYN2-NOT: 0x0000000070000001 (AARCH64_BTI_PLT) +# PACDYN2: 0x0000000070000003 (AARCH64_PAC_PLT) + +# PACPLT: Disassembly of section .text: +# PACPLT: 0000000000210370 : +# PACPLT-NEXT: 210370: bl 0x2103a0 +# PACPLT-NEXT: ret +# PACPLT: 0000000000210378 : +# PACPLT-NEXT: 210378: ret +# PACPLT: Disassembly of section .plt: +# PACPLT: 0000000000210380 <.plt>: +# PACPLT-NEXT: 210380: stp x16, x30, [sp, #-16]! +# PACPLT-NEXT: adrp x16, 0x230000 +# PACPLT-NEXT: ldr x17, [x16, #1192] +# PACPLT-NEXT: add x16, x16, #1192 +# PACPLT-NEXT: br x17 +# PACPLT-NEXT: nop +# PACPLT-NEXT: nop +# PACPLT-NEXT: nop +# PACPLT: 00000000002103a0 : +# PACPLT-NEXT: 2103a0: adrp x16, 0x230000 +# PACPLT-NEXT: ldr x17, [x16, #1200] +# PACPLT-NEXT: add x16, x16, #1200 +# PACPLT-NEXT: autia1716 +# PACPLT-NEXT: br x17 +# PACPLT-NEXT: nop + + +.aeabi_subsection aeabi_feature_and_bits, optional, uleb128 +.aeabi_attribute Tag_Feature_BTI, 0 +.aeabi_attribute Tag_Feature_PAC, 1 +.aeabi_attribute Tag_Feature_GCS, 0 + +.text +.globl _start +.type func1,%function +func1: + bl func2 + ret diff --git a/llvm/include/llvm/Support/AArch64AttributeParser.h b/llvm/include/llvm/Support/AArch64AttributeParser.h index aa82ca13668d5..796dbfd6f4162 100644 --- a/llvm/include/llvm/Support/AArch64AttributeParser.h +++ b/llvm/include/llvm/Support/AArch64AttributeParser.h @@ -25,6 +25,17 @@ class AArch64AttributeParser : public ELFExtendedAttrParser { : ELFExtendedAttrParser(nullptr, returnTagsNamesMap()) {} }; +// Used for extracting AArch64 Build Attributes +struct AArch64BuildAttrSubsections { + struct PauthSubSection { + uint64_t TagPlatform = 0; + uint64_t TagSchema = 0; + } Pauth; + uint32_t AndFeatures = 0; +}; + +AArch64BuildAttrSubsections +extractBuildAttributesSubsections(const llvm::AArch64AttributeParser &); } // namespace llvm #endif // LLVM_SUPPORT_AARCH64ATTRIBUTEPARSER_H diff --git a/llvm/lib/Support/AArch64AttributeParser.cpp b/llvm/lib/Support/AArch64AttributeParser.cpp index c675ef2a3b3df..eed8dba5d250a 100644 --- a/llvm/lib/Support/AArch64AttributeParser.cpp +++ b/llvm/lib/Support/AArch64AttributeParser.cpp @@ -8,6 +8,7 @@ //===---------------------------------------------------------------------===// #include "llvm/Support/AArch64AttributeParser.h" +#include "llvm/Support/AArch64BuildAttributes.h" std::vector & llvm::AArch64AttributeParser::returnTagsNamesMap() { @@ -19,3 +20,29 @@ llvm::AArch64AttributeParser::returnTagsNamesMap() { {"aeabi_feature_and_bits", 2, "Tag_Feature_GCS"}}; return TagsNamesMap; } + +llvm::AArch64BuildAttrSubsections llvm::extractBuildAttributesSubsections( + const llvm::AArch64AttributeParser &Attributes) { + + llvm::AArch64BuildAttrSubsections SubSections; + auto GetPauthValue = [&Attributes](unsigned Tag) { + return Attributes.getAttributeValue("aeabi_pauthabi", Tag).value_or(0); + }; + SubSections.Pauth.TagPlatform = + GetPauthValue(llvm::AArch64BuildAttributes::TAG_PAUTH_PLATFORM); + SubSections.Pauth.TagSchema = + GetPauthValue(llvm::AArch64BuildAttributes::TAG_PAUTH_SCHEMA); + + auto GetFeatureValue = [&Attributes](unsigned Tag) { + return Attributes.getAttributeValue("aeabi_feature_and_bits", Tag) + .value_or(0); + }; + SubSections.AndFeatures |= + GetFeatureValue(llvm::AArch64BuildAttributes::TAG_FEATURE_BTI); + SubSections.AndFeatures |= + GetFeatureValue(llvm::AArch64BuildAttributes::TAG_FEATURE_PAC) << 1; + SubSections.AndFeatures |= + GetFeatureValue(llvm::AArch64BuildAttributes::TAG_FEATURE_GCS) << 2; + + return SubSections; +} From cbc512f81f67556feaeda276736cc30243527ac6 Mon Sep 17 00:00:00 2001 From: Sivan Shani Date: Mon, 23 Jun 2025 17:05:58 +0100 Subject: [PATCH 2/4] Addressed review comments on test files --- .../ELF/Inputs/aarch64-func3-pac-replace.s | 10 -- lld/test/ELF/Inputs/aarch64-pac1-replace.s | 13 -- lld/test/ELF/aarch64-build-attributes-be.s | 27 +--- lld/test/ELF/aarch64-build-attributes-err.s | 20 +-- .../ELF/aarch64-build-attributes-malformed.s | 2 + lld/test/ELF/aarch64-build-attributes-mixed.s | 69 ++++---- lld/test/ELF/aarch64-build-attributes.s | 17 +- lld/test/ELF/aarch64-feature-pac-replace.s | 148 ------------------ 8 files changed, 61 insertions(+), 245 deletions(-) delete mode 100644 lld/test/ELF/Inputs/aarch64-func3-pac-replace.s delete mode 100644 lld/test/ELF/Inputs/aarch64-pac1-replace.s delete mode 100644 lld/test/ELF/aarch64-feature-pac-replace.s diff --git a/lld/test/ELF/Inputs/aarch64-func3-pac-replace.s b/lld/test/ELF/Inputs/aarch64-func3-pac-replace.s deleted file mode 100644 index b6133844d07f7..0000000000000 --- a/lld/test/ELF/Inputs/aarch64-func3-pac-replace.s +++ /dev/null @@ -1,10 +0,0 @@ -// Declare file properties exclusively with aarch64 build attributes. - -.aeabi_subsection aeabi_feature_and_bits, optional, uleb128 -.aeabi_attribute Tag_Feature_PAC, 1 - -.text -.globl func3 -.type func3,@function -func3: - ret diff --git a/lld/test/ELF/Inputs/aarch64-pac1-replace.s b/lld/test/ELF/Inputs/aarch64-pac1-replace.s deleted file mode 100644 index f763f9de2342a..0000000000000 --- a/lld/test/ELF/Inputs/aarch64-pac1-replace.s +++ /dev/null @@ -1,13 +0,0 @@ -// This file replace gnu properties with aarch64 build attributes. - -.aeabi_subsection aeabi_feature_and_bits, optional, uleb128 -.aeabi_attribute Tag_Feature_PAC, 1 - -.text -.globl func2 -.type func2,@function -func2: - .globl func3 - .type func3, @function - bl func3 - ret diff --git a/lld/test/ELF/aarch64-build-attributes-be.s b/lld/test/ELF/aarch64-build-attributes-be.s index 985e19348cf66..8ae9ce5d7f60b 100644 --- a/lld/test/ELF/aarch64-build-attributes-be.s +++ b/lld/test/ELF/aarch64-build-attributes-be.s @@ -3,11 +3,6 @@ // RUN: ld.lld %t.o --shared -o %t.so // RUN: llvm-readelf -n %t.so | FileCheck %s --check-prefix=NOTE -/// The Build attributes section appearing in the output of -/// llvm-mc should not appear in the output of lld, because -/// AArch64 build attributes are being transformed into .gnu.properties. - -/// Test mc -> big endian, lld -> little endian // RUN: llvm-mc -triple=aarch64_be %s -filetype=obj -o %t.o // RUN: ld.lld %t.o --shared -o %t.so // RUN: llvm-readelf -n %t.so | FileCheck %s --check-prefix=NOTE @@ -16,23 +11,7 @@ // RUN: ld.lld -r %t.o -o %t2.o // RUN: llvm-readelf -n %t.so | FileCheck %s --check-prefix=NOTE -/// Test mc -> little endian, lld -> big endian -// RUN: llvm-mc -triple=aarch64 %s -filetype=obj -o %t.o -// RUN: ld.lld --EB %t.o --shared -o %t.so -// RUN: llvm-readelf -n %t.so | FileCheck %s --check-prefix=NOTE -// RUN: ld.lld --EB %t.o -o %t -// RUN: llvm-readelf -n %t.so | FileCheck %s --check-prefix=NOTE -// RUN: ld.lld --EB -r %t.o -o %t2.o -// RUN: llvm-readelf -n %t.so | FileCheck %s --check-prefix=NOTE - -/// Test mc -> big endian, lld -> big endian -// RUN: llvm-mc -triple=aarch64_be %s -filetype=obj -o %t.o -// RUN: ld.lld --EB %t.o --shared -o %t.so -// RUN: llvm-readelf -n %t.so | FileCheck %s --check-prefix=NOTE -// RUN: ld.lld --EB %t.o -o %t -// RUN: llvm-readelf -n %t.so | FileCheck %s --check-prefix=NOTE -// RUN: ld.lld --EB -r %t.o -o %t2.o -// RUN: llvm-readelf -n %t.so | FileCheck %s --check-prefix=NOTE +/// Test that lld can read big-endian build-attributes. // NOTE: Displaying notes found in: .note.gnu.property // NOTE-NEXT: Owner Data size Description @@ -42,8 +21,8 @@ .aeabi_subsection aeabi_pauthabi, required, uleb128 -.aeabi_attribute Tag_PAuth_Platform, 81985529216486895 -.aeabi_attribute Tag_PAuth_Schema, 81985529216486895 +.aeabi_attribute Tag_PAuth_Platform, 0x123456789ABCDEF +.aeabi_attribute Tag_PAuth_Schema, 0x123456789ABCDEF .aeabi_subsection aeabi_feature_and_bits, optional, uleb128 .aeabi_attribute Tag_Feature_BTI, 1 .aeabi_attribute Tag_Feature_PAC, 1 diff --git a/lld/test/ELF/aarch64-build-attributes-err.s b/lld/test/ELF/aarch64-build-attributes-err.s index 965f13673eb5c..029cb1a68a5e7 100644 --- a/lld/test/ELF/aarch64-build-attributes-err.s +++ b/lld/test/ELF/aarch64-build-attributes-err.s @@ -15,21 +15,21 @@ .aeabi_attribute Tag_Feature_GCS, 1 .section ".note.gnu.property", "a" -.long 4 +.long 0x4 .long 0x10 .long 0x5 .asciz "GNU" .long 0xc0000000 // GNU_PROPERTY_AARCH64_FEATURE_1_AND -.long 4 -.long 2 // GNU_PROPERTY_AARCH64_FEATURE_1_PAC -.long 0 +.long 0x4 +.long 0x2 // GNU_PROPERTY_AARCH64_FEATURE_1_PAC +.long 0x0 .section ".note.gnu.property", "a" -.long 4 -.long 24 -.long 5 +.long 0x4 +.long 0x18 +.long 0x5 .asciz "GNU" .long 0xc0000001 -.long 16 -.quad 305419896 // platform -.quad 2271560481 // version +.long 0x10 +.quad 0x12345678 // platform +.quad 0x87654321 // version diff --git a/lld/test/ELF/aarch64-build-attributes-malformed.s b/lld/test/ELF/aarch64-build-attributes-malformed.s index 7787f6e2dbf4d..f40da1ab7e8a1 100644 --- a/lld/test/ELF/aarch64-build-attributes-malformed.s +++ b/lld/test/ELF/aarch64-build-attributes-malformed.s @@ -1,3 +1,5 @@ +# REQUIRES: aarch64 + # RUN: llvm-mc -triple=aarch64 -filetype=obj %s -o %t.o # RUN: ld.lld %t.o /dev/null 2>&1 | FileCheck %s diff --git a/lld/test/ELF/aarch64-build-attributes-mixed.s b/lld/test/ELF/aarch64-build-attributes-mixed.s index 729aebcef8d75..68e9a1fbffda5 100644 --- a/lld/test/ELF/aarch64-build-attributes-mixed.s +++ b/lld/test/ELF/aarch64-build-attributes-mixed.s @@ -1,21 +1,24 @@ +// REQUIRES: aarch64 + // RUN: rm -rf %t && split-file %s %t && cd %t // RUN: llvm-mc -triple=aarch64 -filetype=obj %s -o %t11.o -// RUN: llvm-mc -triple=aarch64 -filetype=obj merged-mixed-2.s -o %t12.o -// RUN: llvm-mc -triple=aarch64 -filetype=obj merged-mixed-3.s -o %t13.o +// RUN: llvm-mc -triple=aarch64 -filetype=obj merged-property.s -o %t12.o +// RUN: llvm-mc -triple=aarch64 -filetype=obj merged-property2.s -o %t13.o // RUN: ld.lld -r %t11.o %t12.o %t13.o -o %t.merged1.o // RUN: llvm-readelf -n %t.merged1.o | FileCheck %s --check-prefix=NOTE-MIXED +/// This test verifies merging of AArch64 build attributes and GNU property notes. +/// Three object files are combined: one with build attributes (PAuth information, BTI, PAC, GCS), +/// and two with GNU property notes encoding the same feature bits. +/// PAuth ABI info is provided in one of the files and it is expected to be preserved in the merged output. + // NOTE-MIXED: Displaying notes found in: .note.gnu.property // NOTE-MIXED-NEXT: Owner Data size Description // NOTE-MIXED-NEXT: GNU 0x00000028 NT_GNU_PROPERTY_TYPE_0 (property note) // NOTE-MIXED-NEXT: Properties: aarch64 feature: BTI, PAC // NOTE-MIXED-NEXT: AArch64 PAuth ABI core info: platform 0x31 (unknown), version 0x13 -/// The Build attributes section appearing in the output of -/// llvm-mc should not appear in the output of lld, because -/// AArch64 build attributes are being transformed into .gnu.properties. - // CHECK: .note.gnu.property // CHECK-NOT: .ARM.attributes @@ -28,35 +31,37 @@ .aeabi_attribute Tag_Feature_GCS, 1 -//--- merged-mixed-2.s +//--- merged-property.s .section ".note.gnu.property", "a" - .long 4 // Name length is always 4 ("GNU") - .long end - begin // Data length - .long 5 // Type: NT_GNU_PROPERTY_TYPE_0 - .asciz "GNU" // Name - .p2align 3 + .long 0x4 // Name length is always 4 ("GNU") + .long end - begin // Data length + .long 0x5 // Type: NT_GNU_PROPERTY_TYPE_0 + .asciz "GNU" // Name + .p2align 0x3 begin: - .long 0xc0000000 // GNU_PROPERTY_AARCH64_FEATURE_1_AND - .long 4 - .long 7 // GNU_PROPERTY_AARCH64_FEATURE_1_BTI, PAC and GCS - .long 0 + .long 0xc0000000 // GNU_PROPERTY_AARCH64_FEATURE_1_AND + .long 0x4 + .long 0x7 // pr_data: BTI (1), PAC (2), GCS (4) = 0b111 = 7 + .long 0x0 // PAuth ABI property note - .long 0xc0000001 // Type: GNU_PROPERTY_AARCH64_FEATURE_PAUTH - .long 16 // Data size - .quad 49 // PAuth ABI platform - .quad 19 // PAuth ABI version - .p2align 3 // Align to 8 byte for 64 bit + .long 0xc0000001 // GNU_PROPERTY_AARCH64_FEATURE_PAUTH + .long 0x10 // Data length + .quad 0x31 // PAuth ABI platform + .quad 0x13 // PAuth ABI version + .p2align 0x3 // Align to 8 byte for 64 bit end: -//--- merged-mixed-3.s +//--- merged-property2.s .section .note.gnu.property, "a" - .align 4 - .long 4 // namesz - .long 0x10 // descsz - .long 5 // type (NT_GNU_PROPERTY_TYPE_0) - .asciz "GNU" // name (null-terminated) - .align 4 - .long 0xc0000000 // pr_type (GNU_PROPERTY_AARCH64_FEATURE_1_AND) - .long 4 // pr_datasz - .long 7 // pr_data: BTI (1), PAC (2), GCS (4) = 0b111 = 7 - .long 0 // padding or next property + .align 0x4 + .long 0x4 // Name length is always 4 ("GNU") + .long end2 - begin2 // Data length + .long 0x5 // Type: NT_GNU_PROPERTY_TYPE_0 + .asciz "GNU" // Name +begin2: + .align 0x4 + .long 0xc0000000 // Type: GNU_PROPERTY_AARCH64_FEATURE_1_AND + .long 0x4 // Data length + .long 0x7 // pr_data: BTI (1), PAC (2), GCS (4) = 0b111 = 7 + .long 0x0 +end2: diff --git a/lld/test/ELF/aarch64-build-attributes.s b/lld/test/ELF/aarch64-build-attributes.s index 90a68959a7b23..f2d542150897e 100644 --- a/lld/test/ELF/aarch64-build-attributes.s +++ b/lld/test/ELF/aarch64-build-attributes.s @@ -2,21 +2,22 @@ // RUN: rm -rf %t && split-file %s %t && cd %t // RUN: llvm-mc -triple=aarch64 -filetype=obj %s -o %t1.o -// RUN: llvm-mc -triple=aarch64 -filetype=obj merged-2.s -o %t2.o -// RUN: llvm-mc -triple=aarch64 -filetype=obj merged-3.s -o %t3.o +// RUN: llvm-mc -triple=aarch64 -filetype=obj pauth-bti-gcs.s -o %t2.o +// RUN: llvm-mc -triple=aarch64 -filetype=obj pauth-bti-pac.s -o %t3.o // RUN: ld.lld -r %t1.o %t2.o %t3.o -o %t.merged.o // RUN: llvm-readelf -n %t.merged.o | FileCheck %s --check-prefix=NOTE +/// This test merges three object files with AArch64 build attributes. +/// All contain identical PAuth ABI info (platform/version), which must be preserved. +/// Only BTI is common across all three in the AND feature set, so the merged output +/// must show BTI only. PAC and GCS are present in subsets and should not appear. + // NOTE: Displaying notes found in: .note.gnu.property // NOTE-NEXT: Owner Data size Description // NOTE-NEXT: GNU 0x00000028 NT_GNU_PROPERTY_TYPE_0 (property note) // NOTE-NEXT: Properties: aarch64 feature: BTI // NOTE-NEXT: AArch64 PAuth ABI core info: platform 0x31 (unknown), version 0x13 -/// The Build attributes section appearing in the output of -/// llvm-mc should not appear in the output of lld, because -/// AArch64 build attributes are being transformed into .gnu.properties. - // CHECK: .note.gnu.property // CHECK-NOT: .ARM.attributes @@ -29,7 +30,7 @@ .aeabi_attribute Tag_Feature_GCS, 1 -//--- merged-2.s +//--- pauth-bti-gcs.s .aeabi_subsection aeabi_pauthabi, required, uleb128 .aeabi_attribute Tag_PAuth_Platform, 49 .aeabi_attribute Tag_PAuth_Schema, 19 @@ -39,7 +40,7 @@ .aeabi_attribute Tag_Feature_GCS, 1 -//--- merged-3.s +//--- pauth-bti-pac.s .aeabi_subsection aeabi_pauthabi, required, uleb128 .aeabi_attribute Tag_PAuth_Platform, 49 .aeabi_attribute Tag_PAuth_Schema, 19 diff --git a/lld/test/ELF/aarch64-feature-pac-replace.s b/lld/test/ELF/aarch64-feature-pac-replace.s deleted file mode 100644 index c60a430ed850f..0000000000000 --- a/lld/test/ELF/aarch64-feature-pac-replace.s +++ /dev/null @@ -1,148 +0,0 @@ - -### This file replace .note.gnu.property with aarch64 build attributes in order to confirm -### interoperability. -### (Still using gnu properties in the helper files) - -# REQUIRES: aarch64 -# RUN: llvm-mc -filetype=obj -triple=aarch64-linux-gnu %s -o %t.o -# RUN: llvm-mc -filetype=obj -triple=aarch64-linux-gnu %p/Inputs/aarch64-pac1.s -o %t1.o -# RUN: llvm-mc -filetype=obj -triple=aarch64-linux-gnu %p/Inputs/aarch64-pac1-replace.s -o %t1-ba.o -# RUN: llvm-mc -filetype=obj -triple=aarch64-linux-gnu %p/Inputs/aarch64-func3.s -o %t2.o -# RUN: llvm-mc -filetype=obj -triple=aarch64-linux-gnu %p/Inputs/aarch64-func3-pac.s -o %t3.o -# RUN: llvm-mc -filetype=obj -triple=aarch64-linux-gnu %p/Inputs/aarch64-func3-pac-replace.s -o %t3-ba.o -# RUN: llvm-mc -filetype=obj -triple=aarch64-linux-gnu %p/Inputs/aarch64-func2.s -o %tno.o - -## We do not add PAC support when the inputs don't have the .note.gnu.property -## field. - -# RUN: ld.lld %tno.o %t3.o --shared -o %tno.so -# RUN: ld.lld %tno.o %t3-ba.o --shared -o %tno-ba.so -# RUN: llvm-objdump --no-print-imm-hex -d --mattr=+v8.3a --no-show-raw-insn %tno.so | FileCheck --check-prefix=NOPAC %s -# RUN: llvm-objdump --no-print-imm-hex -d --mattr=+v8.3a --no-show-raw-insn %tno-ba.so | FileCheck --check-prefix=NOPAC %s -# RUN: llvm-readelf -x .got.plt %tno.so | FileCheck --check-prefix SOGOTPLT %s -# RUN: llvm-readelf -x .got.plt %tno-ba.so | FileCheck --check-prefix SOGOTPLT %s -# RUN: llvm-readelf --dynamic-table %tno.so | FileCheck --check-prefix NOPACDYN %s -# RUN: llvm-readelf --dynamic-table %tno-ba.so | FileCheck --check-prefix NOPACDYN %s - -# NOPAC: 00000000000102b8 : -# NOPAC-NEXT: 102b8: bl 0x102f0 -# NOPAC-NEXT: ret -# NOPAC: Disassembly of section .plt: -# NOPAC: 00000000000102d0 <.plt>: -# NOPAC-NEXT: 102d0: stp x16, x30, [sp, #-16]! -# NOPAC-NEXT: adrp x16, 0x30000 -# NOPAC-NEXT: ldr x17, [x16, #960] -# NOPAC-NEXT: add x16, x16, #960 -# NOPAC-NEXT: br x17 -# NOPAC-NEXT: nop -# NOPAC-NEXT: nop -# NOPAC-NEXT: nop -# NOPAC: 00000000000102f0 : -# NOPAC-NEXT: 102f0: adrp x16, 0x30000 -# NOPAC-NEXT: ldr x17, [x16, #968] -# NOPAC-NEXT: add x16, x16, #968 -# NOPAC-NEXT: br x17 - -# SOGOTPLT: Hex dump of section '.got.plt': -# SOGOTPLT-NEXT: 0x000303b0 00000000 00000000 00000000 00000000 -# SOGOTPLT-NEXT: 0x000303c0 00000000 00000000 d0020100 00000000 - -# NOPACDYN-NOT: 0x0000000070000001 (AARCH64_BTI_PLT) -# NOPACDYN-NOT: 0x0000000070000003 (AARCH64_PAC_PLT) - - -# RUN: ld.lld %t1.o %t3.o --shared --soname=t.so -o %t.so -# RUN: ld.lld %t1-ba.o %t3-ba.o --shared --soname=t.so -o %t-ba.so -# RUN: llvm-readelf -n %t.so | FileCheck --check-prefix PACPROP %s -# RUN: llvm-readelf -n %t-ba.so | FileCheck --check-prefix PACPROP %s -# RUN: llvm-objdump --no-print-imm-hex -d --mattr=+v8.3a --no-show-raw-insn %t.so | FileCheck --check-prefix PACSO %s -# RUN: llvm-objdump --no-print-imm-hex -d --mattr=+v8.3a --no-show-raw-insn %t-ba.so | FileCheck --check-prefix PACSO %s -# RUN: llvm-readelf -x .got.plt %t.so | FileCheck --check-prefix SOGOTPLT2 %s -# RUN: llvm-readelf -x .got.plt %t-ba.so | FileCheck --check-prefix SOGOTPLT2 %s -# RUN: llvm-readelf --dynamic-table %t.so | FileCheck --check-prefix PACDYN %s -# RUN: llvm-readelf --dynamic-table %t-ba.so | FileCheck --check-prefix PACDYN %s - -# PACPROP: Properties: aarch64 feature: PAC - -# PACSO: Disassembly of section .text: -# PACSO: 0000000000010348 : -# PACSO-NEXT: 10348: bl 0x10380 -# PACSO-NEXT: 1034c: ret -# PACSO: 0000000000010350 : -# PACSO-NEXT: 10350: ret -# PACSO: Disassembly of section .plt: -# PACSO: 0000000000010360 <.plt>: -# PACSO-NEXT: 10360: stp x16, x30, [sp, #-16]! -# PACSO-NEXT: 10364: adrp x16, 0x30000 -# PACSO-NEXT: 10368: ldr x17, [x16, #1120] -# PACSO-NEXT: 1036c: add x16, x16, #1120 -# PACSO-NEXT: 10370: br x17 -# PACSO-NEXT: 10374: nop -# PACSO-NEXT: 10378: nop -# PACSO-NEXT: 1037c: nop -# PACSO: 0000000000010380 : -# PACSO-NEXT: 10380: adrp x16, 0x30000 -# PACSO-NEXT: 10384: ldr x17, [x16, #1128] -# PACSO-NEXT: 10388: add x16, x16, #1128 -# PACSO-NEXT: 1038c: br x17 - -# SOGOTPLT2: Hex dump of section '.got.plt': -# SOGOTPLT2-NEXT: 0x00030450 00000000 00000000 00000000 00000000 -# SOGOTPLT2-NEXT: 0x00030460 00000000 00000000 60030100 00000000 - -# PACDYN-NOT: 0x0000000070000001 (AARCH64_BTI_PLT) -# PACDYN-NOT: 0x0000000070000003 (AARCH64_PAC_PLT) - - -# RUN: ld.lld %t.o %t2.o -z pac-plt %t.so -o %tpacplt.exe 2>&1 | FileCheck -DFILE=%t2.o --check-prefix WARN %s -# RUN: ld.lld %t.o %t2.o -z pac-plt %t-ba.so -o %tpacplt-ba.exe 2>&1 | FileCheck -DFILE=%t2.o --check-prefix WARN %s - -# WARN: warning: [[FILE]]: -z pac-plt: file does not have GNU_PROPERTY_AARCH64_FEATURE_1_PAC property and no valid PAuth core info present for this link job - - -# RUN: llvm-readelf -n %tpacplt.exe | FileCheck --check-prefix=PACPROP %s -# RUN: llvm-readelf -n %tpacplt-ba.exe | FileCheck --check-prefix=PACPROP %s -# RUN: llvm-readelf --dynamic-table %tpacplt.exe | FileCheck --check-prefix PACDYN2 %s -# RUN: llvm-readelf --dynamic-table %tpacplt-ba.exe | FileCheck --check-prefix PACDYN2 %s -# RUN: llvm-objdump --no-print-imm-hex -d --mattr=+v8.3a --no-show-raw-insn %tpacplt.exe | FileCheck --check-prefix PACPLT %s -# RUN: llvm-objdump --no-print-imm-hex -d --mattr=+v8.3a --no-show-raw-insn %tpacplt-ba.exe | FileCheck --check-prefix PACPLT %s - -# PACDYN2-NOT: 0x0000000070000001 (AARCH64_BTI_PLT) -# PACDYN2: 0x0000000070000003 (AARCH64_PAC_PLT) - -# PACPLT: Disassembly of section .text: -# PACPLT: 0000000000210370 : -# PACPLT-NEXT: 210370: bl 0x2103a0 -# PACPLT-NEXT: ret -# PACPLT: 0000000000210378 : -# PACPLT-NEXT: 210378: ret -# PACPLT: Disassembly of section .plt: -# PACPLT: 0000000000210380 <.plt>: -# PACPLT-NEXT: 210380: stp x16, x30, [sp, #-16]! -# PACPLT-NEXT: adrp x16, 0x230000 -# PACPLT-NEXT: ldr x17, [x16, #1192] -# PACPLT-NEXT: add x16, x16, #1192 -# PACPLT-NEXT: br x17 -# PACPLT-NEXT: nop -# PACPLT-NEXT: nop -# PACPLT-NEXT: nop -# PACPLT: 00000000002103a0 : -# PACPLT-NEXT: 2103a0: adrp x16, 0x230000 -# PACPLT-NEXT: ldr x17, [x16, #1200] -# PACPLT-NEXT: add x16, x16, #1200 -# PACPLT-NEXT: autia1716 -# PACPLT-NEXT: br x17 -# PACPLT-NEXT: nop - - -.aeabi_subsection aeabi_feature_and_bits, optional, uleb128 -.aeabi_attribute Tag_Feature_BTI, 0 -.aeabi_attribute Tag_Feature_PAC, 1 -.aeabi_attribute Tag_Feature_GCS, 0 - -.text -.globl _start -.type func1,%function -func1: - bl func2 - ret From fd61a7778531077754334ee8697c2dbae8290407 Mon Sep 17 00:00:00 2001 From: Sivan Shani Date: Fri, 4 Jul 2025 10:05:48 +0100 Subject: [PATCH 3/4] Address review comments: extract feature attributes directly from the input file instead of using a redundant intermediary; improve comments. --- lld/ELF/InputFiles.cpp | 82 ++++++++++++++++-------------------------- lld/ELF/InputFiles.h | 5 --- 2 files changed, 31 insertions(+), 56 deletions(-) diff --git a/lld/ELF/InputFiles.cpp b/lld/ELF/InputFiles.cpp index 55a04c43056c4..d28bb7181d765 100644 --- a/lld/ELF/InputFiles.cpp +++ b/lld/ELF/InputFiles.cpp @@ -540,49 +540,43 @@ uint32_t ObjFile::getSectionIndex(const Elf_Sym &sym) const { template static void -handleAArch64BAAndGnuProperties(ObjFile *file, Ctx &ctx, bool hasGP, - const AArch64BuildAttrSubsections &baInfo, - const GnuPropertiesInfo &gpInfo) { - if (hasGP) { +handleAArch64BAAndGnuProperties(ObjFile *file, Ctx &ctx, + const AArch64BuildAttrSubsections &baInfo) { + if (file->aarch64PauthAbiCoreInfo) { // Check for data mismatch - if (gpInfo.pauthAbiCoreInfo) { - if (baInfo.Pauth.TagPlatform != gpInfo.pauthAbiCoreInfo->platform || - baInfo.Pauth.TagSchema != gpInfo.pauthAbiCoreInfo->version) + if (file->aarch64PauthAbiCoreInfo) { + if (baInfo.Pauth.TagPlatform != file->aarch64PauthAbiCoreInfo->platform || + baInfo.Pauth.TagSchema != file->aarch64PauthAbiCoreInfo->version) Err(ctx) << file << " Pauth Data mismatch: file contains both GNU properties and " "AArch64 build attributes sections with different Pauth data"; } - if (baInfo.AndFeatures != gpInfo.andFeatures) + if (baInfo.AndFeatures != file->andFeatures) Err(ctx) << file << " Features Data mismatch: file contains both GNU " "properties and AArch64 build attributes sections with " "different And Features data"; } else { - // Write missing data - // We can only know when Pauth is missing. - // Unlike AArch64 Build Attributes, GNU properties does not give a way to - // distinguish between no-value given to value of '0' given. + // When BuildAttributes are missing, PauthABI value default to (TagPlatform + // = 0, TagSchema = 0). GNU properties do not write PAuthAbiCoreInfo if GNU + // property is not present. To match this behaviour, we only write + // PAuthAbiCoreInfo when there is at least one non-zero value. The + // specification reserves TagPlatform = 0, TagSchema = 1 values to match the + // 'Invalid' GNU property section with platform = 0, version = 0. if (baInfo.Pauth.TagPlatform || baInfo.Pauth.TagSchema) { - // According to the BuildAttributes specification Build Attributes - // default to a value of 0 when not present. A (TagPlatform, TagSchema) of - // (0, 0) maps to 'no PAuth property present'. A (TagPlatform, TagSchema) - // of (0, 1) maps to an explicit PAuth property of platform = 0, version = - // 0 ('Invalid'). - if (baInfo.Pauth.TagPlatform == 0 && baInfo.Pauth.TagSchema == 1) { + if (baInfo.Pauth.TagPlatform == 0 && baInfo.Pauth.TagSchema == 1) file->aarch64PauthAbiCoreInfo = {0, 0}; - } else { + else file->aarch64PauthAbiCoreInfo = {baInfo.Pauth.TagPlatform, baInfo.Pauth.TagSchema}; - } } file->andFeatures = baInfo.AndFeatures; } } template -static GnuPropertiesInfo readGnuProperty(Ctx &, const InputSection &, - ObjFile &); +static void readGnuProperty(Ctx &, const InputSection &, ObjFile &); template void ObjFile::parse(bool ignoreComdats) { object::ELFFile obj = this->getObj(); @@ -600,27 +594,19 @@ template void ObjFile::parse(bool ignoreComdats) { uint64_t size = objSections.size(); sections.resize(size); - // For handling AArch64 Build attributes and GNU properties AArch64BuildAttrSubsections aarch64BAsubSections; - GnuPropertiesInfo gnuProperty; bool hasAArch64BuildAttributes = false; - bool hasGNUProperties = false; for (size_t i = 0; i != size; ++i) { const Elf_Shdr &sec = objSections[i]; - // Object files that use processor features such as Intel Control-Flow - // Enforcement (CET) or AArch64 Branch Target Identification BTI, use a - // .note.gnu.property section containing a bitfield of feature bits like the - // GNU_PROPERTY_X86_FEATURE_1_IBT flag. Read a bitmap containing the flag. + // Read GNU property section into a per-InputFile structure that will be + // merged at a later stage. A synthetic section will be created for the + // merged contents. if (check(obj.getSectionName(sec, shstrtab)) == ".note.gnu.property") { - gnuProperty = readGnuProperty( + readGnuProperty( ctx, InputSection(*this, sec, check(obj.getSectionName(sec, shstrtab))), *this); - hasGNUProperties = true; - // Since we merge bitmaps from multiple object files to create a new - // .note.gnu.property containing a single AND'ed bitmap, we discard an - // input file's .note.gnu.property section. sections[i] = &InputSection::discarded; } @@ -707,20 +693,16 @@ template void ObjFile::parse(bool ignoreComdats) { } break; case EM_AARCH64: - // At this stage AArch64 Build Attributes does not replace GNU Properties. - // When both exists, their values must match. - // When both exists and contain different attributes, they complement each - // other. Currently attributes are represented in the linked object file - // as GNU properties, which are already supported by the Linux kernel and - // the dynamic loader. In the future, when relocatable linking (`-r` flag) - // is performed, a single merged AArch64 Build Attributes section will be - // emitted. + // Extract Build Attributes section contents into aarch64BAsubSections. + // Input objects may contain both build Build Attributes and GNU + // properties. We delay processing Build Attributes until we have finished + // reading all sections so that we can check that these are consistent. if (sec.sh_type == SHT_AARCH64_ATTRIBUTES) { ArrayRef contents = check(obj.getSectionContents(sec)); AArch64AttributeParser attributes; - StringRef name = check(obj.getSectionName(sec, shstrtab)); - InputSection isec(*this, sec, name); if (Error e = attributes.parse(contents, ELFT::Endianness)) { + StringRef name = check(obj.getSectionName(sec, shstrtab)); + InputSection isec(*this, sec, name); Warn(ctx) << &isec << ": " << std::move(e); } else { aarch64BAsubSections = extractBuildAttributesSubsections(attributes); @@ -743,8 +725,7 @@ template void ObjFile::parse(bool ignoreComdats) { // Handle AArch64 Build Attributes and GNU properties: // - Err on mismatched values. // - Store missing values as GNU properties. - handleAArch64BAAndGnuProperties(this, ctx, hasGNUProperties, - aarch64BAsubSections, gnuProperty); + handleAArch64BAAndGnuProperties(this, ctx, aarch64BAsubSections); } // Read a symbol table. @@ -1066,8 +1047,8 @@ static void parseGnuPropertyNote(Ctx &ctx, ELFFileBase &f, // hardware-assisted call flow control; // - AArch64 PAuth ABI core info (16 bytes). template -static GnuPropertiesInfo readGnuProperty(Ctx &ctx, const InputSection &sec, - ObjFile &f) { +static void readGnuProperty(Ctx &ctx, const InputSection &sec, + ObjFile &f) { using Elf_Nhdr = typename ELFT::Nhdr; using Elf_Note = typename ELFT::Note; @@ -1084,7 +1065,7 @@ static GnuPropertiesInfo readGnuProperty(Ctx &ctx, const InputSection &sec, featureAndType = GNU_PROPERTY_RISCV_FEATURE_1_AND; break; default: - return GnuPropertiesInfo{}; + return; } ArrayRef data = sec.content(); @@ -1099,7 +1080,7 @@ static GnuPropertiesInfo readGnuProperty(Ctx &ctx, const InputSection &sec, auto *nhdr = reinterpret_cast(data.data()); if (data.size() < sizeof(Elf_Nhdr) || data.size() < nhdr->getSize(sec.addralign)) - return (err(data.data()) << "data is too short", GnuPropertiesInfo{}); + return void(err(data.data()) << "data is too short"); Elf_Note note(*nhdr); if (nhdr->n_type != NT_GNU_PROPERTY_TYPE_0 || note.getName() != "GNU") { @@ -1115,7 +1096,6 @@ static GnuPropertiesInfo readGnuProperty(Ctx &ctx, const InputSection &sec, // Go to next NOTE record to look for more FEATURE_1_AND descriptions. data = data.slice(nhdr->getSize(sec.addralign)); } - return GnuPropertiesInfo{f.andFeatures, f.aarch64PauthAbiCoreInfo}; } template diff --git a/lld/ELF/InputFiles.h b/lld/ELF/InputFiles.h index 9d40030f22fcc..ba844ad18f637 100644 --- a/lld/ELF/InputFiles.h +++ b/lld/ELF/InputFiles.h @@ -244,11 +244,6 @@ class ELFFileBase : public InputFile { std::optional aarch64PauthAbiCoreInfo; }; -struct GnuPropertiesInfo { - uint32_t andFeatures = 0; - std::optional pauthAbiCoreInfo; -}; - // .o file. template class ObjFile : public ELFFileBase { LLVM_ELF_IMPORT_TYPES_ELFT(ELFT) From 87105389608bb3d87683886de03ccd2e6e22c845 Mon Sep 17 00:00:00 2001 From: Sivan Shani Date: Fri, 4 Jul 2025 11:30:10 +0100 Subject: [PATCH 4/4] Address CR comment: fix typo default-->defaults --- lld/ELF/InputFiles.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lld/ELF/InputFiles.cpp b/lld/ELF/InputFiles.cpp index d28bb7181d765..3dd706131f0f7 100644 --- a/lld/ELF/InputFiles.cpp +++ b/lld/ELF/InputFiles.cpp @@ -558,7 +558,7 @@ handleAArch64BAAndGnuProperties(ObjFile *file, Ctx &ctx, "properties and AArch64 build attributes sections with " "different And Features data"; } else { - // When BuildAttributes are missing, PauthABI value default to (TagPlatform + // When BuildAttributes are missing, PauthABI value defaults to (TagPlatform // = 0, TagSchema = 0). GNU properties do not write PAuthAbiCoreInfo if GNU // property is not present. To match this behaviour, we only write // PAuthAbiCoreInfo when there is at least one non-zero value. The