Re: [PATCH 02/18] objtool: Support data symbol printing

From: Josh Poimboeuf
Date: Thu Apr 14 2022 - 13:08:27 EST


On Thu, Apr 14, 2022 at 06:36:51PM +0200, Peter Zijlstra wrote:
> On Thu, Apr 14, 2022 at 08:38:54AM -0700, Josh Poimboeuf wrote:
>
> > > Yes, I'd not seen that yet, what's that for? The Changelog alludes to
> > > something, but I don't think it actually does get used later.
> >
> > Nick had asked for something like that, it's just a way to avoid doing
> > math every time we look at a warning, i.e. to convert func+offset to
> > sec+offset.
> >
> > But it's kind of ugly and I'm not 100% happy with it.
> >
> > Maybe it should be behind an option (--sec-offsets)?
>
> Can do I suppose... Myself, I have this script:
>
> $ cat objdump-func.sh
> #!/bin/bash
>
> OBJ=$1; shift
> FUNC=$1; shift
>
> objdump -wdr $@ $OBJ | awk "/^\$/ { P=0; } /$FUNC[^>]*>:\$/ { P=1; O=strtonum(\"0x\" \$1); } { if (P) { o=strtonum(\"0x\" \$1); printf(\"%04x \", o-O); print \$0; } }"

That is nice, just added to my ~/bin.

And how am I just learning about objdump "-w" ?!?!

I wrote up a new version of that patch which adds a '--sec-address'
option (see below), but maybe I'll just drop it for now. It's not
really relevant to this set anyway.


From: Josh Poimboeuf <jpoimboe@xxxxxxxxxx>
Subject: [PATCH] objtool: Add option to print section addresses

To help prevent objtool users from having to do math, add an option to
print the section address in addition to the function address.

Normal:

vmlinux.o: warning: objtool: fixup_exception()+0x2d1: unreachable instruction

With '--sec-address':

vmlinux.o: warning: objtool: fixup_exception()+0x2d1 (.text+0x76c51): unreachable instruction

Suggested-by: Nick Desaulniers <ndesaulniers@xxxxxxxxxx>
Signed-off-by: Josh Poimboeuf <jpoimboe@xxxxxxxxxx>
---
tools/objtool/builtin-check.c | 1 +
tools/objtool/include/objtool/builtin.h | 1 +
tools/objtool/include/objtool/warn.h | 31 ++++++++++++++-----------
3 files changed, 19 insertions(+), 14 deletions(-)

diff --git a/tools/objtool/builtin-check.c b/tools/objtool/builtin-check.c
index 3df46e9b4b03..2c562e3dec55 100644
--- a/tools/objtool/builtin-check.c
+++ b/tools/objtool/builtin-check.c
@@ -55,6 +55,7 @@ const struct option check_options[] = {
OPT_BOOLEAN(0, "module", &opts.module, "object is part of a kernel module"),
OPT_BOOLEAN(0, "no-fp", &opts.no_fp, "skip frame pointer validation"),
OPT_BOOLEAN(0, "no-unreachable", &opts.no_unreachable, "skip 'unreachable instruction' warnings"),
+ OPT_BOOLEAN(0, "sec-address", &opts.sec_address, "print section addresses in warnings"),
OPT_BOOLEAN(0, "stats", &opts.stats, "print statistics"),
OPT_BOOLEAN(0, "vmlinux", &opts.vmlinux, "vmlinux.o validation"),

diff --git a/tools/objtool/include/objtool/builtin.h b/tools/objtool/include/objtool/builtin.h
index 0cac9bd6a97f..e6910a66317a 100644
--- a/tools/objtool/include/objtool/builtin.h
+++ b/tools/objtool/include/objtool/builtin.h
@@ -33,6 +33,7 @@ struct opts {
bool module;
bool no_fp;
bool no_unreachable;
+ bool sec_address;
bool stats;
bool vmlinux;
};
diff --git a/tools/objtool/include/objtool/warn.h b/tools/objtool/include/objtool/warn.h
index c4bde3e2a79c..a3e79ae75f2e 100644
--- a/tools/objtool/include/objtool/warn.h
+++ b/tools/objtool/include/objtool/warn.h
@@ -11,30 +11,33 @@
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
+#include <objtool/builtin.h>
#include <objtool/elf.h>

extern const char *objname;

static inline char *offstr(struct section *sec, unsigned long offset)
{
- struct symbol *func;
- char *name, *str;
- unsigned long name_off;
+ bool is_text = (sec->sh.sh_flags & SHF_EXECINSTR);
+ struct symbol *sym = NULL;
+ char *str;
+ int len;

- func = find_func_containing(sec, offset);
- if (!func)
- func = find_symbol_containing(sec, offset);
- if (func) {
- name = func->name;
- name_off = offset - func->offset;
+ if (is_text)
+ sym = find_func_containing(sec, offset);
+ if (!sym)
+ sym = find_symbol_containing(sec, offset);
+
+ if (sym) {
+ str = malloc(strlen(sym->name) + strlen(sec->name) + 40);
+ len = sprintf(str, "%s+0x%lx", sym->name, offset - sym->offset);
+ if (opts.sec_address)
+ sprintf(str+len, " (%s+0x%lx)", sec->name, offset);
} else {
- name = sec->name;
- name_off = offset;
+ str = malloc(strlen(sec->name) + 20);
+ sprintf(str, "%s+0x%lx", sec->name, offset);
}

- str = malloc(strlen(name) + 20);
- sprintf(str, "%s+0x%lx", name, name_off);
-
return str;
}

--
2.34.1