Re: [PATCH 32/48] objtool: Add is_cold_func() helper

Josh Poimboeuf
2026-04-23T15:12:10Z

On Thu, Apr 23, 2026 at 10:38:49AM +0200, Peter Zijlstra wrote:
> On Wed, Apr 22, 2026 at 09:04:00PM -0700, Josh Poimboeuf wrote:
>
> > diff --git a/tools/objtool/elf.c b/tools/objtool/elf.c
> > index 00c2389f345f..8a6e1338af97 100644
> > --- a/tools/objtool/elf.c
> > +++ b/tools/objtool/elf.c
> > @@ -586,8 +586,11 @@ static int elf_add_symbol(struct elf *elf, struct symbol *sym)
> > if (strstarts(sym->name, ".klp.sym"))
> > sym->klp = 1;
> >
> > + sym->pfunc = sym->cfunc = sym;
> > +
> > if (!sym->klp && !is_sec_sym(sym) && strstr(sym->name, ".cold")) {
> > - sym->cold = 1;
> > + /* Tell read_symbols() this is a cold subfunction */
> > + sym->pfunc = NULL;
> >
> > /*
> > * Clang doesn't mark cold subfunctions as STT_FUNC, which
> > @@ -596,8 +599,6 @@ static int elf_add_symbol(struct elf *elf, struct symbol *sym)
> > sym->type = STT_FUNC;
> > }
> >
> > - sym->pfunc = sym->cfunc = sym;
> > -
> > return 0;
> > }
>
> So now the cold subfunction has a NULL parent-function and a
> child-function that points to the parent?
>
> I'm confused.

It's a bit clunky. As the comment implies, 'sym->pfunc = NULL' is a
signal to it caller read_symbols() that this is a .cold function. Then,
after all the symbols have been added, read_symbols() goes and finds the
parent.

I think I did it this way because klp-diff.c calls elf_add_symbol() (via
elf_create_symbol()) and later needs to call is_cold_func() on it. In
that case, even though the parent isn't set, it still works because
is_cold_func() returns true for sym->pfunc != sym;

--
Josh