Assume ALTERNATIVE()s know what they're doing and do not change, or cause to change, instructions in .altinstr_replacement sections.
Unified · Split
| @@ -993,18 +993,27 @@ static void remove_insn_ops(struct instruction *insn) · 992 unmodified lines | |||
| 993 | } | 993 | } |
| 994 | } | 994 | } |
| 995 | 995 | ||
| 996 | static void add_call_dest(struct objtool_file *file, struct instruction *insn, | 996 | static void annotate_call_site(struct objtool_file *file, |
| 997 | struct symbol *dest, bool sibling) | 997 | struct instruction *insn, bool sibling) |
| 998 | { | 998 | { |
| 999 | struct reloc *reloc = insn_reloc(file, insn); | 999 | struct reloc *reloc = insn_reloc(file, insn); |
| 1000 | struct symbol *sym = insn->call_dest; | ||
| 1000 | 1001 | ||
| 1001 | insn->call_dest = dest; | 1002 | if (!sym) |
| 1002 | if (!dest) | 1003 | sym = reloc->sym; |
| 1004 | |||
| 1005 | /* | ||
| 1006 | * Alternative replacement code is just template code which is | ||
| 1007 | * sometimes copied to the original instruction. For now, don't | ||
| 1008 | * annotate it. (In the future we might consider annotating the | ||
| 1009 | * original instruction if/when it ever makes sense to do so.) | ||
| 1010 | */ | ||
| 1011 | if (!strcmp(insn->sec->name, ".altinstr_replacement")) | ||
| 1003 | return; | 1012 | return; |
| 1004 | 1013 | ||
| 1005 | if (insn->call_dest->static_call_tramp) { | 1014 | if (sym->static_call_tramp) { |
| 1006 | list_add_tail(&insn->call_node, | 1015 | list_add_tail(&insn->call_node, &file->static_call_list); |
| 1007 | &file->static_call_list); | 1016 | return; |
| 1008 | } | 1017 | } |
| 1009 | 1018 | ||
| 1010 | /* | 1019 | /* |
| @@ -1012,7 +1021,7 @@ static void add_call_dest(struct objtool_file *file, struct instruction *insn, · 1 unmodified line | |||
| 1012 | * so they need a little help, NOP out any KCOV calls from noinstr | 1021 | * so they need a little help, NOP out any KCOV calls from noinstr |
| 1013 | * text. | 1022 | * text. |
| 1014 | */ | 1023 | */ |
| 1015 | if (insn->sec->noinstr && insn->call_dest->kcov) { | 1024 | if (insn->sec->noinstr && sym->kcov) { |
| 1016 | if (reloc) { | 1025 | if (reloc) { |
| 1017 | reloc->type = R_NONE; | 1026 | reloc->type = R_NONE; |
| 1018 | elf_write_reloc(file->elf, reloc); | 1027 | elf_write_reloc(file->elf, reloc); |
| @@ -1024,9 +1033,10 @@ static void add_call_dest(struct objtool_file *file, struct instruction *insn, · 5 unmodified lines | |||
| 1024 | : arch_nop_insn(insn->len)); | 1033 | : arch_nop_insn(insn->len)); |
| 1025 | 1034 | ||
| 1026 | insn->type = sibling ? INSN_RETURN : INSN_NOP; | 1035 | insn->type = sibling ? INSN_RETURN : INSN_NOP; |
| 1036 | return; | ||
| 1027 | } | 1037 | } |
| 1028 | 1038 | ||
| 1029 | if (mcount && insn->call_dest->fentry) { | 1039 | if (mcount && sym->fentry) { |
| 1030 | if (sibling) | 1040 | if (sibling) |
| 1031 | WARN_FUNC("Tail call to __fentry__ !?!?", insn->sec, insn->offset); | 1041 | WARN_FUNC("Tail call to __fentry__ !?!?", insn->sec, insn->offset); |
| 1032 | 1042 | ||
| @@ -1041,9 +1051,17 @@ static void add_call_dest(struct objtool_file *file, struct instruction *insn, · 8 unmodified lines | |||
| 1041 | 1051 | ||
| 1042 | insn->type = INSN_NOP; | 1052 | insn->type = INSN_NOP; |
| 1043 | 1053 | ||
| 1044 | list_add_tail(&insn->mcount_loc_node, | 1054 | list_add_tail(&insn->mcount_loc_node, &file->mcount_loc_list); |
| 1045 | &file->mcount_loc_list); | 1055 | return; |
| 1046 | } | 1056 | } |
| 1057 | } | ||
| 1058 | |||
| 1059 | static void add_call_dest(struct objtool_file *file, struct instruction *insn, | ||
| 1060 | struct symbol *dest, bool sibling) | ||
| 1061 | { | ||
| 1062 | insn->call_dest = dest; | ||
| 1063 | if (!dest) | ||
| 1064 | return; | ||
| 1047 | 1065 | ||
| 1048 | /* | 1066 | /* |
| 1049 | * Whatever stack impact regular CALLs have, should be undone | 1067 | * Whatever stack impact regular CALLs have, should be undone |
| @@ -1053,6 +1071,8 @@ static void add_call_dest(struct objtool_file *file, struct instruction *insn, · 3 unmodified lines | |||
| 1053 | * are converted to JUMP, see read_intra_function_calls(). | 1071 | * are converted to JUMP, see read_intra_function_calls(). |
| 1054 | */ | 1072 | */ |
| 1055 | remove_insn_ops(insn); | 1073 | remove_insn_ops(insn); |
| 1074 | |||
| 1075 | annotate_call_site(file, insn, sibling); | ||
| 1056 | } | 1076 | } |
| 1057 | 1077 | ||
| 1058 | /* | 1078 | /* |