Skip to content

Commit 84eb7d2

Browse files
kito-chengNelson Chu
authored andcommitted
RISC-V: Implment the merge logic for GNU_PROPERTY_RISCV_FEATURE_1_AND
GNU_PROPERTY_RISCV_FEATURE_1_AND will perform a bitwise AND operation on the properties of the input files.
1 parent 4ad5217 commit 84eb7d2

15 files changed

+383
-0
lines changed

bfd/elfnn-riscv.c

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,8 @@ struct _bfd_riscv_elf_obj_tdata
177177
/* tls_type for each local got entry. */
178178
char *local_got_tls_type;
179179

180+
/* All GNU_PROPERTY_RISCV_FEATURE_1_AND properties. */
181+
uint32_t gnu_and_prop;
180182
/* PLT type. */
181183
riscv_plt_type plt_type;
182184
};
@@ -5809,6 +5811,36 @@ riscv_elf_merge_symbol_attribute (struct elf_link_hash_entry *h,
58095811
h->other |= STO_RISCV_VARIANT_CC;
58105812
}
58115813

5814+
/* Implement elf_backend_setup_gnu_properties for RISC-V. It serves as a
5815+
wrapper function for _bfd_riscv_elf_link_setup_gnu_properties to account
5816+
for the effect of GNU properties of the output_bfd. */
5817+
5818+
static bfd *
5819+
elfNN_riscv_link_setup_gnu_properties (struct bfd_link_info *info)
5820+
{
5821+
uint32_t and_prop = _bfd_riscv_elf_tdata (info->output_bfd)->gnu_and_prop;
5822+
5823+
bfd *pbfd = _bfd_riscv_elf_link_setup_gnu_properties (info, &and_prop);
5824+
5825+
_bfd_riscv_elf_tdata (info->output_bfd)->gnu_and_prop = and_prop;
5826+
return pbfd;
5827+
}
5828+
5829+
/* Implement elf_backend_merge_gnu_properties for RISC-V. It serves as a
5830+
wrapper function for _bfd_riscv_elf_merge_gnu_properties to account
5831+
for the effect of GNU properties of the output_bfd. */
5832+
5833+
static bool
5834+
elfNN_riscv_merge_gnu_properties (struct bfd_link_info *info, bfd *abfd,
5835+
bfd *bbfd ATTRIBUTE_UNUSED,
5836+
elf_property *aprop, elf_property *bprop)
5837+
{
5838+
uint32_t and_prop = _bfd_riscv_elf_tdata (info->output_bfd)->gnu_and_prop;
5839+
5840+
return _bfd_riscv_elf_merge_gnu_properties (info, abfd, aprop, bprop,
5841+
and_prop);
5842+
}
5843+
58125844
#define TARGET_LITTLE_SYM riscv_elfNN_vec
58135845
#define TARGET_LITTLE_NAME "elfNN-littleriscv"
58145846
#define TARGET_BIG_SYM riscv_elfNN_be_vec
@@ -5848,6 +5880,9 @@ riscv_elf_merge_symbol_attribute (struct elf_link_hash_entry *h,
58485880

58495881
#define elf_backend_init_index_section _bfd_elf_init_1_index_section
58505882

5883+
#define elf_backend_setup_gnu_properties elfNN_riscv_link_setup_gnu_properties
5884+
#define elf_backend_merge_gnu_properties elfNN_riscv_merge_gnu_properties
5885+
58515886
#define elf_backend_can_gc_sections 1
58525887
#define elf_backend_can_refcount 1
58535888
#define elf_backend_want_got_plt 1

bfd/elfxx-riscv.c

Lines changed: 171 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3366,3 +3366,174 @@ riscv_print_extensions (void)
33663366
}
33673367
printf ("\n");
33683368
}
3369+
3370+
/* Find the first input bfd with GNU property and merge it with GPROP. If no
3371+
such input is found, add it to a new section at the last input. Update
3372+
GPROP accordingly. */
3373+
3374+
bfd *
3375+
_bfd_riscv_elf_link_setup_gnu_properties (struct bfd_link_info *info,
3376+
uint32_t *and_prop_p)
3377+
{
3378+
asection *sec;
3379+
bfd *pbfd;
3380+
bfd *ebfd = NULL;
3381+
elf_property *prop;
3382+
3383+
uint32_t and_prop = *and_prop_p;
3384+
3385+
/* Find a normal input file with GNU property note. */
3386+
for (pbfd = info->input_bfds; pbfd != NULL; pbfd = pbfd->link.next)
3387+
if (bfd_get_flavour (pbfd) == bfd_target_elf_flavour
3388+
&& bfd_count_sections (pbfd) != 0)
3389+
{
3390+
ebfd = pbfd;
3391+
3392+
if (elf_properties (pbfd) != NULL)
3393+
break;
3394+
}
3395+
3396+
/* If ebfd != NULL it is either an input with property note or the last
3397+
input. Either way if we have and_prop, we should add it (by
3398+
creating a section if needed). */
3399+
if (ebfd != NULL && (and_prop))
3400+
{
3401+
prop = _bfd_elf_get_property (ebfd, GNU_PROPERTY_RISCV_FEATURE_1_AND, 4);
3402+
3403+
prop->u.number |= and_prop;
3404+
prop->pr_kind = property_number;
3405+
3406+
/* pbfd being NULL implies ebfd is the last input. Create the GNU
3407+
property note section. */
3408+
if (pbfd == NULL)
3409+
{
3410+
sec
3411+
= bfd_make_section_with_flags (ebfd, NOTE_GNU_PROPERTY_SECTION_NAME,
3412+
(SEC_ALLOC | SEC_LOAD | SEC_IN_MEMORY
3413+
| SEC_READONLY | SEC_HAS_CONTENTS
3414+
| SEC_DATA));
3415+
if (sec == NULL)
3416+
info->callbacks->einfo (
3417+
_ ("%F%P: failed to create GNU property section\n"));
3418+
3419+
elf_section_type (sec) = SHT_NOTE;
3420+
}
3421+
}
3422+
3423+
pbfd = _bfd_elf_link_setup_gnu_properties (info);
3424+
3425+
if (bfd_link_relocatable (info))
3426+
return pbfd;
3427+
3428+
/* If pbfd has any GNU_PROPERTY_RISCV_FEATURE_1_AND properties, update
3429+
and_prop accordingly. */
3430+
if (pbfd != NULL)
3431+
{
3432+
elf_property_list *p;
3433+
elf_property_list *plist = elf_properties (pbfd);
3434+
3435+
if ((p = _bfd_elf_find_property (plist, GNU_PROPERTY_RISCV_FEATURE_1_AND,
3436+
NULL))
3437+
!= NULL)
3438+
and_prop = p->property.u.number
3439+
& (GNU_PROPERTY_RISCV_FEATURE_1_CFI_LP_UNLABELED
3440+
| GNU_PROPERTY_RISCV_FEATURE_1_CFI_SS);
3441+
}
3442+
3443+
*and_prop_p = and_prop;
3444+
return pbfd;
3445+
}
3446+
3447+
/* Define elf_backend_parse_gnu_properties for RISC-V. */
3448+
3449+
enum elf_property_kind
3450+
_bfd_riscv_elf_parse_gnu_properties (bfd *abfd, unsigned int type,
3451+
bfd_byte *ptr, unsigned int datasz)
3452+
{
3453+
elf_property *prop;
3454+
3455+
switch (type)
3456+
{
3457+
case GNU_PROPERTY_RISCV_FEATURE_1_AND:
3458+
if (datasz != 4)
3459+
{
3460+
_bfd_error_handler (_ (
3461+
"error: %pB: <corrupt RISC-V used size: 0x%x>"),
3462+
abfd, datasz);
3463+
return property_corrupt;
3464+
}
3465+
prop = _bfd_elf_get_property (abfd, type, datasz);
3466+
/* Combine properties of the same type. */
3467+
prop->u.number |= bfd_h_get_32 (abfd, ptr);
3468+
prop->pr_kind = property_number;
3469+
break;
3470+
3471+
default:
3472+
return property_ignored;
3473+
}
3474+
3475+
return property_number;
3476+
}
3477+
3478+
/* Merge RISC-V GNU property BPROP with APROP also accounting for PROP.
3479+
If APROP isn't NULL, merge it with BPROP and/or PROP. Vice-versa if BROP
3480+
isn't NULL. Return TRUE if there is any update to APROP or if BPROP should
3481+
be merge with ABFD. */
3482+
3483+
bool
3484+
_bfd_riscv_elf_merge_gnu_properties
3485+
(struct bfd_link_info *info ATTRIBUTE_UNUSED, bfd *abfd ATTRIBUTE_UNUSED,
3486+
elf_property *aprop, elf_property *bprop, uint32_t and_prop)
3487+
{
3488+
unsigned int orig_number;
3489+
bool updated = false;
3490+
unsigned int pr_type = aprop != NULL ? aprop->pr_type : bprop->pr_type;
3491+
3492+
switch (pr_type)
3493+
{
3494+
case GNU_PROPERTY_RISCV_FEATURE_1_AND: {
3495+
if (aprop != NULL && bprop != NULL)
3496+
{
3497+
orig_number = aprop->u.number;
3498+
aprop->u.number = (orig_number & bprop->u.number) | and_prop;
3499+
updated = orig_number != aprop->u.number;
3500+
/* Remove the property if all feature bits are cleared. */
3501+
if (aprop->u.number == 0)
3502+
aprop->pr_kind = property_remove;
3503+
break;
3504+
}
3505+
/* If either is NULL, the AND would be 0 so, if there is
3506+
any PROP, asign it to the input that is not NULL. */
3507+
if (and_prop)
3508+
{
3509+
if (aprop != NULL)
3510+
{
3511+
orig_number = aprop->u.number;
3512+
aprop->u.number = and_prop;
3513+
updated = orig_number != aprop->u.number;
3514+
}
3515+
else if (bprop != NULL)
3516+
{
3517+
bprop->u.number = and_prop;
3518+
updated = true;
3519+
}
3520+
/* Shouldn't happen because we checked one of APROP or BPROP !=
3521+
* NULL. */
3522+
else
3523+
abort ();
3524+
}
3525+
/* No PROP and BPROP is NULL, so remove APROP. */
3526+
else if (!and_prop && bprop == NULL && aprop != NULL)
3527+
{
3528+
aprop->pr_kind = property_remove;
3529+
updated = true;
3530+
}
3531+
}
3532+
break;
3533+
3534+
default:
3535+
abort ();
3536+
}
3537+
3538+
return updated;
3539+
}

