Ming-Yi Lai 691ca556e0
[RISCV] Emit .note.gnu.property section when Zicfiss-based shadow stack is enabled (#127036)
RISC-V Zicfiss-based shadow stack needs to let the linker/loader know if
the binary is built with the mechanism enabled to support proper
link-time/load-time management of this feature. The information is
encoded as a bit in the `.note.gnu.property` section. This patch
implements emitting the section for RISC-V targets when Zicfiss-based
shadow stack is enabled.

When Clang receives the `-fcf-protection=return` flag, it adds the
`hw-shadow-stack` attribute to LLVM functions, and adds a non-zero
valued attribute named `cf-protection-return` to the LLVM module it
generates. The backend depends on the `hw-shadow-stack` attributes to
generate Zicfiss-based shadow stack instructions for each function, but
at the module scope, the `cf-protection-return` attribute is a better
indication of whether the translation unit is built with Zicfiss-based
shadow stack enabled, so this patch emits the `.note.gnu.property`
section with the "Zicfiss-based shadow stack" bit toggled on when it
sees the `cf-protection-return` attribute.
2025-05-14 11:48:59 +08:00

100 lines
3.4 KiB
C++

//===-- RISCVTargetStreamer.h - RISC-V Target Streamer ---------*- C++ -*--===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_LIB_TARGET_RISCV_MCTARGETDESC_RISCVTARGETSTREAMER_H
#define LLVM_LIB_TARGET_RISCV_MCTARGETDESC_RISCVTARGETSTREAMER_H
#include "RISCV.h"
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCSubtargetInfo.h"
namespace llvm {
class formatted_raw_ostream;
enum class RISCVOptionArchArgType {
Full,
Plus,
Minus,
};
struct RISCVOptionArchArg {
RISCVOptionArchArgType Type;
std::string Value;
RISCVOptionArchArg(RISCVOptionArchArgType Type, std::string Value)
: Type(Type), Value(Value) {}
};
class RISCVTargetStreamer : public MCTargetStreamer {
RISCVABI::ABI TargetABI = RISCVABI::ABI_Unknown;
bool HasRVC = false;
bool HasTSO = false;
public:
RISCVTargetStreamer(MCStreamer &S);
void finish() override;
virtual void reset();
virtual void emitDirectiveOptionArch(ArrayRef<RISCVOptionArchArg> Args);
virtual void emitDirectiveOptionExact();
virtual void emitDirectiveOptionNoExact();
virtual void emitDirectiveOptionPIC();
virtual void emitDirectiveOptionNoPIC();
virtual void emitDirectiveOptionPop();
virtual void emitDirectiveOptionPush();
virtual void emitDirectiveOptionRelax();
virtual void emitDirectiveOptionNoRelax();
virtual void emitDirectiveOptionRVC();
virtual void emitDirectiveOptionNoRVC();
virtual void emitDirectiveVariantCC(MCSymbol &Symbol);
virtual void emitAttribute(unsigned Attribute, unsigned Value);
virtual void finishAttributeSection();
virtual void emitTextAttribute(unsigned Attribute, StringRef String);
virtual void emitIntTextAttribute(unsigned Attribute, unsigned IntValue,
StringRef StringValue);
void emitNoteGnuPropertySection(const uint32_t Feature1And);
void emitTargetAttributes(const MCSubtargetInfo &STI, bool EmitStackAlign);
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; }
};
// This part is for ascii assembly output
class RISCVTargetAsmStreamer : public RISCVTargetStreamer {
formatted_raw_ostream &OS;
void finishAttributeSection() override;
void emitAttribute(unsigned Attribute, unsigned Value) override;
void emitTextAttribute(unsigned Attribute, StringRef String) override;
void emitIntTextAttribute(unsigned Attribute, unsigned IntValue,
StringRef StringValue) override;
public:
RISCVTargetAsmStreamer(MCStreamer &S, formatted_raw_ostream &OS);
void emitDirectiveOptionArch(ArrayRef<RISCVOptionArchArg> Args) override;
void emitDirectiveOptionExact() override;
void emitDirectiveOptionNoExact() override;
void emitDirectiveOptionPIC() override;
void emitDirectiveOptionNoPIC() override;
void emitDirectiveOptionPop() override;
void emitDirectiveOptionPush() override;
void emitDirectiveOptionRelax() override;
void emitDirectiveOptionNoRelax() override;
void emitDirectiveOptionRVC() override;
void emitDirectiveOptionNoRVC() override;
void emitDirectiveVariantCC(MCSymbol &Symbol) override;
};
}
#endif