Skip to content

Commit fd61a77

Browse files
committed
Address review comments: extract feature attributes directly from the input file instead of using a redundant intermediary; improve comments.
1 parent cbc512f commit fd61a77

File tree

2 files changed

+31
-56
lines changed

2 files changed

+31
-56
lines changed

lld/ELF/InputFiles.cpp

Lines changed: 31 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -540,49 +540,43 @@ uint32_t ObjFile<ELFT>::getSectionIndex(const Elf_Sym &sym) const {
540540

541541
template <class ELFT>
542542
static void
543-
handleAArch64BAAndGnuProperties(ObjFile<ELFT> *file, Ctx &ctx, bool hasGP,
544-
const AArch64BuildAttrSubsections &baInfo,
545-
const GnuPropertiesInfo &gpInfo) {
546-
if (hasGP) {
543+
handleAArch64BAAndGnuProperties(ObjFile<ELFT> *file, Ctx &ctx,
544+
const AArch64BuildAttrSubsections &baInfo) {
545+
if (file->aarch64PauthAbiCoreInfo) {
547546
// Check for data mismatch
548-
if (gpInfo.pauthAbiCoreInfo) {
549-
if (baInfo.Pauth.TagPlatform != gpInfo.pauthAbiCoreInfo->platform ||
550-
baInfo.Pauth.TagSchema != gpInfo.pauthAbiCoreInfo->version)
547+
if (file->aarch64PauthAbiCoreInfo) {
548+
if (baInfo.Pauth.TagPlatform != file->aarch64PauthAbiCoreInfo->platform ||
549+
baInfo.Pauth.TagSchema != file->aarch64PauthAbiCoreInfo->version)
551550
Err(ctx)
552551
<< file
553552
<< " Pauth Data mismatch: file contains both GNU properties and "
554553
"AArch64 build attributes sections with different Pauth data";
555554
}
556-
if (baInfo.AndFeatures != gpInfo.andFeatures)
555+
if (baInfo.AndFeatures != file->andFeatures)
557556
Err(ctx) << file
558557
<< " Features Data mismatch: file contains both GNU "
559558
"properties and AArch64 build attributes sections with "
560559
"different And Features data";
561560
} else {
562-
// Write missing data
563-
// We can only know when Pauth is missing.
564-
// Unlike AArch64 Build Attributes, GNU properties does not give a way to
565-
// distinguish between no-value given to value of '0' given.
561+
// When BuildAttributes are missing, PauthABI value default to (TagPlatform
562+
// = 0, TagSchema = 0). GNU properties do not write PAuthAbiCoreInfo if GNU
563+
// property is not present. To match this behaviour, we only write
564+
// PAuthAbiCoreInfo when there is at least one non-zero value. The
565+
// specification reserves TagPlatform = 0, TagSchema = 1 values to match the
566+
// 'Invalid' GNU property section with platform = 0, version = 0.
566567
if (baInfo.Pauth.TagPlatform || baInfo.Pauth.TagSchema) {
567-
// According to the BuildAttributes specification Build Attributes
568-
// default to a value of 0 when not present. A (TagPlatform, TagSchema) of
569-
// (0, 0) maps to 'no PAuth property present'. A (TagPlatform, TagSchema)
570-
// of (0, 1) maps to an explicit PAuth property of platform = 0, version =
571-
// 0 ('Invalid').
572-
if (baInfo.Pauth.TagPlatform == 0 && baInfo.Pauth.TagSchema == 1) {
568+
if (baInfo.Pauth.TagPlatform == 0 && baInfo.Pauth.TagSchema == 1)
573569
file->aarch64PauthAbiCoreInfo = {0, 0};
574-
} else {
570+
else
575571
file->aarch64PauthAbiCoreInfo = {baInfo.Pauth.TagPlatform,
576572
baInfo.Pauth.TagSchema};
577-
}
578573
}
579574
file->andFeatures = baInfo.AndFeatures;
580575
}
581576
}
582577

583578
template <typename ELFT>
584-
static GnuPropertiesInfo readGnuProperty(Ctx &, const InputSection &,
585-
ObjFile<ELFT> &);
579+
static void readGnuProperty(Ctx &, const InputSection &, ObjFile<ELFT> &);
586580

587581
template <class ELFT> void ObjFile<ELFT>::parse(bool ignoreComdats) {
588582
object::ELFFile<ELFT> obj = this->getObj();
@@ -600,27 +594,19 @@ template <class ELFT> void ObjFile<ELFT>::parse(bool ignoreComdats) {
600594
uint64_t size = objSections.size();
601595
sections.resize(size);
602596

603-
// For handling AArch64 Build attributes and GNU properties
604597
AArch64BuildAttrSubsections aarch64BAsubSections;
605-
GnuPropertiesInfo gnuProperty;
606598
bool hasAArch64BuildAttributes = false;
607-
bool hasGNUProperties = false;
608599

609600
for (size_t i = 0; i != size; ++i) {
610601
const Elf_Shdr &sec = objSections[i];
611-
// Object files that use processor features such as Intel Control-Flow
612-
// Enforcement (CET) or AArch64 Branch Target Identification BTI, use a
613-
// .note.gnu.property section containing a bitfield of feature bits like the
614-
// GNU_PROPERTY_X86_FEATURE_1_IBT flag. Read a bitmap containing the flag.
602+
// Read GNU property section into a per-InputFile structure that will be
603+
// merged at a later stage. A synthetic section will be created for the
604+
// merged contents.
615605
if (check(obj.getSectionName(sec, shstrtab)) == ".note.gnu.property") {
616-
gnuProperty = readGnuProperty(
606+
readGnuProperty(
617607
ctx,
618608
InputSection(*this, sec, check(obj.getSectionName(sec, shstrtab))),
619609
*this);
620-
hasGNUProperties = true;
621-
// Since we merge bitmaps from multiple object files to create a new
622-
// .note.gnu.property containing a single AND'ed bitmap, we discard an
623-
// input file's .note.gnu.property section.
624610
sections[i] = &InputSection::discarded;
625611
}
626612

@@ -707,20 +693,16 @@ template <class ELFT> void ObjFile<ELFT>::parse(bool ignoreComdats) {
707693
}
708694
break;
709695
case EM_AARCH64:
710-
// At this stage AArch64 Build Attributes does not replace GNU Properties.
711-
// When both exists, their values must match.
712-
// When both exists and contain different attributes, they complement each
713-
// other. Currently attributes are represented in the linked object file
714-
// as GNU properties, which are already supported by the Linux kernel and
715-
// the dynamic loader. In the future, when relocatable linking (`-r` flag)
716-
// is performed, a single merged AArch64 Build Attributes section will be
717-
// emitted.
696+
// Extract Build Attributes section contents into aarch64BAsubSections.
697+
// Input objects may contain both build Build Attributes and GNU
698+
// properties. We delay processing Build Attributes until we have finished
699+
// reading all sections so that we can check that these are consistent.
718700
if (sec.sh_type == SHT_AARCH64_ATTRIBUTES) {
719701
ArrayRef<uint8_t> contents = check(obj.getSectionContents(sec));
720702
AArch64AttributeParser attributes;
721-
StringRef name = check(obj.getSectionName(sec, shstrtab));
722-
InputSection isec(*this, sec, name);
723703
if (Error e = attributes.parse(contents, ELFT::Endianness)) {
704+
StringRef name = check(obj.getSectionName(sec, shstrtab));
705+
InputSection isec(*this, sec, name);
724706
Warn(ctx) << &isec << ": " << std::move(e);
725707
} else {
726708
aarch64BAsubSections = extractBuildAttributesSubsections(attributes);
@@ -743,8 +725,7 @@ template <class ELFT> void ObjFile<ELFT>::parse(bool ignoreComdats) {
743725
// Handle AArch64 Build Attributes and GNU properties:
744726
// - Err on mismatched values.
745727
// - Store missing values as GNU properties.
746-
handleAArch64BAAndGnuProperties<ELFT>(this, ctx, hasGNUProperties,
747-
aarch64BAsubSections, gnuProperty);
728+
handleAArch64BAAndGnuProperties<ELFT>(this, ctx, aarch64BAsubSections);
748729
}
749730

750731
// Read a symbol table.
@@ -1066,8 +1047,8 @@ static void parseGnuPropertyNote(Ctx &ctx, ELFFileBase &f,
10661047
// hardware-assisted call flow control;
10671048
// - AArch64 PAuth ABI core info (16 bytes).
10681049
template <class ELFT>
1069-
static GnuPropertiesInfo readGnuProperty(Ctx &ctx, const InputSection &sec,
1070-
ObjFile<ELFT> &f) {
1050+
static void readGnuProperty(Ctx &ctx, const InputSection &sec,
1051+
ObjFile<ELFT> &f) {
10711052
using Elf_Nhdr = typename ELFT::Nhdr;
10721053
using Elf_Note = typename ELFT::Note;
10731054

@@ -1084,7 +1065,7 @@ static GnuPropertiesInfo readGnuProperty(Ctx &ctx, const InputSection &sec,
10841065
featureAndType = GNU_PROPERTY_RISCV_FEATURE_1_AND;
10851066
break;
10861067
default:
1087-
return GnuPropertiesInfo{};
1068+
return;
10881069
}
10891070

10901071
ArrayRef<uint8_t> data = sec.content();
@@ -1099,7 +1080,7 @@ static GnuPropertiesInfo readGnuProperty(Ctx &ctx, const InputSection &sec,
10991080
auto *nhdr = reinterpret_cast<const Elf_Nhdr *>(data.data());
11001081
if (data.size() < sizeof(Elf_Nhdr) ||
11011082
data.size() < nhdr->getSize(sec.addralign))
1102-
return (err(data.data()) << "data is too short", GnuPropertiesInfo{});
1083+
return void(err(data.data()) << "data is too short");
11031084

11041085
Elf_Note note(*nhdr);
11051086
if (nhdr->n_type != NT_GNU_PROPERTY_TYPE_0 || note.getName() != "GNU") {
@@ -1115,7 +1096,6 @@ static GnuPropertiesInfo readGnuProperty(Ctx &ctx, const InputSection &sec,
11151096
// Go to next NOTE record to look for more FEATURE_1_AND descriptions.
11161097
data = data.slice(nhdr->getSize(sec.addralign));
11171098
}
1118-
return GnuPropertiesInfo{f.andFeatures, f.aarch64PauthAbiCoreInfo};
11191099
}
11201100

11211101
template <class ELFT>

lld/ELF/InputFiles.h

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -244,11 +244,6 @@ class ELFFileBase : public InputFile {
244244
std::optional<AArch64PauthAbiCoreInfo> aarch64PauthAbiCoreInfo;
245245
};
246246

247-
struct GnuPropertiesInfo {
248-
uint32_t andFeatures = 0;
249-
std::optional<AArch64PauthAbiCoreInfo> pauthAbiCoreInfo;
250-
};
251-
252247
// .o file.
253248
template <class ELFT> class ObjFile : public ELFFileBase {
254249
LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)

0 commit comments

Comments
 (0)