bfd/elfxx-riscv.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,3 +133,16 @@ extern void
133133
bfd_elf32_riscv_set_data_segment_info (struct bfd_link_info *, int *);
134134
extern void
135135
bfd_elf64_riscv_set_data_segment_info (struct bfd_link_info *, int *);
136+
137+
extern bfd *
138+
_bfd_riscv_elf_link_setup_gnu_properties (struct bfd_link_info *, uint32_t *);
139+
140+
extern enum elf_property_kind
141+
_bfd_riscv_elf_parse_gnu_properties (bfd *, unsigned int, bfd_byte *,
142+
unsigned int);
143+
144+
extern bool
145+
_bfd_riscv_elf_merge_gnu_properties (struct bfd_link_info *, bfd *,
146+
elf_property *, elf_property *, uint32_t);
147+
148+
#define elf_backend_parse_gnu_properties _bfd_riscv_elf_parse_gnu_properties

ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,12 @@ if [istarget "riscv*-*-*"] {
227227
run_dump_test "data-reloc-rv64-addr32-pic"
228228
run_dump_test "data-reloc-rv64-undef32-pic"
229229

230+
run_dump_test "property-zicfilp-unlabeled"
231+
run_dump_test "property-zicfiss"
232+
run_dump_test "property-combine-and-1"
233+
run_dump_test "property-combine-and-2"
234+
run_dump_test "property-combine-and-3"
235+
230236
# IFUNC testcases.
231237
# Check IFUNC by single type relocs.
232238
run_dump_test_ifunc "ifunc-reloc-call-01" rv32 exe
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
#name: RISC-V GNU Property (multiple inputs, combine section) - 1
2+
#source: property1.s
3+
#source: property2.s
4+
#as: -march=rv64g
5+
#ld: -shared
6+
#readelf: -n
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
#name: RISC-V GNU Property (multiple inputs, combine section) - 2
2+
#source: property1.s
3+
#source: property3.s
4+
#as: -march=rv64g
5+
#ld: -shared
6+
#readelf: -n
7+
8+
Displaying notes found in: .note.gnu.property
9+
[ ]+Owner[ ]+Data size[ ]+Description
10+
[ ]+GNU[ ]+0x00000010[ ]+NT_GNU_PROPERTY_TYPE_0
11+
[ ]+Properties: RISC-V AND feature: CFI_LP_UNLABELED
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
#name: RISC-V GNU Property (multiple inputs, combine section) - 3
2+
#source: property1.s
3+
#source: property4.s
4+
#as: -march=rv64g
5+
#ld: -shared
6+
#readelf: -n
7+
8+
Displaying notes found in: .note.gnu.property
9+
[ ]+Owner[ ]+Data size[ ]+Description
10+
[ ]+GNU[ ]+0x00000010[ ]+NT_GNU_PROPERTY_TYPE_0
11+
[ ]+Properties: RISC-V AND feature: CFI_SS
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
#name: GNU Property (single input, CFI_LP_UNLABELED)
2+
#source: property-zicfilp-unlabeled.s
3+
#as: -march=rv64g
4+
#ld: -shared
5+
#readelf: -n
6+
7+
Displaying notes found in: .note.gnu.property
8+
[ ]+Owner[ ]+Data size[ ]+Description
9+
[ ]+GNU[ ]+0x00000010[ ]+NT_GNU_PROPERTY_TYPE_0
10+
[ ]+Properties: RISC-V AND feature: CFI_LP_UNLABELED
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
.text
2+
.globl _start
3+
.type _start,@function
4+
_start:
5+
ret
6+
7+
.section ".note.gnu.property", "a"
8+
.p2align 3
9+
.long 1f - 0f /* name length */
10+
.long 5f - 2f /* data length */
11+
.long 5 /* note type */
12+
0: .asciz "GNU" /* vendor name */
13+
1:
14+
.p2align 3
15+
2: .long 0xc0000000 /* pr_type. */
16+
.long 4f - 3f /* pr_datasz. */
17+
3:
18+
.long 0x1 /* GNU_PROPERTY_RISCV_FEATURE_1_CFI_LP_UNLABELED. */
19+
4:
20+
.p2align 3
21+
5:
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
#name: GNU Property (single input, CFI_SS)
2+
#source: property-zicfiss.s
3+
#as: -march=rv64g
4+
#ld: -shared
5+
#readelf: -n
6+
7+
Displaying notes found in: .note.gnu.property
8+
[ ]+Owner[ ]+Data size[ ]+Description
9+
[ ]+GNU[ ]+0x00000010[ ]+NT_GNU_PROPERTY_TYPE_0
10+
[ ]+Properties: RISC-V AND feature: CFI_SS

0 commit comments

Comments
 (0)