-
Notifications
You must be signed in to change notification settings - Fork 13.5k
[lld][AArch64][Build Attributes] Add support for converting AArch64 Build Attributes to GNU Properties #131990
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
f98c952
d4299e9
783dbf9
5dfca32
8b6377a
9d81bc0
9c8f950
94bebe0
e73a6bd
60a5eea
9052abf
52869a1
534e55e
02a1fa7
ec89018
7292c36
d026726
6709e9a
04e2a16
eb2abbc
eb84c8c
be821a5
f9a0fcb
ab6dc73
8a21905
fd365cb
024847d
f9d7aa8
7903817
f225428
0e643e5
f187b20
81a86d8
592100f
fe23b71
dceec93
de3e43e
72e725a
902f9ef
2df0fcb
ecd2c51
d439930
22c6478
3321d46
17dbb95
ed7b5e6
f0eb74d
6a541b8
4620091
c8637a0
1470bdf
98dc05f
57d7ff9
ddb1b3e
debcd30
deaf7de
88359f4
64a45ed
8873a15
9e70cbe
bbb33fe
711ea6f
b46b466
24f4b80
8e27785
da33de6
5cb1940
572e5f4
31214b8
7d2d795
b2803a3
cb49f85
dd89ea1
93f21f2
e40609a
3f5b14c
5013203
9738781
45f7246
d802fcc
ae1a032
b5c882e
54fe275
afca83d
20760a9
8b1e002
37a3aec
da6ddb2
b3e62ec
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -22,6 +22,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" | ||
|
@@ -539,6 +540,65 @@ uint32_t ObjFile<ELFT>::getSectionIndex(const Elf_Sym &sym) const { | |
this); | ||
} | ||
|
||
template <class ELFT> | ||
static void | ||
handleAArch64BAAndGnuProperties(const ELFT &tPointer, Ctx &ctx, bool isBE, | ||
bool hasBA, bool hasGP, | ||
const AArch64BuildAttrSubsections &baInfo, | ||
const gnuPropertiesInfo &gpInfo) { | ||
|
||
auto serializeUnsigned = [&](unsigned valueLow, unsigned valueHigh, | ||
bool isBE) -> std::array<uint8_t, 16> { | ||
std::array<uint8_t, 16> arr; | ||
for (size_t i = 0; i < 8; ++i) { | ||
arr[i] = static_cast<uint8_t>( | ||
(static_cast<uint64_t>(valueLow) >> (8 * (isBE ? (7 - i) : i))) & | ||
0xFF); | ||
arr[i + 8] = static_cast<uint8_t>( | ||
(static_cast<uint64_t>(valueHigh) >> (8 * (isBE ? (7 - i) : i))) & | ||
0xFF); | ||
}; | ||
return arr; | ||
}; | ||
|
||
if (hasBA && hasGP) { | ||
// Check for data mismatch | ||
if (!gpInfo.aarch64PauthAbiCoreInfo.empty()) { | ||
auto baPauth = serializeUnsigned(baInfo.Pauth.TagPlatform, | ||
baInfo.Pauth.TagSchema, isBE); | ||
if (gpInfo.aarch64PauthAbiCoreInfo != ArrayRef<uint8_t>(baPauth)) | ||
Err(ctx) | ||
<< tPointer | ||
<< " Pauth Data mismatch: file contains both GNU properties and " | ||
"AArch64 build attributes sections with different Pauth data"; | ||
} | ||
if (baInfo.AndFeatures != gpInfo.andFeatures) | ||
Err(ctx) << tPointer | ||
<< " Features Data mismatch: file contains both GNU " | ||
"properties and AArch64 build attributes sections with " | ||
"different And Features data"; | ||
} | ||
|
||
if (hasBA && !hasGP) { | ||
// 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) { | ||
tPointer->aarch64PauthAbiCoreInfoStorage = serializeUnsigned( | ||
baInfo.Pauth.TagPlatform, baInfo.Pauth.TagSchema, isBE); | ||
tPointer->aarch64PauthAbiCoreInfo = | ||
tPointer->aarch64PauthAbiCoreInfoStorage; | ||
} | ||
tPointer->andFeatures = baInfo.AndFeatures; | ||
} | ||
} | ||
|
||
// Forward declaration: | ||
template <typename ELFT> | ||
static gnuPropertiesInfo readGnuProperty(Ctx &, const InputSection &, | ||
ObjFile<ELFT> &); | ||
|
||
template <class ELFT> void ObjFile<ELFT>::parse(bool ignoreComdats) { | ||
object::ELFFile<ELFT> obj = this->getObj(); | ||
// Read a section table. justSymbols is usually false. | ||
|
@@ -554,8 +614,32 @@ template <class ELFT> void ObjFile<ELFT>::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 gnuPropertiesInformation; | ||
bool hasAArch64BuildAttributes = false; | ||
bool hasGNUProperties = false; | ||
|
||
for (size_t i = 0; i != size; ++i) { | ||
const Elf_Shdr &sec = objSections[i]; | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It looks like BuildAttributes are read in parse() but gnu properties are read in as part of initializeSections. As neither GNU properties or BuildAttributes rely on symbol information then it should be possible to read them here, move the BuildAttributes reading to initializeSections or delay the merging of BuildAttributes and GNU properties to after initializeSections. If reading GNU properties is moved here, remember to remove them from createInputSection or they will get processed twice. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. done |
||
// 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") { | ||
gnuPropertiesInformation = 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)) { | ||
|
@@ -639,16 +723,30 @@ template <class ELFT> void ObjFile<ELFT>::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<uint8_t> 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; | ||
} | ||
sivan-shani marked this conversation as resolved.
Show resolved
Hide resolved
|
||
// 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 | ||
// metadata, and we don't want them to end up in the output file for | ||
// static executables. | ||
if (sec.sh_type == SHT_AARCH64_MEMTAG_GLOBALS_STATIC && | ||
!canHaveMemtagGlobals(ctx)) | ||
|
@@ -657,6 +755,16 @@ template <class ELFT> void ObjFile<ELFT>::parse(bool ignoreComdats) { | |
} | ||
} | ||
|
||
Stylie777 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
if (hasAArch64BuildAttributes) { | ||
bool isBE = ELFT::Endianness == llvm::endianness::big; | ||
// Handle AArch64 Build Attributes and GNU properties: | ||
// - Err on mismatched values. | ||
// - Store missing values as GNU properties. | ||
handleAArch64BAAndGnuProperties(this, ctx, isBE, hasAArch64BuildAttributes, | ||
hasGNUProperties, aarch64BAsubSections, | ||
gnuPropertiesInformation); | ||
} | ||
|
||
// Read a symbol table. | ||
initializeSymbols(obj); | ||
} | ||
|
@@ -968,14 +1076,15 @@ static void parseGnuPropertyNote(Ctx &ctx, ELFFileBase &f, | |
desc = desc.slice(alignTo<(ELFT::Is64Bits ? 8 : 4)>(size)); | ||
} | ||
} | ||
|
||
// Read the following info from the .note.gnu.property section and write it to | ||
// the corresponding fields in `ObjFile`: | ||
// - Feature flags (32 bits) representing x86 or AArch64 features for | ||
// hardware-assisted call flow control; | ||
// - AArch64 PAuth ABI core info (16 bytes). | ||
template <class ELFT> | ||
static void readGnuProperty(Ctx &ctx, const InputSection &sec, | ||
ObjFile<ELFT> &f) { | ||
static gnuPropertiesInfo readGnuProperty(Ctx &ctx, const InputSection &sec, | ||
ObjFile<ELFT> &f) { | ||
using Elf_Nhdr = typename ELFT::Nhdr; | ||
using Elf_Note = typename ELFT::Note; | ||
|
||
|
@@ -991,7 +1100,7 @@ static void readGnuProperty(Ctx &ctx, const InputSection &sec, | |
auto *nhdr = reinterpret_cast<const Elf_Nhdr *>(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") { | ||
|
@@ -1011,6 +1120,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 <class ELFT> | ||
|
@@ -1065,19 +1175,6 @@ InputSectionBase *ObjFile<ELFT>::createInputSection(uint32_t idx, | |
return &InputSection::discarded; | ||
} | ||
|
||
// 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. | ||
// | ||
// 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. | ||
if (name == ".note.gnu.property") { | ||
readGnuProperty<ELFT>(ctx, InputSection(*this, sec, name), *this); | ||
return &InputSection::discarded; | ||
} | ||
|
||
// Split stacks is a feature to support a discontiguous stack, | ||
// commonly used in the programming language Go. For the details, | ||
// see https://gcc.gnu.org/wiki/SplitStacks. An object file compiled | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -242,6 +242,12 @@ class ELFFileBase : public InputFile { | |
uint32_t andFeatures = 0; | ||
bool hasCommonSyms = false; | ||
ArrayRef<uint8_t> aarch64PauthAbiCoreInfo; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Will this ever point anywhere other than There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
No
Yes In other places There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. An alternative that involves a bit of refactoring of the existing aarch64PauthABICoreInfo, which is optimal for a note section, but not ideal for build attributes, is to deserialize the aarch64PauthABICoreInfo and store the members as two uint64_t instead of an arrayRef. We'll need to update the comparison code in Driver.cpp and in the .note.gnu.property writing code, but it may be neater overall. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I agree that the proposed approach could lead to a cleaner design overall, but given the scope and context of the current changes, it feels a bit too involved to refactor at this stage. It might be better to revisit this as a follow-up if needed. |
||
std::array<uint8_t, 16> aarch64PauthAbiCoreInfoStorage; | ||
}; | ||
|
||
struct gnuPropertiesInfo { | ||
Stylie777 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
uint32_t andFeatures = 0; | ||
ArrayRef<uint8_t> aarch64PauthAbiCoreInfo; | ||
}; | ||
|
||
// .o file. | ||
|
@@ -268,7 +274,6 @@ template <class ELFT> class ObjFile : public ELFFileBase { | |
|
||
uint32_t getSectionIndex(const Elf_Sym &sym) const; | ||
|
||
|
||
// Pointer to this input file's .llvm_addrsig section, if it has one. | ||
const Elf_Shdr *addrsigSec = nullptr; | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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): invalid Extended Build Attributes subsection size at offset: 39 | ||
|
||
.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. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've simplified this in my pr131990 branch, but why do we need this serialization at all?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There are 2 reasons for the serialization of
baInfo.Pauth.TagPlatform
andbaInfo.Pauth.TagSchema
into an array:gpInfo.aarch64PauthAbiCoreInfo
)file->aarch64PauthAbiCoreInfoStorage
While the second seems unavoidable, the first could be replaced with reading the values from the
gpInfo.aarch64PauthAbiCoreInfo
array.Reading the values from the array has the advantage of allowing more granular error messages.
On the other hand, it require some more operations.
Will commit a version that reads the values from the array separately so it can be decided which one is preferable.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In some conversations I've had with the PAuthABI team, they've wanted a property/build-attribute that would be the equivalent of the command-line option
-z pac-plt
ostensibly to prevent user-error if the linker is called directly (the clang driver could add this automatically).In that case it would be inconvenient to store the PAuthABICoreInfo as an array_ref only used for comparison.
Would definitely like to see an implementation where both BuildAttributes and GNU properties decode to the same individual properties. Then in https://github.com/llvm/llvm-project/blob/main/lld/ELF/SyntheticSections.cpp#L347 was can use a
write32()
call for each property rather than memcpy.