Possible patch; fix perf Annotation of Thumb code

Dave Martin dave.martin at linaro.org
Thu Jan 13 11:05:40 EST 2011


On Thu, Jan 13, 2011 at 7:00 AM, Dr. David Alan Gilbert
<david.gilbert at linaro.org> wrote:
> Hi,
>  I'm finding that if I annotate an ARM Thumb function with perf that it's
> mis-disassembling it; below is a patch that fixes it, but I'm not sure if
> it's the best place for the fix.
>
>  The problem is that on Thumb, the bottom bit of the symbol address is
> set for thumb functions, and thus perf starts disassembling at address+1,
> and since all thumb instructions are 2 bytes aligned to 2 bytes you end
> up disassembling across the middle of pairs of instructions.
>
>
>  The patch removes that bottom bit during symbol loading.
>
>  Questions:
>    1) Is this the right place to do it - does some other bit of Perf need the
> raw symbol value?  My alternative is to mask it just before the objdump,
> but then my worry is if it also needs masking somewhere else.
>
>    2) Should the check be more selective - i.e. only some symbol types?

We should definitely only do this if for function symbols, since data
symbols have no "thumb bit" and can be arbitrarily aligned.

I think this can be achieved by checking map->type :

if ((ehdr.e_machine == EM_ARM) && map->type == MAP__FUNCTION &&
(sym.st_value & 1)) {
 ...

Cheers
---Dave

>
> This is against the Linaro 2.6.37 tree; I'm happy to rebase it against
> the clean 2.6.37 if people agree the patch is doing the right thing.
>
> Dave
> (For reference this corresponds to this bug
> https://bugs.launchpad.net/linux-linaro/+bug/677547 )
>
>        Signed-off-by: Dr. David Alan Gilbert <david.gilbert at linaro.org>
> ---
> diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c
> index 439ab94..3d77b5e 100644
> --- a/tools/perf/util/symbol.c
> +++ b/tools/perf/util/symbol.c
> @@ -1129,6 +1129,11 @@ static int dso__load_sym(struct dso *self, struct map *map, const char *name,
>
>                section_name = elf_sec__name(&shdr, secstrs);
>
> +               /* On ARM, symbols for thumb functions have 1 added to
> +               the symbol address as a flag - remove it */
> +               if ((ehdr.e_machine == EM_ARM) && (sym.st_value & 1))
> +                       sym.st_value-=1;
> +
>                if (self->kernel != DSO_TYPE_USER || kmodule) {
>                        char dso_name[PATH_MAX];
>
>



More information about the linux-arm-kernel mailing list