Skip to content

Commit

Permalink
SiFive: Add -z force-zicfilp option
Browse files Browse the repository at this point in the history
  • Loading branch information
hau-hsu committed Nov 21, 2023
1 parent fbe2b10 commit ce77d76
Show file tree
Hide file tree
Showing 7 changed files with 121 additions and 3 deletions.
49 changes: 49 additions & 0 deletions bfd/elfnn-riscv.c
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,13 @@ struct _bfd_riscv_elf_obj_tdata

/* All GNU_PROPERTY_RISCV_FEATURE_2_OR properties. */
uint32_t gnu_or_prop;

/* True to warn when linking objects with incompatible
GNU_PROPERTY_RISCV_FEATURE_1_ZICFILP. */
bool zicfilp_warn;

/* PLT type based on security. */
riscv_plt_type plt_type;
};

#define _bfd_riscv_elf_tdata(abfd) \
Expand Down Expand Up @@ -265,9 +272,22 @@ void
riscv_elfNN_set_options (struct bfd_link_info *link_info,
struct riscv_elf_params *params)
{
struct bfd *output_bfd = link_info->output_bfd;
riscv_elf_hash_table (link_info)->params = params;
switch (params->plt_type)
{
case PLT_ZICFILP:
_bfd_riscv_elf_tdata (output_bfd)->zicfilp_warn = true;
_bfd_riscv_elf_tdata (output_bfd)->gnu_and_prop
|= GNU_PROPERTY_RISCV_FEATURE_1_ZICFILP;
break;

default:
break;
}
}


static bool
riscv_info_to_howto_rela (bfd *abfd,
arelent *cache_ptr,
Expand Down Expand Up @@ -5544,6 +5564,21 @@ elfNN_riscv_link_setup_gnu_properties (struct bfd_link_info *info)
return pbfd;
}

/* Warn Zicfilp when -z force-zicfilp is enabled but the bfd doesn't have
the property in NOTE. */
static void
riscv_warn_zicfilp_if_necessary(const elf_property* prop, const bfd *abfd)
{
if ((prop && !(prop->u.number & GNU_PROPERTY_RISCV_FEATURE_1_ZICFILP))
|| !prop)
{
_bfd_error_handler (_("%pB: warning: Zicfilp turned on by -z force-zicfilp when "
"all inputs do not have ZICFILP in NOTE section."),
abfd);
}
}


