diff --git a/lld/ELF/Config.h b/lld/ELF/Config.h index c55b547a733c7..6c43d3aadbdbe 100644 --- a/lld/ELF/Config.h +++ b/lld/ELF/Config.h @@ -188,6 +188,8 @@ struct Config { StringRef zBtiReport = "none"; StringRef zCetReport = "none"; StringRef zPauthReport = "none"; + StringRef zZicfilpReport = "none"; + StringRef zZicfissReport = "none"; bool ltoBBAddrMap; llvm::StringRef ltoBasicBlockSections; std::pair thinLTOObjectSuffixReplace; @@ -331,6 +333,8 @@ struct Config { bool zText; bool zRetpolineplt; bool zWxneeded; + bool zForceZicfilp; + bool zForceZicfiss; DiscardPolicy discard; GnuStackKind zGnustack; ICFLevel icf; diff --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp index b29e1e1a67f13..54b6dc40c33a5 100644 --- a/lld/ELF/Driver.cpp +++ b/lld/ELF/Driver.cpp @@ -468,6 +468,13 @@ static void checkOptions() { error("-z pauth-report only supported on AArch64"); } + if (config->emachine != EM_RISCV) { + if (config->zZicfilpReport != "none") + error("-z zicfilip-report only supported on RISC-V"); + if (config->zZicfissReport != "none") + error("-z zicfiss-report only supported on RISC-V"); + } + if (config->emachine != EM_386 && config->emachine != EM_X86_64 && config->zCetReport != "none") error("-z cet-report only supported on X86 and X86_64"); @@ -1465,6 +1472,8 @@ static void readConfigs(opt::InputArgList &args) { config->zWxneeded = hasZOption(args, "wxneeded"); setUnresolvedSymbolPolicy(args); config->power10Stubs = args.getLastArgValue(OPT_power10_stubs_eq) != "no"; + config->zForceZicfilp = hasZOption(args, "force-zicfilp"); + config->zForceZicfiss = hasZOption(args, "force-zicfiss"); if (opt::Arg *arg = args.getLastArg(OPT_eb, OPT_el)) { if (arg->getOption().matches(OPT_eb)) @@ -1508,7 +1517,9 @@ static void readConfigs(opt::InputArgList &args) { auto reports = {std::make_pair("bti-report", &config->zBtiReport), std::make_pair("cet-report", &config->zCetReport), - std::make_pair("pauth-report", &config->zPauthReport)}; + std::make_pair("pauth-report", &config->zPauthReport), + std::make_pair("zicfilp-report", &config->zZicfilpReport), + std::make_pair("zicfiss-report", &config->zZicfissReport)}; for (opt::Arg *arg : args.filtered(OPT_z)) { std::pair option = StringRef(arg->getValue()).split('='); @@ -2651,7 +2662,7 @@ static void checkAndReportMissingFeature(StringRef config, uint32_t features, // ones can be allowed (see -z pauth-report). static void readSecurityNotes() { if (config->emachine != EM_386 && config->emachine != EM_X86_64 && - config->emachine != EM_AARCH64) + config->emachine != EM_AARCH64 && config->emachine != EM_RISCV) return; config->andFeatures = -1; @@ -2685,6 +2696,17 @@ static void readSecurityNotes() { toString(f) + ": -z cet-report: file does not have " "GNU_PROPERTY_X86_FEATURE_1_SHSTK property"); + checkAndReportMissingFeature( + config->zZicfilpReport, features, + GNU_PROPERTY_RISCV_FEATURE_1_CFI_LP_SIMPLE, + toString(f) + ": -z zicfilp-report: file does not have " + "GNU_PROPERTY_RISCV_FEATURE_1_CFI_LP_SIMPLE property"); + + checkAndReportMissingFeature( + config->zZicfissReport, features, GNU_PROPERTY_RISCV_FEATURE_1_CFI_SS, + toString(f) + ": -z zicfiss-report: file does not have " + "GNU_PROPERTY_RISCV_FEATURE_1_CFI_SS property"); + if (config->zForceBti && !(features & GNU_PROPERTY_AARCH64_FEATURE_1_BTI)) { features |= GNU_PROPERTY_AARCH64_FEATURE_1_BTI; if (config->zBtiReport == "none") @@ -2697,6 +2719,24 @@ static void readSecurityNotes() { "GNU_PROPERTY_X86_FEATURE_1_IBT property"); features |= GNU_PROPERTY_X86_FEATURE_1_IBT; } + + if (config->zForceZicfilp && + !(features & GNU_PROPERTY_RISCV_FEATURE_1_CFI_LP_SIMPLE)) { + features |= GNU_PROPERTY_RISCV_FEATURE_1_CFI_LP_SIMPLE; + if (config->zZicfilpReport == "none") + warn(toString(f) + + ": -z force-zicfilp: file does not have " + "GNU_PROPERTY_RISCV_FEATURE_1_CFI_LP_SIMPLE property"); + } + + if (config->zForceZicfiss && + !(features & GNU_PROPERTY_RISCV_FEATURE_1_CFI_SS)) { + features |= GNU_PROPERTY_RISCV_FEATURE_1_CFI_SS; + if (config->zZicfissReport == "none") + warn(toString(f) + ": -z force-zicfiss: file does not have " + "GNU_PROPERTY_RISCV_FEATURE_1_CFI_SS property"); + } + if (config->zPacPlt && !(features & GNU_PROPERTY_AARCH64_FEATURE_1_PAC)) { warn(toString(f) + ": -z pac-plt: file does not have " "GNU_PROPERTY_AARCH64_FEATURE_1_PAC property"); diff --git a/lld/ELF/InputFiles.cpp b/lld/ELF/InputFiles.cpp index 1f496026d3ae2..e80e11714a694 100644 --- a/lld/ELF/InputFiles.cpp +++ b/lld/ELF/InputFiles.cpp @@ -954,9 +954,20 @@ void readGnuProperty(const InputSection &sec, ObjFile &f) { continue; } - uint32_t featureAndType = config->emachine == EM_AARCH64 - ? GNU_PROPERTY_AARCH64_FEATURE_1_AND - : GNU_PROPERTY_X86_FEATURE_1_AND; + uint32_t featureAndType = 0; + switch (config->emachine) { + case EM_X86_64: + featureAndType = GNU_PROPERTY_X86_FEATURE_1_AND; + break; + case EM_AARCH64: + featureAndType = GNU_PROPERTY_AARCH64_FEATURE_1_AND; + break; + case EM_RISCV: + featureAndType = GNU_PROPERTY_RISCV_FEATURE_1_AND; + break; + default : + llvm_unreachable("unknow EMachine for GNU_PROPERTY AND"); + } // Read a body of a NOTE record, which consists of type-length-value fields. ArrayRef desc = note.getDesc(sec.addralign); diff --git a/lld/ELF/SyntheticSections.cpp b/lld/ELF/SyntheticSections.cpp index 7b9ada40c0f67..bd6f3a3f2bb07 100644 --- a/lld/ELF/SyntheticSections.cpp +++ b/lld/ELF/SyntheticSections.cpp @@ -323,9 +323,18 @@ void GnuPropertySection::writeTo(uint8_t *buf) { write32(buf + 8, NT_GNU_PROPERTY_TYPE_0); // Type memcpy(buf + 12, "GNU", 4); // Name string - uint32_t featureAndType = config->emachine == EM_AARCH64 - ? GNU_PROPERTY_AARCH64_FEATURE_1_AND - : GNU_PROPERTY_X86_FEATURE_1_AND; + uint32_t featureAndType = 0; + switch (config->emachine) { + default: + featureAndType = GNU_PROPERTY_X86_FEATURE_1_AND; + break; + case EM_AARCH64: + featureAndType = GNU_PROPERTY_AARCH64_FEATURE_1_AND; + break; + case EM_RISCV: + featureAndType = GNU_PROPERTY_RISCV_FEATURE_1_AND; + break; + } unsigned offset = 16; if (config->andFeatures != 0) { diff --git a/lld/test/ELF/riscv-force-cfi-property.s b/lld/test/ELF/riscv-force-cfi-property.s new file mode 100644 index 0000000000000..1fcc84a0d5912 --- /dev/null +++ b/lld/test/ELF/riscv-force-cfi-property.s @@ -0,0 +1,36 @@ +# REQUIRES: riscv + +# RUN: llvm-mc -filetype=obj -triple=riscv32-unknown-elf %s -o %t.rv32_lp.o +# RUN: ld.lld %t.rv32_lp.o -zforce-zicfilp -o %t.rv32_lp | count 0 +# RUN: llvm-readobj -n %t.rv32_lp | FileCheck -check-prefix=CHECK -check-prefix=CHECK_ZICFILP %s + +# RUN: llvm-mc -filetype=obj -triple=riscv64-unknown-elf %s -o %t.rv64_lp.o +# RUN: ld.lld %t.rv64_lp.o -zforce-zicfilp -o %t.rv64_lp | count 0 +# RUN: llvm-readobj -n %t.rv64_lp | FileCheck -check-prefix=CHECK -check-prefix=CHECK_ZICFILP %s + +# RUN: llvm-mc -filetype=obj -triple=riscv32-unknown-elf %s -o %t.rv32_ss.o +# RUN: ld.lld %t.rv32_ss.o -zforce-zicfiss -o %t.rv32_ss | count 0 +# RUN: llvm-readobj -n %t.rv32_ss | FileCheck -check-prefix=CHECK -check-prefix=CHECK_ZICFISS %s + +# RUN: llvm-mc -filetype=obj -triple=riscv64-unknown-elf %s -o %t.rv64_ss.o +# RUN: ld.lld %t.rv64_ss.o -zforce-zicfiss -o %t.rv64_ss | count 0 +# RUN: llvm-readobj -n %t.rv64_ss | FileCheck -check-prefix=CHECK -check-prefix=CHECK_ZICFISS %s + +# RUN: llvm-mc -filetype=obj -triple=riscv32-unknown-elf %s -o %t.rv32_lp_ss.o +# RUN: ld.lld %t.rv32_lp_ss.o -zforce-zicfilp -zforce-zicfiss -o %t.rv32_lp_ss | count 0 +# RUN: llvm-readobj -n %t.rv32_lp_ss | FileCheck -check-prefix=CHECK -check-prefix=CHECK_ZICFILP_ZICFISS %s + +# RUN: llvm-mc -filetype=obj -triple=riscv64-unknown-elf %s -o %t.rv64_lp_ss.o +# RUN: ld.lld %t.rv64_lp_ss.o -zforce-zicfilp -zforce-zicfiss -o %t.rv64_lp_ss | count 0 +# RUN: llvm-readobj -n %t.rv64_lp_ss | FileCheck -check-prefix=CHECK -check-prefix=CHECK_ZICFILP_ZICFISS %s + + + +// CHECK: Name: .note.gnu.property +// CHECK: Type: NT_GNU_PROPERTY_TYPE_0 (property note) +// CHECK: Property [ +// CHECK_ZICFISS: riscv feature: Zicfiss +// CHECK_ZICFILP: riscv feature: Zicfilp +// CHECK_ZICFILP_ZICFISS: riscv feature: Zicfilp, Zicfiss +// CHECK: ] + diff --git a/llvm/include/llvm/BinaryFormat/ELF.h b/llvm/include/llvm/BinaryFormat/ELF.h index f296acc2ca4bb..c8da286fc9588 100644 --- a/llvm/include/llvm/BinaryFormat/ELF.h +++ b/llvm/include/llvm/BinaryFormat/ELF.h @@ -1737,6 +1737,7 @@ enum : unsigned { GNU_PROPERTY_AARCH64_FEATURE_1_AND = 0xc0000000, GNU_PROPERTY_AARCH64_FEATURE_PAUTH = 0xc0000001, GNU_PROPERTY_X86_FEATURE_1_AND = 0xc0000002, + GNU_PROPERTY_RISCV_FEATURE_1_AND = 0xc0000000, GNU_PROPERTY_X86_UINT32_OR_LO = 0xc0008000, GNU_PROPERTY_X86_FEATURE_2_NEEDED = GNU_PROPERTY_X86_UINT32_OR_LO + 1, @@ -1796,6 +1797,12 @@ enum : unsigned { GNU_PROPERTY_X86_ISA_1_V4 = 1 << 3, }; +// riscv processor feature bits. +enum : unsigned { + GNU_PROPERTY_RISCV_FEATURE_1_CFI_LP_SIMPLE = 1 << 0, + GNU_PROPERTY_RISCV_FEATURE_1_CFI_SS = 1 << 1, +}; + // FreeBSD note types. enum { NT_FREEBSD_ABI_TAG = 1, diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVTargetStreamer.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVTargetStreamer.cpp index 0f92e9ed6a64d..c374eb6cf0453 100644 --- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVTargetStreamer.cpp +++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVTargetStreamer.cpp @@ -13,7 +13,10 @@ #include "RISCVTargetStreamer.h" #include "RISCVBaseInfo.h" #include "RISCVMCTargetDesc.h" +#include "llvm/MC/MCContext.h" +#include "llvm/MC/MCSectionELF.h" #include "llvm/MC/MCSymbol.h" +#include "llvm/BinaryFormat/ELF.h" #include "llvm/Support/FormattedStream.h" #include "llvm/Support/RISCVAttributes.h" #include "llvm/TargetParser/RISCVISAInfo.h" @@ -22,7 +25,11 @@ using namespace llvm; RISCVTargetStreamer::RISCVTargetStreamer(MCStreamer &S) : MCTargetStreamer(S) {} -void RISCVTargetStreamer::finish() { finishAttributeSection(); } +void RISCVTargetStreamer::finish() { + finishAttributeSection(); + emitGNUProgramProperties(); +} + void RISCVTargetStreamer::reset() {} void RISCVTargetStreamer::emitDirectiveOptionPush() {} @@ -52,6 +59,9 @@ void RISCVTargetStreamer::setFlagsFromFeatures(const MCSubtargetInfo &STI) { HasRVC = STI.hasFeature(RISCV::FeatureStdExtC) || STI.hasFeature(RISCV::FeatureStdExtZca); HasTSO = STI.hasFeature(RISCV::FeatureStdExtZtso); + HasZicfilp = STI.hasFeature(RISCV::FeatureStdExtZicfilp); + HasZicfiss = STI.hasFeature(RISCV::FeatureStdExtZicfiss); + IsRV64 = STI.hasFeature(RISCV::Feature64Bit); } void RISCVTargetStreamer::emitTargetAttributes(const MCSubtargetInfo &STI, @@ -77,6 +87,47 @@ void RISCVTargetStreamer::emitTargetAttributes(const MCSubtargetInfo &STI, } } +void RISCVTargetStreamer::emitGNUProgramProperties() { + unsigned FeatureAndFlags = 0; + // Check Zicfilp or Zicfiss with features + // TODO should we check with codegen enable + // ex. -mllvm -riscv-hardware-shadow-stack=true ? + if (hasZicfilp()) + FeatureAndFlags |= ELF::GNU_PROPERTY_RISCV_FEATURE_1_CFI_LP_SIMPLE; + + if (hasZicfiss()) + FeatureAndFlags |= ELF::GNU_PROPERTY_RISCV_FEATURE_1_CFI_SS; + + if (FeatureAndFlags == 0) + return; + + MCStreamer &OutStreamer = getStreamer(); + MCContext &Context = OutStreamer.getContext(); + MCSectionELF *Nt = Context.getELFSection(".note.gnu.property", ELF::SHT_NOTE, + ELF::SHF_ALLOC); + MCSection *Cur = OutStreamer.getCurrentSectionOnly(); + OutStreamer.switchSection(Nt); + + // Emit the note header. + uint64_t DataSize = isRV64() ? 4 : 3; + OutStreamer.emitValueToAlignment(isRV64() ? Align(8) : Align(4)); + OutStreamer.emitIntValue(4, 4); // data size for note name + OutStreamer.emitIntValue(4 * DataSize, 4); // data size + OutStreamer.emitIntValue(ELF::NT_GNU_PROPERTY_TYPE_0, 4); // note type + OutStreamer.emitBytes(StringRef("GNU", 4)); // note name + + // Emit the CFI(Zicfilp/Zicfiss) properties. + OutStreamer.emitIntValue(ELF::GNU_PROPERTY_RISCV_FEATURE_1_AND, + 4); // and property + OutStreamer.emitIntValue(4, 4); // data size + OutStreamer.emitIntValue(FeatureAndFlags, 4); // data + if (isRV64()) + OutStreamer.emitIntValue(0, 4); // Padding + + OutStreamer.endSection(Nt); + OutStreamer.switchSection(Cur); +} + // This part is for ascii assembly output RISCVTargetAsmStreamer::RISCVTargetAsmStreamer(MCStreamer &S, formatted_raw_ostream &OS) diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVTargetStreamer.h b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVTargetStreamer.h index cb8bc21cb6355..0f3a3e501cfe2 100644 --- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVTargetStreamer.h +++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVTargetStreamer.h @@ -35,6 +35,9 @@ class RISCVTargetStreamer : public MCTargetStreamer { RISCVABI::ABI TargetABI = RISCVABI::ABI_Unknown; bool HasRVC = false; bool HasTSO = false; + bool HasZicfilp = false; + bool HasZicfiss = false; + bool IsRV64 = false; public: RISCVTargetStreamer(MCStreamer &S); @@ -58,11 +61,15 @@ class RISCVTargetStreamer : public MCTargetStreamer { StringRef StringValue); void emitTargetAttributes(const MCSubtargetInfo &STI, bool EmitStackAlign); + void emitGNUProgramProperties(); void setTargetABI(RISCVABI::ABI ABI); RISCVABI::ABI getTargetABI() const { return TargetABI; } void setFlagsFromFeatures(const MCSubtargetInfo &STI); bool hasRVC() const { return HasRVC; } bool hasTSO() const { return HasTSO; } + bool hasZicfilp() const { return HasZicfilp; } + bool hasZicfiss() const { return HasZicfiss; } + bool isRV64() const { return IsRV64; } }; // This part is for ascii assembly output diff --git a/llvm/test/tools/llvm-readobj/ELF/RISCV/riscv-cfi-property.s b/llvm/test/tools/llvm-readobj/ELF/RISCV/riscv-cfi-property.s new file mode 100644 index 0000000000000..865532196c4d0 --- /dev/null +++ b/llvm/test/tools/llvm-readobj/ELF/RISCV/riscv-cfi-property.s @@ -0,0 +1,78 @@ +# RUN: rm -rf %t && split-file %s %t && cd %t + +#--- gnu-property-riscv32.s +// RUN: llvm-mc -triple riscv32 -filetype obj gnu-property-riscv32.s -o gnu-property-riscv32.o +// RUN: llvm-readobj -n gnu-property-riscv32.o | FileCheck -check-prefix=LLVM gnu-property-riscv32.s +// RUN: llvm-readobj -n --elf-output-style=GNU gnu-property-riscv32.o | FileCheck -check-prefix=GNU gnu-property-riscv32.s + + +// LLVM: Notes [ +// LLVM-NEXT: NoteSection { +// LLVM-NEXT: Name: .note.gnu.property +// LLVM-NEXT: Offset: 0x34 +// LLVM-NEXT: Size: 0x1C +// LLVM-NEXT: Note { +// LLVM-NEXT: Owner: GNU +// LLVM-NEXT: Data size: 0xC +// LLVM-NEXT: Type: NT_GNU_PROPERTY_TYPE_0 (property note) +// LLVM-NEXT: Property [ +// LLVM-NEXT: riscv feature: Zicfilp, Zicfiss +// LLVM-NEXT: ] +// LLVM-NEXT: } +// LLVM-NEXT: } +// LLVM-NEXT: ] + +// GNU: Displaying notes found in: .note.gnu.property +// GNU-NEXT: Owner Data size Description +// GNU-NEXT: GNU 0x0000000c NT_GNU_PROPERTY_TYPE_0 (property note) +// GNU-NEXT: Properties: riscv feature: Zicfilp, Zicfiss + +// GNU Note Section Example +.section .note.gnu.property, "a" + .p2align 2 + .long 4 + .long 12; + .long 5 + .asciz "GNU" + .long 0xc0000000 + .long 4 + .long 3 + +#--- gnu-property-riscv64.s +// RUN: llvm-mc -triple riscv64 -filetype obj gnu-property-riscv64.s -o gnu-property-riscv64.o +// RUN: llvm-readobj -n gnu-property-riscv64.o | FileCheck -check-prefix=LLVM64 gnu-property-riscv64.s +// RUN: llvm-readobj -n --elf-output-style=GNU gnu-property-riscv64.o | FileCheck -check-prefix=GNU64 gnu-property-riscv64.s + + +// LLVM64: Notes [ +// LLVM64-NEXT: NoteSection { +// LLVM64-NEXT: Name: .note.gnu.property +// LLVM64-NEXT: Offset: 0x40 +// LLVM64-NEXT: Size: 0x20 +// LLVM64-NEXT: Note { +// LLVM64-NEXT: Owner: GNU +// LLVM64-NEXT: Data size: 0x10 +// LLVM64-NEXT: Type: NT_GNU_PROPERTY_TYPE_0 (property note) +// LLVM64-NEXT: Property [ +// LLVM64-NEXT: riscv feature: Zicfilp, Zicfiss +// LLVM64-NEXT: ] +// LLVM64-NEXT: } +// LLVM64-NEXT: } +// LLVM64-NEXT: ] + +// GNU64: Displaying notes found in: .note.gnu.property +// GNU64-NEXT: Owner Data size Description +// GNU64-NEXT: GNU 0x00000010 NT_GNU_PROPERTY_TYPE_0 (property note) +// GNU64-NEXT: Properties: riscv feature: Zicfilp, Zicfiss + +// GNU Note Section Example +.section .note.gnu.property, "a" + .p2align 2 + .long 4 + .long 16; + .long 5 + .asciz "GNU" + .long 0xc0000000 + .long 4 + .long 3 + .long 0 diff --git a/llvm/tools/llvm-readobj/ELFDumper.cpp b/llvm/tools/llvm-readobj/ELFDumper.cpp index a752cc4015293..096fdf58bacac 100644 --- a/llvm/tools/llvm-readobj/ELFDumper.cpp +++ b/llvm/tools/llvm-readobj/ELFDumper.cpp @@ -5239,7 +5239,7 @@ static bool printAArch64PAuthABICoreInfo(raw_ostream &OS, uint32_t DataSize, template static std::string getGNUProperty(uint32_t Type, uint32_t DataSize, - ArrayRef Data) { + ArrayRef Data, unsigned EMachine) { std::string str; raw_string_ostream OS(str); uint32_t PrData; @@ -5272,8 +5272,19 @@ static std::string getGNUProperty(uint32_t Type, uint32_t DataSize, return OS.str(); case GNU_PROPERTY_AARCH64_FEATURE_1_AND: case GNU_PROPERTY_X86_FEATURE_1_AND: - OS << ((Type == GNU_PROPERTY_AARCH64_FEATURE_1_AND) ? "aarch64 feature: " - : "x86 feature: "); + if (Type == GNU_PROPERTY_AARCH64_FEATURE_1_AND) { + static_assert( + GNU_PROPERTY_AARCH64_FEATURE_1_AND == + GNU_PROPERTY_RISCV_FEATURE_1_AND, + "AARCH64 and RISCV have different FEATURE_1_AND property type"); + if (EMachine == ELF::EM_RISCV) + OS << "riscv feature: "; + else + OS << "aarch64 feature: "; + } else { + OS << "x86 feature: "; + } + if (DataSize != 4) { OS << format("", DataSize); return OS.str(); @@ -5283,14 +5294,21 @@ static std::string getGNUProperty(uint32_t Type, uint32_t DataSize, OS << ""; return OS.str(); } + if (Type == GNU_PROPERTY_AARCH64_FEATURE_1_AND) { - DumpBit(GNU_PROPERTY_AARCH64_FEATURE_1_BTI, "BTI"); - DumpBit(GNU_PROPERTY_AARCH64_FEATURE_1_PAC, "PAC"); - DumpBit(GNU_PROPERTY_AARCH64_FEATURE_1_GCS, "GCS"); + if (EMachine == ELF::EM_RISCV) { + DumpBit(GNU_PROPERTY_RISCV_FEATURE_1_CFI_LP_SIMPLE, "Zicfilp"); + DumpBit(GNU_PROPERTY_RISCV_FEATURE_1_CFI_SS, "Zicfiss"); + } else { + DumpBit(GNU_PROPERTY_AARCH64_FEATURE_1_BTI, "BTI"); + DumpBit(GNU_PROPERTY_AARCH64_FEATURE_1_PAC, "PAC"); + DumpBit(GNU_PROPERTY_AARCH64_FEATURE_1_GCS, "GCS"); + } } else { DumpBit(GNU_PROPERTY_X86_FEATURE_1_IBT, "IBT"); DumpBit(GNU_PROPERTY_X86_FEATURE_1_SHSTK, "SHSTK"); } + if (PrData) OS << format("", PrData); return OS.str(); @@ -5347,7 +5365,8 @@ static std::string getGNUProperty(uint32_t Type, uint32_t DataSize, } template -static SmallVector getGNUPropertyList(ArrayRef Arr) { +static SmallVector getGNUPropertyList(ArrayRef Arr, + unsigned EMachine) { using Elf_Word = typename ELFT::Word; SmallVector Properties; @@ -5365,8 +5384,8 @@ static SmallVector getGNUPropertyList(ArrayRef Arr) { Properties.push_back(OS.str()); break; } - Properties.push_back( - getGNUProperty(Type, DataSize, Arr.take_front(PaddedSize))); + Properties.push_back(getGNUProperty( + Type, DataSize, Arr.take_front(PaddedSize), EMachine)); Arr = Arr.drop_front(PaddedSize); } @@ -5418,7 +5437,7 @@ static StringRef getDescAsStringRef(ArrayRef Desc) { template static bool printGNUNote(raw_ostream &OS, uint32_t NoteType, - ArrayRef Desc) { + ArrayRef Desc, unsigned EMachine) { // Return true if we were able to pretty-print the note, false otherwise. switch (NoteType) { default: @@ -5440,7 +5459,7 @@ static bool printGNUNote(raw_ostream &OS, uint32_t NoteType, break; case ELF::NT_GNU_PROPERTY_TYPE_0: OS << " Properties:"; - for (const std::string &Property : getGNUPropertyList(Desc)) + for (const std::string &Property : getGNUPropertyList(Desc, EMachine)) OS << " " << Property << "\n"; break; } @@ -6130,7 +6149,8 @@ template void GNUELFDumper::printNotes() { // Print the description, or fallback to printing raw bytes for unknown // owners/if we fail to pretty-print the contents. if (Name == "GNU") { - if (printGNUNote(OS, Type, Descriptor)) + if (printGNUNote(OS, Type, Descriptor, + this->Obj.getHeader().e_machine)) return Error::success(); } else if (Name == "FreeBSD") { if (std::optional N = @@ -7746,7 +7766,7 @@ template void LLVMELFDumper::printAddrsig() { template static bool printGNUNoteLLVMStyle(uint32_t NoteType, ArrayRef Desc, - ScopedPrinter &W) { + ScopedPrinter &W, unsigned EMachine) { // Return true if we were able to pretty-print the note, false otherwise. switch (NoteType) { default: @@ -7771,7 +7791,7 @@ static bool printGNUNoteLLVMStyle(uint32_t NoteType, ArrayRef Desc, break; case ELF::NT_GNU_PROPERTY_TYPE_0: ListScope D(W, "Property"); - for (const std::string &Property : getGNUPropertyList(Desc)) + for (const std::string &Property : getGNUPropertyList(Desc, EMachine)) W.printString(Property); break; } @@ -7887,7 +7907,8 @@ template void LLVMELFDumper::printNotes() { // Print the description, or fallback to printing raw bytes for unknown // owners/if we fail to pretty-print the contents. if (Name == "GNU") { - if (printGNUNoteLLVMStyle(Type, Descriptor, W)) + if (printGNUNoteLLVMStyle(Type, Descriptor, W, + this->Obj.getHeader().e_machine)) return Error::success(); } else if (Name == "FreeBSD") { if (std::optional N =