31
31
#include " llvm/Support/TarWriter.h"
32
32
#include " llvm/Support/raw_ostream.h"
33
33
34
+ #include < tuple>
35
+
34
36
using namespace llvm ;
35
37
using namespace llvm ::ELF;
36
38
using namespace llvm ::object;
@@ -878,11 +880,14 @@ void ObjFile<ELFT>::initializeSections(bool ignoreComdats,
878
880
// of zero or more type-length-value fields. We want to find a field of a
879
881
// certain type. It seems a bit too much to just store a 32-bit value, perhaps
880
882
// 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) {
882
886
using Elf_Nhdr = typename ELFT::Nhdr;
883
887
using Elf_Note = typename ELFT::Note;
884
888
885
889
uint32_t featuresSet = 0 ;
890
+ SmallVector<uint8_t , 0 > aarch64PauthAbiTag;
886
891
ArrayRef<uint8_t > data = sec.content ();
887
892
auto reportFatal = [&](const uint8_t *place, const char *msg) {
888
893
fatal (toString (sec.file ) + " :(" + sec.name + " +0x" +
@@ -926,6 +931,16 @@ template <class ELFT> static uint32_t readAndFeatures(const InputSection &sec) {
926
931
featuresSet |= read32<ELFT::TargetEndianness>(desc.data ());
927
932
}
928
933
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
+
929
944
// Padding is present in the note descriptor, if necessary.
930
945
desc = desc.slice (alignTo<(ELFT::Is64Bits ? 8 : 4 )>(size));
931
946
}
@@ -934,7 +949,7 @@ template <class ELFT> static uint32_t readAndFeatures(const InputSection &sec) {
934
949
data = data.slice (nhdr->getSize (sec.addralign ));
935
950
}
936
951
937
- return featuresSet;
952
+ return { featuresSet, aarch64PauthAbiTag} ;
938
953
}
939
954
940
955
// Extract compatibility info for aarch64 pointer authentication from the
@@ -1029,12 +1044,15 @@ InputSectionBase *ObjFile<ELFT>::createInputSection(uint32_t idx,
1029
1044
// .note.gnu.property containing a single AND'ed bitmap, we discard an input
1030
1045
// file's .note.gnu.property section.
1031
1046
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));
1033
1049
return &InputSection::discarded;
1034
1050
}
1035
1051
1036
1052
if (config->emachine == EM_AARCH64 &&
1037
1053
name == " .note.AARCH64-PAUTH-ABI-tag" ) {
1054
+ // TODO: proper handling of both ways of ELF marking in one file
1055
+ assert (this ->aarch64PauthAbiTag .empty ());
1038
1056
readAArch64PauthAbiTag<ELFT>(InputSection (*this , sec, name), *this );
1039
1057
return &InputSection::discarded;
1040
1058
}
0 commit comments