@@ -540,49 +540,43 @@ uint32_t ObjFile<ELFT>::getSectionIndex(const Elf_Sym &sym) const {
540540
541541template <class ELFT >
542542static 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
583578template <typename ELFT>
584- static GnuPropertiesInfo readGnuProperty (Ctx &, const InputSection &,
585- ObjFile<ELFT> &);
579+ static void readGnuProperty (Ctx &, const InputSection &, ObjFile<ELFT> &);
586580
587581template <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).
10681049template <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
11211101template <class ELFT >
0 commit comments