On Fri, Apr 28, 2023 at 10:28:19AM +0000, Christophe Leroy wrote: > > diff --git a/tools/objtool/check.c b/tools/objtool/check.c > > index 5b600bbf2389..d67b80251eec 100644 > > --- a/tools/objtool/check.c > > +++ b/tools/objtool/check.c > > @@ -131,6 +131,27 @@ static struct instruction *prev_insn_same_sym(struct objtool_file *file, > > for (insn = next_insn_same_sec(file, insn); insn; \ > > insn = next_insn_same_sec(file, insn)) > > > > +static struct instruction *find_insn_containing(struct objtool_file *file, > > + struct section *sec, > > + unsigned long offset) > > +{ > > + struct instruction *insn; > > + > > + insn = find_insn(file, sec, 0); > > + if (!insn) > > + return NULL; > > + > > + sec_for_each_insn_from(file, insn) { > > + if (insn->offset > offset) > > + return NULL; > > + if (insn->offset <= offset && (insn->offset + insn->len) > offset) > > + return insn; > > + } > > + > > + return NULL; > > +} Urgh, this is horrendous crap. Yes you're only using it in case of a warning, but adding a function like this makes it appear like it's actually sane to use. A far better implementation -- but still not stellar -- would be something like: sym = find_symbol_containing(sec, offset); if (!sym) // fail sym_for_each_insn(file, sym, insn) { ... } But given insn_hash uses sec_offset_hash() you can do something similar to find_reloc_by_dest_range() start = offset - (INSN_MAX_SIZE - 1); for_offset_range(o, start, start + INSN_MAX_SIZE) { hash_for_each_possible(file->insn_hash, insn, hash, sec_offset_hash(sec, o)) { if (insn->sec != sec) continue; if (insn->offset <= offset && insn->offset + inns->len > offset) return insn; } } return NULL; > > + > > + > > static inline struct symbol *insn_call_dest(struct instruction *insn) > > { > > if (insn->type == INSN_JUMP_DYNAMIC || > > @@ -4529,6 +4550,61 @@ static int validate_reachable_instructions(struct objtool_file *file) > > return 0; > > } > > > > +static int is_in_pvh_code(struct instruction *insn) > > +{ > > + struct symbol *sym = insn->sym; > > + > > + return sym && !strcmp(sym->name, "pvh_start_xen"); > > +} > > + > > +static int validate_pie(struct objtool_file *file) > > +{ > > + struct section *sec; > > + struct reloc *reloc; > > + struct instruction *insn; > > + int warnings = 0; > > + > > + for_each_sec(file, sec) { > > + if (!sec->reloc) > > + continue; > > + if (!(sec->sh.sh_flags & SHF_ALLOC)) > > + continue; > > + > > + list_for_each_entry(reloc, &sec->reloc->reloc_list, list) { > > + switch (reloc->type) { > > + case R_X86_64_NONE: > > + case R_X86_64_PC32: > > + case R_X86_64_PLT32: > > + case R_X86_64_64: > > + case R_X86_64_PC64: > > + case R_X86_64_GOTPCREL: > > + break; > > + case R_X86_64_32: > > + case R_X86_64_32S: > > That looks very specific to X86, should it go at another place ? > > If it can work for any architecture, can you add generic macros, just > like commit c1449735211d ("objtool: Use macros to define arch specific > reloc types") then commit c984aef8c832 ("objtool/powerpc: Add --mcount > specific implementation") ? Yes, this should be something like arch_PIE_reloc() or so. Similar to arch_pc_relative_reloc().