@@ -4114,54 +4114,61 @@ static bool ignore_unreachable_insn(struct objtool_file *file, struct instructio
41144114 return false;
41154115}
41164116
4117- static int add_prefix_symbol (struct objtool_file * file , struct symbol * func ,
4118- struct instruction * insn )
4117+ static int add_prefix_symbol (struct objtool_file * file , struct symbol * func )
41194118{
4120- if (!opts .prefix )
4121- return 0 ;
4119+ struct instruction * insn , * prev ;
41224120
4123- for (;;) {
4124- struct instruction * prev = prev_insn_same_sec ( file , insn );
4125- u64 offset ;
4121+ insn = find_insn ( file , func -> sec , func -> offset );
4122+ if (! insn )
4123+ return -1 ;
41264124
4127- if (!prev )
4128- break ;
4125+ for (prev = prev_insn_same_sec (file , insn );
4126+ prev ;
4127+ prev = prev_insn_same_sec (file , prev )) {
4128+ u64 offset ;
41294129
41304130 if (prev -> type != INSN_NOP )
4131- break ;
4131+ return -1 ;
41324132
41334133 offset = func -> offset - prev -> offset ;
4134- if (offset >= opts .prefix ) {
4135- if (offset == opts .prefix ) {
4136- /*
4137- * Since the sec->symbol_list is ordered by
4138- * offset (see elf_add_symbol()) the added
4139- * symbol will not be seen by the iteration in
4140- * validate_section().
4141- *
4142- * Hence the lack of list_for_each_entry_safe()
4143- * there.
4144- *
4145- * The direct concequence is that prefix symbols
4146- * don't get visited (because pointless), except
4147- * for the logic in ignore_unreachable_insn()
4148- * that needs the terminating insn to be visited
4149- * otherwise it will report the hole.
4150- *
4151- * Hence mark the first instruction of the
4152- * prefix symbol as visisted.
4153- */
4154- prev -> visited |= VISITED_BRANCH ;
4155- elf_create_prefix_symbol (file -> elf , func , opts .prefix );
4156- }
4157- break ;
4158- }
4159- insn = prev ;
4134+
4135+ if (offset > opts .prefix )
4136+ return -1 ;
4137+
4138+ if (offset < opts .prefix )
4139+ continue ;
4140+
4141+ elf_create_prefix_symbol (file -> elf , func , opts .prefix );
4142+ break ;
41604143 }
41614144
4145+ if (!prev )
4146+ return -1 ;
4147+
41624148 return 0 ;
41634149}
41644150
4151+ static int add_prefix_symbols (struct objtool_file * file )
4152+ {
4153+ struct section * sec ;
4154+ struct symbol * func ;
4155+ int warnings = 0 ;
4156+
4157+ for_each_sec (file , sec ) {
4158+ if (!(sec -> sh .sh_flags & SHF_EXECINSTR ))
4159+ continue ;
4160+
4161+ sec_for_each_sym (sec , func ) {
4162+ if (func -> type != STT_FUNC )
4163+ continue ;
4164+
4165+ add_prefix_symbol (file , func );
4166+ }
4167+ }
4168+
4169+ return warnings ;
4170+ }
4171+
41654172static int validate_symbol (struct objtool_file * file , struct section * sec ,
41664173 struct symbol * sym , struct insn_state * state )
41674174{
@@ -4180,8 +4187,6 @@ static int validate_symbol(struct objtool_file *file, struct section *sec,
41804187 if (!insn || insn -> ignore || insn -> visited )
41814188 return 0 ;
41824189
4183- add_prefix_symbol (file , sym , insn );
4184-
41854190 state -> uaccess = sym -> uaccess_safe ;
41864191
41874192 ret = validate_branch (file , insn_func (insn ), insn , * state );
@@ -4621,6 +4626,13 @@ int check(struct objtool_file *file)
46214626 warnings += ret ;
46224627 }
46234628
4629+ if (opts .prefix ) {
4630+ ret = add_prefix_symbols (file );
4631+ if (ret < 0 )
4632+ return ret ;
4633+ warnings += ret ;
4634+ }
4635+
46244636 if (opts .ibt ) {
46254637 ret = create_ibt_endbr_seal_sections (file );
46264638 if (ret < 0 )
0 commit comments