/* Implement elf_backend_merge_gnu_properties for RISC-V. It serves as a
wrapper function for _bfd_riscv_elf_merge_gnu_properties to account
for the effect of GNU properties of the output_bfd. */
Expand All @@ -5555,6 +5590,20 @@ elfNN_riscv_merge_gnu_properties (struct bfd_link_info *info,
{
uint32_t and_prop
= _bfd_riscv_elf_tdata (info->output_bfd)->gnu_and_prop;

/* If output has been marked with CFILP using command line argument, give out
warning if necessary. */
/* Properties are merged per type, hence only check for warnings when merging
GNU_PROPERTY_RISCV_FEATURE_1_ZICFILP. */
if (((aprop && aprop->pr_type == GNU_PROPERTY_RISCV_FEATURE_1_AND)
|| (bprop && bprop->pr_type == GNU_PROPERTY_RISCV_FEATURE_1_AND))
&& (and_prop & GNU_PROPERTY_RISCV_FEATURE_1_ZICFILP)
&& (_bfd_riscv_elf_tdata (info->output_bfd)->zicfilp_warn))
{
riscv_warn_zicfilp_if_necessary(aprop, abfd);
riscv_warn_zicfilp_if_necessary(bprop, bbfd);
}

uint32_t or_prop
= _bfd_riscv_elf_tdata (info->output_bfd)->gnu_or_prop;
return _bfd_riscv_elf_merge_gnu_properties (info, abfd, aprop,
Expand Down
14 changes: 11 additions & 3 deletions bfd/elfxx-riscv.c
Original file line number Diff line number Diff line change
Expand Up @@ -2777,11 +2777,19 @@ _bfd_riscv_elf_link_setup_gnu_properties (struct bfd_link_info *info,
if (ebfd != NULL && (and_prop || or_prop))
{
prop = _bfd_elf_get_property (ebfd,
GNU_PROPERTY_RISCV_FEATURE_1_AND,
4);
GNU_PROPERTY_RISCV_FEATURE_1_AND,
4);

if (and_prop & GNU_PROPERTY_RISCV_FEATURE_1_ZICFILP
&& !(prop->u.number & GNU_PROPERTY_RISCV_FEATURE_1_ZICFILP))
{
_bfd_error_handler (_("%pB: warning: Zicfilp turned on by -z force-zicfilp "
"when all inputs do not have ZICFILP in NOTE "
"section."), ebfd);
}

prop->u.number |= and_prop;
prop->pr_kind = property_number;

prop = _bfd_elf_get_property (ebfd,
GNU_PROPERTY_RISCV_FEATURE_2_OR,
4);
Expand Down
15 changes: 15 additions & 0 deletions bfd/elfxx-riscv.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,25 @@

#define RISCV_UNKNOWN_VERSION -1

typedef enum
{
PLT_NORMAL = 0x0, /* Normal plts. */
PLT_ZICFILP = 0x1 /* Landing pad plts. */
} riscv_plt_type;

/* To indicate if LP is enabled with/without warning. */
typedef enum
{
ZICFILP_NONE = 0, /* LP is not enabled. */
ZICFILP_WARN = 1, /* LP is enabled with -z force-zicfilp. */
} riscv_enable_zicfilp_type;

struct riscv_elf_params
{
/* Whether to relax code sequences to GP-relative addressing. */
bool relax_gp;
riscv_plt_type plt_type;
riscv_enable_zicfilp_type zicfilp_type;
};

extern void riscv_elf32_set_options (struct bfd_link_info *,
Expand Down
11 changes: 11 additions & 0 deletions ld/emultempl/riscvelf.em
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,19 @@ PARSE_AND_LIST_LONGOPTS=${PARSE_AND_LIST_LONGOPTS}'
PARSE_AND_LIST_OPTIONS=${PARSE_AND_LIST_OPTIONS}'
fprintf (file, _(" --relax-gp Perform GP relaxation\n"));
fprintf (file, _(" --no-relax-gp Don'\''t perform GP relaxation\n"));
fprintf (file, _(" -z force-zicfilp Turn on Zicfilp mechanism and generate PLTs with landing pad. Generate warnings for missing Zicfilp on inputs\n\n"));
'

PARSE_AND_LIST_ARGS_CASE_Z_RISCV='
else if (strcmp (optarg, "force-zicfilp") == 0)
{
params.plt_type |= PLT_ZICFILP;
params.zicfilp_type = ZICFILP_WARN;
}
'
PARSE_AND_LIST_ARGS_CASE_Z="$PARSE_AND_LIST_ARGS_CASE_Z $PARSE_AND_LIST_ARGS_CASE_Z_RISCV"


PARSE_AND_LIST_ARGS_CASES=${PARSE_AND_LIST_ARGS_CASES}'
case OPTION_RELAX_GP:
params.relax_gp = 1;
Expand Down
2 changes: 2 additions & 0 deletions ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,8 @@ if [istarget "riscv*-*-*"] {
run_dump_test "property-zicfilp"
run_dump_test "property-zicfiss"
run_dump_test "property-combine-and-1"
run_dump_test "property-force-zicfilp"
run_dump_test "property-force-zicfilp-all-missing"

# IFUNC testcases.
# Check IFUNC by single type relocs.
Expand Down
16 changes: 16 additions & 0 deletions ld/testsuite/ld-riscv-elf/property-force-zicfilp-all-missing.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#name: Warn with all missing GNU NOTE Zicfilp input
#source: property1.s
#source: property2.s
#as: -mabi=lp64
#ld: -shared -z force-zicfilp
#warning: .*: warning: Zicfilp turned on by -z force-zicfilp.*$
#readelf: -n

# Should warn about the missing input ZICFILP NOTE but should
# still mark output as ZICFILP

Displaying notes found in: .note.gnu.property
[ ]+Owner[ ]+Data size[ ]+Description
[ ]+GNU[ ]+0x00000020[ ]+NT_GNU_PROPERTY_TYPE_0
[ ]+Properties: RISC-V AND feature: ZICFILP
[ ]+RISC-V OR feature:
17 changes: 17 additions & 0 deletions ld/testsuite/ld-riscv-elf/property-force-zicfilp.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#name: Warn with one missing GNU NOTE Zicfilp input
#source: property1.s
#source: property2.s
#as: -mabi=lp64 -defsym __property_zicfilp__=1 -defsym __property_zicfiss__=1
#ld: -shared -z force-zicfilp
#warning: .*: warning: Zicfilp turned on by -z force-zicfilp.*$
#readelf: -n

# Should warn about the missing input ZICFILP NOTE but should
# still mark output as ZICFILP

Displaying notes found in: .note.gnu.property
[ ]+Owner[ ]+Data size[ ]+Description
[ ]+GNU[ ]+0x00000020[ ]+NT_GNU_PROPERTY_TYPE_0
[ ]+Properties: RISC-V AND feature: ZICFILP
[ ]+RISC-V OR feature: ZICFISS

0 comments on commit ce77d76

Please sign in to comment.