@@ -427,6 +427,40 @@ static void add_ignores(struct objtool_file *file)
427
427
}
428
428
}
429
429
430
+ /*
431
+ * FIXME: For now, just ignore any alternatives which add retpolines. This is
432
+ * a temporary hack, as it doesn't allow ORC to unwind from inside a retpoline.
433
+ * But it at least allows objtool to understand the control flow *around* the
434
+ * retpoline.
435
+ */
436
+ static int add_nospec_ignores (struct objtool_file * file )
437
+ {
438
+ struct section * sec ;
439
+ struct rela * rela ;
440
+ struct instruction * insn ;
441
+
442
+ sec = find_section_by_name (file -> elf , ".rela.discard.nospec" );
443
+ if (!sec )
444
+ return 0 ;
445
+
446
+ list_for_each_entry (rela , & sec -> rela_list , list ) {
447
+ if (rela -> sym -> type != STT_SECTION ) {
448
+ WARN ("unexpected relocation symbol type in %s" , sec -> name );
449
+ return -1 ;
450
+ }
451
+
452
+ insn = find_insn (file , rela -> sym -> sec , rela -> addend );
453
+ if (!insn ) {
454
+ WARN ("bad .discard.nospec entry" );
455
+ return -1 ;
456
+ }
457
+
458
+ insn -> ignore_alts = true;
459
+ }
460
+
461
+ return 0 ;
462
+ }
463
+
430
464
/*
431
465
* Find the destination instructions for all jumps.
432
466
*/
@@ -509,11 +543,18 @@ static int add_call_destinations(struct objtool_file *file)
509
543
dest_off = insn -> offset + insn -> len + insn -> immediate ;
510
544
insn -> call_dest = find_symbol_by_offset (insn -> sec ,
511
545
dest_off );
546
+ /*
547
+ * FIXME: Thanks to retpolines, it's now considered
548
+ * normal for a function to call within itself. So
549
+ * disable this warning for now.
550
+ */
551
+ #if 0
512
552
if (!insn -> call_dest ) {
513
553
WARN_FUNC ("can't find call dest symbol at offset 0x%lx" ,
514
554
insn -> sec , insn -> offset , dest_off );
515
555
return -1 ;
516
556
}
557
+ #endif
517
558
} else if (rela -> sym -> type == STT_SECTION ) {
518
559
insn -> call_dest = find_symbol_by_offset (rela -> sym -> sec ,
519
560
rela -> addend + 4 );
@@ -678,12 +719,6 @@ static int add_special_section_alts(struct objtool_file *file)
678
719
return ret ;
679
720
680
721
list_for_each_entry_safe (special_alt , tmp , & special_alts , list ) {
681
- alt = malloc (sizeof (* alt ));
682
- if (!alt ) {
683
- WARN ("malloc failed" );
684
- ret = -1 ;
685
- goto out ;
686
- }
687
722
688
723
orig_insn = find_insn (file , special_alt -> orig_sec ,
689
724
special_alt -> orig_off );
@@ -694,6 +729,10 @@ static int add_special_section_alts(struct objtool_file *file)
694
729
goto out ;
695
730
}
696
731
732
+ /* Ignore retpoline alternatives. */
733
+ if (orig_insn -> ignore_alts )
734
+ continue ;
735
+
697
736
new_insn = NULL ;
698
737
if (!special_alt -> group || special_alt -> new_len ) {
699
738
new_insn = find_insn (file , special_alt -> new_sec ,
@@ -719,6 +758,13 @@ static int add_special_section_alts(struct objtool_file *file)
719
758
goto out ;
720
759
}
721
760
761
+ alt = malloc (sizeof (* alt ));
762
+ if (!alt ) {
763
+ WARN ("malloc failed" );
764
+ ret = -1 ;
765
+ goto out ;
766
+ }
767
+
722
768
alt -> insn = new_insn ;
723
769
list_add_tail (& alt -> list , & orig_insn -> alts );
724
770
@@ -1035,6 +1081,10 @@ static int decode_sections(struct objtool_file *file)
1035
1081
1036
1082
add_ignores (file );
1037
1083
1084
+ ret = add_nospec_ignores (file );
1085
+ if (ret )
1086
+ return ret ;
1087
+
1038
1088
ret = add_jump_destinations (file );
1039
1089
if (ret )
1040
1090
return ret ;
0 commit comments