@@ -383,6 +383,7 @@ static int decode_instructions(struct objtool_file *file)
383
383
memset (insn , 0 , sizeof (* insn ));
384
384
INIT_LIST_HEAD (& insn -> alts );
385
385
INIT_LIST_HEAD (& insn -> stack_ops );
386
+ INIT_LIST_HEAD (& insn -> call_node );
386
387
387
388
insn -> sec = sec ;
388
389
insn -> offset = offset ;
@@ -420,8 +421,9 @@ static int decode_instructions(struct objtool_file *file)
420
421
421
422
sym_for_each_insn (file , func , insn ) {
422
423
insn -> func = func ;
423
- if (insn -> type == INSN_ENDBR ) {
424
+ if (insn -> type == INSN_ENDBR && list_empty ( & insn -> call_node ) ) {
424
425
if (insn -> offset == insn -> func -> offset ) {
426
+ list_add_tail (& insn -> call_node , & file -> endbr_list );
425
427
file -> nr_endbr ++ ;
426
428
} else {
427
429
file -> nr_endbr_int ++ ;
@@ -742,6 +744,58 @@ static int create_retpoline_sites_sections(struct objtool_file *file)
742
744
return 0 ;
743
745
}
744
746
747
+ static int create_ibt_endbr_seal_sections (struct objtool_file * file )
748
+ {
749
+ struct instruction * insn ;
750
+ struct section * sec ;
751
+ int idx ;
752
+
753
+ sec = find_section_by_name (file -> elf , ".ibt_endbr_seal" );
754
+ if (sec ) {
755
+ WARN ("file already has .ibt_endbr_seal, skipping" );
756
+ return 0 ;
757
+ }
758
+
759
+ idx = 0 ;
760
+ list_for_each_entry (insn , & file -> endbr_list , call_node )
761
+ idx ++ ;
762
+
763
+ if (stats ) {
764
+ printf ("ibt: ENDBR at function start: %d\n" , file -> nr_endbr );
765
+ printf ("ibt: ENDBR inside functions: %d\n" , file -> nr_endbr_int );
766
+ printf ("ibt: superfluous ENDBR: %d\n" , idx );
767
+ }
768
+
769
+ if (!idx )
770
+ return 0 ;
771
+
772
+ sec = elf_create_section (file -> elf , ".ibt_endbr_seal" , 0 ,
773
+ sizeof (int ), idx );
774
+ if (!sec ) {
775
+ WARN ("elf_create_section: .ibt_endbr_seal" );
776
+ return -1 ;
777
+ }
778
+
779
+ idx = 0 ;
780
+ list_for_each_entry (insn , & file -> endbr_list , call_node ) {
781
+
782
+ int * site = (int * )sec -> data -> d_buf + idx ;
783
+ * site = 0 ;
784
+
785
+ if (elf_add_reloc_to_insn (file -> elf , sec ,
786
+ idx * sizeof (int ),
787
+ R_X86_64_PC32 ,
788
+ insn -> sec , insn -> offset )) {
789
+ WARN ("elf_add_reloc_to_insn: .ibt_endbr_seal" );
790
+ return -1 ;
791
+ }
792
+
793
+ idx ++ ;
794
+ }
795
+
796
+ return 0 ;
797
+ }
798
+
745
799
static int create_mcount_loc_sections (struct objtool_file * file )
746
800
{
747
801
struct section * sec ;
@@ -3120,8 +3174,12 @@ validate_ibt_reloc(struct objtool_file *file, struct reloc *reloc)
3120
3174
if (!dest )
3121
3175
return NULL ;
3122
3176
3123
- if (dest -> type == INSN_ENDBR )
3177
+ if (dest -> type == INSN_ENDBR ) {
3178
+ if (!list_empty (& dest -> call_node ))
3179
+ list_del_init (& dest -> call_node );
3180
+
3124
3181
return NULL ;
3182
+ }
3125
3183
3126
3184
if (reloc -> sym -> static_call_tramp )
3127
3185
return NULL ;
@@ -3860,6 +3918,13 @@ int check(struct objtool_file *file)
3860
3918
warnings += ret ;
3861
3919
}
3862
3920
3921
+ if (ibt ) {
3922
+ ret = create_ibt_endbr_seal_sections (file );
3923
+ if (ret < 0 )
3924
+ goto out ;
3925
+ warnings += ret ;
3926
+ }
3927
+
3863
3928
if (stats ) {
3864
3929
printf ("nr_insns_visited: %ld\n" , nr_insns_visited );
3865
3930
printf ("nr_cfi: %ld\n" , nr_cfi );
0 commit comments