@@ -764,11 +764,9 @@ _bfd_aarch64_report_summary_merge_issues (struct bfd_link_info *info)
764
764
{
765
765
const struct elf_aarch64_obj_tdata * tdata
766
766
= elf_aarch64_tdata (info -> output_bfd );
767
- aarch64_feature_marking_report bti_report = tdata -> sw_protections .bti_report ;
768
- aarch64_feature_marking_report gcs_report = tdata -> sw_protections .gcs_report ;
769
767
770
768
if (tdata -> n_bti_issues > GNU_PROPERTY_ISSUES_MAX
771
- && bti_report != MARKING_NONE )
769
+ && tdata -> sw_protections . bti_report != MARKING_NONE )
772
770
{
773
771
const char * msg
774
772
= (tdata -> sw_protections .bti_report == MARKING_ERROR )
@@ -780,7 +778,7 @@ _bfd_aarch64_report_summary_merge_issues (struct bfd_link_info *info)
780
778
}
781
779
782
780
if (tdata -> n_gcs_issues > GNU_PROPERTY_ISSUES_MAX
783
- && gcs_report != MARKING_NONE )
781
+ && tdata -> sw_protections . gcs_report != MARKING_NONE )
784
782
{
785
783
const char * msg
786
784
= (tdata -> sw_protections .gcs_report == MARKING_ERROR )
@@ -790,6 +788,71 @@ _bfd_aarch64_report_summary_merge_issues (struct bfd_link_info *info)
790
788
"GCS requirements.\n" );
791
789
info -> callbacks -> einfo (msg , tdata -> n_gcs_issues );
792
790
}
791
+
792
+ if (tdata -> n_gcs_dynamic_issues > GNU_PROPERTY_ISSUES_MAX
793
+ && tdata -> sw_protections .gcs_report_dynamic != MARKING_NONE )
794
+ {
795
+ const char * msg
796
+ = (tdata -> sw_protections .gcs_report_dynamic == MARKING_ERROR )
797
+ ? _ ("%Xerror: found a total of %d dynamically-linked objects "
798
+ "incompatible with GCS requirements.\n" )
799
+ : _ ("warning: found a total of %d dynamically-linked objects "
800
+ "incompatible with GCS requirements.\n" );
801
+ info -> callbacks -> einfo (msg , tdata -> n_gcs_dynamic_issues );
802
+ }
803
+ }
804
+
805
+ /* Perform a look-up of a property in an unsorted list of properties. This is
806
+ useful when the list of properties of an object has not been sorted yet. */
807
+ static uint32_t
808
+ _bfd_aarch64_prop_linear_lookup (elf_property_list * properties ,
809
+ unsigned int pr_type )
810
+ {
811
+ for (elf_property_list * p = properties ; p != NULL ; p = p -> next )
812
+ if (p -> property .pr_type == pr_type )
813
+ return p -> property .u .number ;
814
+ return 0 ;
815
+ }
816
+
817
+ /* Compare the GNU properties of the current dynamic object, with the ones of
818
+ the output BFD. Today, we only care about GCS feature stored in
819
+ GNU_PROPERTY_AARCH64_FEATURE_1. */
820
+ static void
821
+ _bfd_aarch64_compare_dynamic_obj_prop_against_outprop (
822
+ struct bfd_link_info * info ,
823
+ const uint32_t outprop ,
824
+ bfd * pbfd )
825
+ {
826
+ if (!(outprop & GNU_PROPERTY_AARCH64_FEATURE_1_GCS ))
827
+ return ;
828
+
829
+ const uint32_t dyn_obj_aarch64_feature_prop =
830
+ _bfd_aarch64_prop_linear_lookup (elf_properties (pbfd ),
831
+ GNU_PROPERTY_AARCH64_FEATURE_1_AND );
832
+ if (!(dyn_obj_aarch64_feature_prop & GNU_PROPERTY_AARCH64_FEATURE_1_GCS ))
833
+ _bfd_aarch64_elf_check_gcs_report (info , pbfd );
834
+ }
835
+
836
+ /* Check compatibility between the GNU properties of the ouput BFD and the
837
+ linked dynamic objects. */
838
+ static void
839
+ _bfd_aarch64_elf_check_gnu_properties_linked_dynamic_objects (
840
+ struct bfd_link_info * info ,
841
+ const uint32_t outprop )
842
+ {
843
+ const struct elf_backend_data * bed = get_elf_backend_data (info -> output_bfd );
844
+ const int elf_machine_code = bed -> elf_machine_code ;
845
+ const unsigned int elfclass = bed -> s -> elfclass ;
846
+
847
+ for (bfd * pbfd = info -> input_bfds ; pbfd != NULL ; pbfd = pbfd -> link .next )
848
+ /* Ignore GNU properties from non-ELF objects or ELF objects with different
849
+ machine code. */
850
+ if ((pbfd -> flags & DYNAMIC ) != 0
851
+ && (bfd_get_flavour (pbfd ) == bfd_target_elf_flavour )
852
+ && (get_elf_backend_data (pbfd )-> elf_machine_code == elf_machine_code )
853
+ && (get_elf_backend_data (pbfd )-> s -> elfclass == elfclass ))
854
+ _bfd_aarch64_compare_dynamic_obj_prop_against_outprop (info , outprop ,
855
+ pbfd );
793
856
}
794
857
795
858
/* Find the first input bfd with GNU property and merge it with GPROP. If no
@@ -855,7 +918,7 @@ _bfd_aarch64_elf_link_setup_gnu_properties (struct bfd_link_info *info)
855
918
/* The property list is sorted in order of type. */
856
919
for (elf_property_list * p = elf_properties (pbfd );
857
920
(p != NULL )
858
- && (GNU_PROPERTY_AARCH64_FEATURE_1_AND <= p -> property .pr_type );
921
+ && (GNU_PROPERTY_AARCH64_FEATURE_1_AND <= p -> property .pr_type );
859
922
p = p -> next )
860
923
{
861
924
/* This merge of features should happen only once as all the identical
@@ -872,9 +935,12 @@ _bfd_aarch64_elf_link_setup_gnu_properties (struct bfd_link_info *info)
872
935
}
873
936
}
874
937
938
+ tdata -> gnu_property_aarch64_feature_1_and = outprop ;
939
+
940
+ _bfd_aarch64_elf_check_gnu_properties_linked_dynamic_objects (info , outprop );
941
+
875
942
_bfd_aarch64_report_summary_merge_issues (info );
876
943
877
- tdata -> gnu_property_aarch64_feature_1_and = outprop ;
878
944
return pbfd ;
879
945
}
880
946
@@ -1047,21 +1113,42 @@ void
1047
1113
_bfd_aarch64_elf_check_gcs_report (struct bfd_link_info * info , bfd * ebfd )
1048
1114
{
1049
1115
struct elf_aarch64_obj_tdata * tdata = elf_aarch64_tdata (info -> output_bfd );
1116
+ bool dynamic_obj = (ebfd -> flags & DYNAMIC ) != 0 ;
1050
1117
1051
- if (tdata -> sw_protections .gcs_report == MARKING_NONE )
1052
- return ;
1053
-
1054
- ++ tdata -> n_gcs_issues ;
1055
-
1056
- if (tdata -> n_gcs_issues > GNU_PROPERTY_ISSUES_MAX )
1057
- return ;
1118
+ if (dynamic_obj )
1119
+ {
1120
+ if (tdata -> sw_protections .gcs_report_dynamic == MARKING_NONE )
1121
+ return ;
1122
+ ++ tdata -> n_gcs_dynamic_issues ;
1123
+ if (tdata -> n_gcs_dynamic_issues > GNU_PROPERTY_ISSUES_MAX )
1124
+ return ;
1125
+ }
1126
+ else
1127
+ {
1128
+ if (tdata -> sw_protections .gcs_report == MARKING_NONE )
1129
+ return ;
1130
+ ++ tdata -> n_gcs_issues ;
1131
+ if (tdata -> n_gcs_issues > GNU_PROPERTY_ISSUES_MAX )
1132
+ return ;
1133
+ }
1058
1134
1059
- const char * msg
1060
- = (tdata -> sw_protections .gcs_report == MARKING_WARN )
1061
- ? _ ("%pB: warning: GCS is required by -z gcs, but this input object file "
1062
- "lacks the necessary property note.\n" )
1063
- : _ ("%X%pB: error: GCS is required by -z gcs, but this input object file "
1064
- "lacks the necessary property note.\n" );
1135
+ const char * msg ;
1136
+ if (dynamic_obj )
1137
+ msg = (tdata -> sw_protections .gcs_report_dynamic == MARKING_WARN )
1138
+ ? _ ("%pB: warning: GCS is required by -z gcs, but this shared library "
1139
+ "lacks the necessary property note. The dynamic loader might not "
1140
+ "enable GCS or refuse to load the program unless all the shared "
1141
+ "library dependencies have the GCS marking.\n" )
1142
+ : _ ("%X%pB: error: GCS is required by -z gcs, but this shared library "
1143
+ "lacks the necessary property note. The dynamic loader might not "
1144
+ "enable GCS or refuse to load the program unless all the shared "
1145
+ "library dependencies have the GCS marking.\n" );
1146
+ else
1147
+ msg = (tdata -> sw_protections .gcs_report == MARKING_WARN )
1148
+ ? _ ("%pB: warning: GCS is required by -z gcs, but this input object file "
1149
+ "lacks the necessary property note.\n" )
1150
+ : _ ("%X%pB: error: GCS is required by -z gcs, but this input object file "
1151
+ "lacks the necessary property note.\n" );
1065
1152
1066
1153
info -> callbacks -> einfo (msg , ebfd );
1067
1154
}
0 commit comments