@@ -430,6 +430,10 @@ static void checkOptions(Ctx &ctx) {
430430 " RISC-V targets" ;
431431 if (ctx.arg .zZicfissReport != ReportPolicy::None)
432432 ErrAlways (ctx) << " -z zicfiss-report is only supported on RISC-V targets" ;
433+ if (ctx.arg .zZicfilp != ZicfilpPolicy::Implicit)
434+ ErrAlways (ctx) << " -z zicfilp is only supported on RISC-V targets" ;
435+ if (ctx.arg .zZicfiss != ZicfissPolicy::Implicit)
436+ ErrAlways (ctx) << " -z zicfiss is only supported on RISC-V targets" ;
433437 }
434438
435439 if (ctx.arg .emachine != EM_386 && ctx.arg .emachine != EM_X86_64 &&
@@ -584,6 +588,46 @@ static GcsPolicy getZGcs(Ctx &ctx, opt::InputArgList &args) {
584588 return ret;
585589}
586590
591+ static ZicfilpPolicy getZZicfilp (Ctx &ctx, opt::InputArgList &args) {
592+ auto ret = ZicfilpPolicy::Implicit;
593+ for (auto *arg : args.filtered (OPT_z)) {
594+ std::pair<StringRef, StringRef> kv = StringRef (arg->getValue ()).split (' =' );
595+ if (kv.first == " zicfilp" ) {
596+ arg->claim ();
597+ if (kv.second == " unlabeled" )
598+ ret = ZicfilpPolicy::Unlabeled;
599+ else if (kv.second == " func-sig" )
600+ ret = ZicfilpPolicy::FuncSig;
601+ else if (kv.second == " never" )
602+ ret = ZicfilpPolicy::Never;
603+ else if (kv.second == " implicit" )
604+ ret = ZicfilpPolicy::Implicit;
605+ else
606+ ErrAlways (ctx) << " unknown -z zicfilp= value: " << kv.second ;
607+ }
608+ }
609+ return ret;
610+ }
611+
612+ static ZicfissPolicy getZZicfiss (Ctx &ctx, opt::InputArgList &args) {
613+ auto ret = ZicfissPolicy::Implicit;
614+ for (auto *arg : args.filtered (OPT_z)) {
615+ std::pair<StringRef, StringRef> kv = StringRef (arg->getValue ()).split (' =' );
616+ if (kv.first == " zicfiss" ) {
617+ arg->claim ();
618+ if (kv.second == " always" )
619+ ret = ZicfissPolicy::Always;
620+ else if (kv.second == " never" )
621+ ret = ZicfissPolicy::Never;
622+ else if (kv.second == " implicit" )
623+ ret = ZicfissPolicy::Implicit;
624+ else
625+ ErrAlways (ctx) << " unknown -z zicfiss= value: " << kv.second ;
626+ }
627+ }
628+ return ret;
629+ }
630+
587631// Report a warning for an unknown -z option.
588632static void checkZOptions (Ctx &ctx, opt::InputArgList &args) {
589633 // This function is called before getTarget(), when certain options are not
@@ -1567,6 +1611,8 @@ static void readConfigs(Ctx &ctx, opt::InputArgList &args) {
15671611 ctx.arg .zCopyreloc = getZFlag (args, " copyreloc" , " nocopyreloc" , true );
15681612 ctx.arg .zForceBti = hasZOption (args, " force-bti" );
15691613 ctx.arg .zForceIbt = hasZOption (args, " force-ibt" );
1614+ ctx.arg .zZicfilp = getZZicfilp (ctx, args);
1615+ ctx.arg .zZicfiss = getZZicfiss (ctx, args);
15701616 ctx.arg .zGcs = getZGcs (ctx, args);
15711617 ctx.arg .zGlobal = hasZOption (args, " global" );
15721618 ctx.arg .zGnustack = getZGnuStack (args);
@@ -2926,6 +2972,18 @@ static void readSecurityNotes(Ctx &ctx) {
29262972 << f
29272973 << " : -z zicfiss-report: file does not have "
29282974 " GNU_PROPERTY_RISCV_FEATURE_1_CFI_SS property" ;
2975+
2976+ if (ctx.arg .zZicfilp == ZicfilpPolicy::Unlabeled &&
2977+ (features & GNU_PROPERTY_RISCV_FEATURE_1_CFI_LP_FUNC_SIG))
2978+ Warn (ctx) << f
2979+ << " : -z zicfilp=unlabeled: file has conflicting property: "
2980+ " GNU_PROPERTY_RISCV_FEATURE_1_CFI_LP_FUNC_SIG" ;
2981+
2982+ if (ctx.arg .zZicfilp == ZicfilpPolicy::FuncSig &&
2983+ (features & GNU_PROPERTY_RISCV_FEATURE_1_CFI_LP_UNLABELED))
2984+ Warn (ctx) << f
2985+ << " : -z zicfilp=func-sig: file has conflicting property: "
2986+ " GNU_PROPERTY_RISCV_FEATURE_1_CFI_LP_UNLABELED" ;
29292987 }
29302988
29312989 if (ctx.arg .zForceBti && !(features & GNU_PROPERTY_AARCH64_FEATURE_1_BTI)) {
@@ -2989,6 +3047,25 @@ static void readSecurityNotes(Ctx &ctx) {
29893047 else if (ctx.arg .zGcs == GcsPolicy::Never)
29903048 ctx.arg .andFeatures &= ~GNU_PROPERTY_AARCH64_FEATURE_1_GCS;
29913049
3050+ if (ctx.arg .emachine == EM_RISCV) {
3051+ // Force enable/disable Zicfilp.
3052+ if (ctx.arg .zZicfilp == ZicfilpPolicy::Unlabeled) {
3053+ ctx.arg .andFeatures |= GNU_PROPERTY_RISCV_FEATURE_1_CFI_LP_UNLABELED;
3054+ ctx.arg .andFeatures &= ~GNU_PROPERTY_RISCV_FEATURE_1_CFI_LP_FUNC_SIG;
3055+ } else if (ctx.arg .zZicfilp == ZicfilpPolicy::FuncSig) {
3056+ ctx.arg .andFeatures |= GNU_PROPERTY_RISCV_FEATURE_1_CFI_LP_FUNC_SIG;
3057+ ctx.arg .andFeatures &= ~GNU_PROPERTY_RISCV_FEATURE_1_CFI_LP_UNLABELED;
3058+ } else if (ctx.arg .zZicfilp == ZicfilpPolicy::Never)
3059+ ctx.arg .andFeatures &= ~(GNU_PROPERTY_RISCV_FEATURE_1_CFI_LP_UNLABELED |
3060+ GNU_PROPERTY_RISCV_FEATURE_1_CFI_LP_FUNC_SIG);
3061+
3062+ // Force enable/disable Zicfiss.
3063+ if (ctx.arg .zZicfiss == ZicfissPolicy::Always)
3064+ ctx.arg .andFeatures |= GNU_PROPERTY_RISCV_FEATURE_1_CFI_SS;
3065+ else if (ctx.arg .zZicfiss == ZicfissPolicy::Never)
3066+ ctx.arg .andFeatures &= ~GNU_PROPERTY_RISCV_FEATURE_1_CFI_SS;
3067+ }
3068+
29923069 // If we are utilising GCS at any stage, the sharedFiles should be checked to
29933070 // ensure they also support this feature. The gcs-report-dynamic option is
29943071 // used to indicate if the user wants information relating to this, and will
0 commit comments