3131#include " llvm/Support/TarWriter.h"
3232#include " llvm/Support/raw_ostream.h"
3333
34+ #include < tuple>
35+
3436using namespace llvm ;
3537using namespace llvm ::ELF;
3638using namespace llvm ::object;
@@ -878,11 +880,14 @@ void ObjFile<ELFT>::initializeSections(bool ignoreComdats,
878880// of zero or more type-length-value fields. We want to find a field of a
879881// certain type. It seems a bit too much to just store a 32-bit value, perhaps
880882// the ABI is unnecessarily complicated.
881- template <class ELFT > static uint32_t readAndFeatures (const InputSection &sec) {
883+ template <class ELFT >
884+ static std::pair<uint32_t , SmallVector<uint8_t , 0 >>
885+ readGnuProperty (const InputSection &sec) {
882886 using Elf_Nhdr = typename ELFT::Nhdr;
883887 using Elf_Note = typename ELFT::Note;
884888
885889 uint32_t featuresSet = 0 ;
890+ SmallVector<uint8_t , 0 > aarch64PauthAbiTag;
886891 ArrayRef<uint8_t > data = sec.content ();
887892 auto reportFatal = [&](const uint8_t *place, const char *msg) {
888893 fatal (toString (sec.file ) + " :(" + sec.name + " +0x" +
@@ -926,6 +931,16 @@ template <class ELFT> static uint32_t readAndFeatures(const InputSection &sec) {
926931 featuresSet |= read32<ELFT::TargetEndianness>(desc.data ());
927932 }
928933
934+ if (config->emachine == EM_AARCH64 &&
935+ type == GNU_PROPERTY_AARCH64_FEATURE_PAUTH) {
936+ // TODO: proper invalid size handling
937+ assert (size == 16 );
938+ // TODO: proper multiple pauth tags handling
939+ assert (aarch64PauthAbiTag.empty ());
940+ aarch64PauthAbiTag.resize (size);
941+ memcpy (aarch64PauthAbiTag.data (), desc.data (), size);
942+ }
943+
929944 // Padding is present in the note descriptor, if necessary.
930945 desc = desc.slice (alignTo<(ELFT::Is64Bits ? 8 : 4 )>(size));
931946 }
@@ -934,7 +949,7 @@ template <class ELFT> static uint32_t readAndFeatures(const InputSection &sec) {
934949 data = data.slice (nhdr->getSize (sec.addralign ));
935950 }
936951
937- return featuresSet;
952+ return { featuresSet, aarch64PauthAbiTag} ;
938953}
939954
940955// Extract compatibility info for aarch64 pointer authentication from the
@@ -1029,12 +1044,15 @@ InputSectionBase *ObjFile<ELFT>::createInputSection(uint32_t idx,
10291044 // .note.gnu.property containing a single AND'ed bitmap, we discard an input
10301045 // file's .note.gnu.property section.
10311046 if (name == " .note.gnu.property" ) {
1032- this ->andFeatures = readAndFeatures<ELFT>(InputSection (*this , sec, name));
1047+ std::tie (this ->andFeatures , this ->aarch64PauthAbiTag ) =
1048+ readGnuProperty<ELFT>(InputSection (*this , sec, name));
10331049 return &InputSection::discarded;
10341050 }
10351051
10361052 if (config->emachine == EM_AARCH64 &&
10371053 name == " .note.AARCH64-PAUTH-ABI-tag" ) {
1054+ // TODO: proper handling of both ways of ELF marking in one file
1055+ assert (this ->aarch64PauthAbiTag .empty ());
10381056 readAArch64PauthAbiTag<ELFT>(InputSection (*this , sec, name), *this );
10391057 return &InputSection::discarded;
10401058 }
0 commit comments