Re: [PATCH V2 4/9] tools/perf: Add support to capture and parse raw instruction in objdump

2024-05-22 Thread Athira Rajeev



> On 10 May 2024, at 7:56 PM, Arnaldo Carvalho de Melo  wrote:
> 
> On Thu, May 09, 2024 at 10:56:23PM +0530, Athira Rajeev wrote:
>> 
>> 
>>> On 7 May 2024, at 3:05 PM, Christophe Leroy  
>>> wrote:
>>> 
>>> 
>>> 
>>> Le 06/05/2024 à 14:19, Athira Rajeev a écrit :
 Add support to capture and parse raw instruction in objdump.
>>> 
>>> What's the purpose of using 'objdump' for reading raw instructions ? 
>>> Can't they be read directly without invoking 'objdump' ? It looks odd to 
>>> me to use objdump to provide readable text and then parse it back.
>> 
>> Hi Christophe,
>> 
>> Thanks for your review comments.
>> 
>> Current implementation for data type profiling on X86 uses "objdump" tool to 
>> get the disassembled code.
> 
> commit 6d17edc113de1e21fc66afa76be475a4f7c91826
> Author: Namhyung Kim 
> Date:   Fri Mar 29 14:58:11 2024 -0700
> 
>perf annotate: Use libcapstone to disassemble
> 
>Now it can use the capstone library to disassemble the instructions.
>Let's use that (if available) for perf annotate to speed up.  Currently
>it only supports x86 architecture.  With this change I can see ~3x speed
>up in data type profiling.
> 
>But note that capstone cannot give the source file and line number info.
>For now, users should use the external objdump for that by specifying
>the --objdump option explicitly.
> 
>Signed-off-by: Namhyung Kim 
>Tested-by: Ian Rogers 
>Cc: Adrian Hunter 
>Cc: Changbin Du 
>Cc: Ingo Molnar 
>Cc: Jiri Olsa 
>Cc: Kan Liang 
>Cc: Peter Zijlstra 
>Link: https://lore.kernel.org/r/20240329215812.537846-5-namhy...@kernel.org
>Signed-off-by: Arnaldo Carvalho de Melo 
> 
> From a quick look at http://www.capstone-engine.org/compile.html it
> seems PowerPC is supported.
> 
> But since we did it first with objdump output parsing, its good to have
> it as an alternative and sometimes a fallback:

Hi Arnaldo, Namhyung

Thanks for the suggestions. libcapstone is a good option and it is faster too.
I will address these changes in V3.

Thanks
Athira
> 
> commit f35847de2a65137e011e559f38a3de5902a5463f
> Author: Namhyung Kim 
> Date:   Wed Apr 24 17:51:56 2024 -0700
> 
>perf annotate: Fallback disassemble to objdump when capstone fails
> 
>I found some cases that capstone failed to disassemble.  Probably my
>capstone is an old version but anyway there's a chance it can fail.  And
>then it silently stopped in the middle.  In my case, it didn't
>understand "RDPKRU" instruction.
> 
>Let's check if the capstone disassemble reached the end of the function
>and fallback to objdump if not
> 
> ---
> 
> - Arnaldo
> 
>> And then the objdump result lines are parsed to get the instruction
>> name and register fields. The initial patchset I posted to enable the
>> data type profiling feature in powerpc was using the same way by
>> getting disassembled code from objdump and parsing the disassembled
>> lines. But in V2, we are introducing change for powerpc to use "raw
>> instruction" and fetch opcode, reg fields from the raw instruction.
> 
>> I tried to explain below that current objdump uses option
>> "--no-show-raw-insn" which doesn't capture raw instruction.  So to
>> capture raw instruction, V2 patchset has changes to use default option
>> "--show-raw-insn" and get the raw instruction [ for powerpc ] along
>> with human readable annotation [ which is used by other archs ]. Since
>> perf tool already has objdump implementation in place, I went in the
>> direction to enhance it to use "--show-raw-insn" for powerpc purpose.
> 
>> But as you mentioned, we can directly read raw instruction without
>> using "objdump" tool.  perf has support to read object code. The dso
>> open/read utilities and helper functions are already present in
>> "util/dso.c" And "dso__data_read_offset" function reads data from dso
>> file offset. We can use these functions and I can make changes to
>> directly read binary instruction without using objdump.
> 
>> Namhyung, Arnaldo, Christophe
>> Looking for your valuable feedback on this approach. Please suggest if this 
>> approach looks fine
>> 
>> 
>> Thanks
>> Athira
>>> 
 Currently, the perf tool infrastructure uses "--no-show-raw-insn" option
 with "objdump" while disassemble. Example from powerpc with this option
 for an instruction address is:
>>> 
>>> Yes and that makes sense because the purpose of objdump is to provide 
>>> human readable annotations, not to perform automated analysis. Am I 
>>> missing something ?
>>> 
 
 Snippet from:
 objdump  --start-address= --stop-address=  -d 
 --no-show-raw-insn -C 
 
 c10224b4: lwz r10,0(r9)
 
 This line "lwz r10,0(r9)" is parsed to extract instruction name,
 registers names and offset. Also to find whether there is a memory
 reference in the operands, "memory_ref_char" field of objdump is used.
 For x86, "(" is used as memory_ref_char to tackle i

Re: [PATCH V2 4/9] tools/perf: Add support to capture and parse raw instruction in objdump

2024-05-10 Thread Arnaldo Carvalho de Melo
On Thu, May 09, 2024 at 10:56:23PM +0530, Athira Rajeev wrote:
> 
> 
> > On 7 May 2024, at 3:05 PM, Christophe Leroy  
> > wrote:
> > 
> > 
> > 
> > Le 06/05/2024 à 14:19, Athira Rajeev a écrit :
> >> Add support to capture and parse raw instruction in objdump.
> > 
> > What's the purpose of using 'objdump' for reading raw instructions ? 
> > Can't they be read directly without invoking 'objdump' ? It looks odd to 
> > me to use objdump to provide readable text and then parse it back.
> 
> Hi Christophe,
> 
> Thanks for your review comments.
> 
> Current implementation for data type profiling on X86 uses "objdump" tool to 
> get the disassembled code.

commit 6d17edc113de1e21fc66afa76be475a4f7c91826
Author: Namhyung Kim 
Date:   Fri Mar 29 14:58:11 2024 -0700

perf annotate: Use libcapstone to disassemble

Now it can use the capstone library to disassemble the instructions.
Let's use that (if available) for perf annotate to speed up.  Currently
it only supports x86 architecture.  With this change I can see ~3x speed
up in data type profiling.

But note that capstone cannot give the source file and line number info.
For now, users should use the external objdump for that by specifying
the --objdump option explicitly.

Signed-off-by: Namhyung Kim 
Tested-by: Ian Rogers 
Cc: Adrian Hunter 
Cc: Changbin Du 
Cc: Ingo Molnar 
Cc: Jiri Olsa 
Cc: Kan Liang 
Cc: Peter Zijlstra 
Link: https://lore.kernel.org/r/20240329215812.537846-5-namhy...@kernel.org
Signed-off-by: Arnaldo Carvalho de Melo 

>From a quick look at http://www.capstone-engine.org/compile.html it
seems PowerPC is supported.

But since we did it first with objdump output parsing, its good to have
it as an alternative and sometimes a fallback:

commit f35847de2a65137e011e559f38a3de5902a5463f
Author: Namhyung Kim 
Date:   Wed Apr 24 17:51:56 2024 -0700

perf annotate: Fallback disassemble to objdump when capstone fails

I found some cases that capstone failed to disassemble.  Probably my
capstone is an old version but anyway there's a chance it can fail.  And
then it silently stopped in the middle.  In my case, it didn't
understand "RDPKRU" instruction.

Let's check if the capstone disassemble reached the end of the function
and fallback to objdump if not

---

- Arnaldo

> And then the objdump result lines are parsed to get the instruction
> name and register fields. The initial patchset I posted to enable the
> data type profiling feature in powerpc was using the same way by
> getting disassembled code from objdump and parsing the disassembled
> lines. But in V2, we are introducing change for powerpc to use "raw
> instruction" and fetch opcode, reg fields from the raw instruction.
 
> I tried to explain below that current objdump uses option
> "--no-show-raw-insn" which doesn't capture raw instruction.  So to
> capture raw instruction, V2 patchset has changes to use default option
> "--show-raw-insn" and get the raw instruction [ for powerpc ] along
> with human readable annotation [ which is used by other archs ]. Since
> perf tool already has objdump implementation in place, I went in the
> direction to enhance it to use "--show-raw-insn" for powerpc purpose.
 
> But as you mentioned, we can directly read raw instruction without
> using "objdump" tool.  perf has support to read object code. The dso
> open/read utilities and helper functions are already present in
> "util/dso.c" And "dso__data_read_offset" function reads data from dso
> file offset. We can use these functions and I can make changes to
> directly read binary instruction without using objdump.
 
> Namhyung, Arnaldo, Christophe
> Looking for your valuable feedback on this approach. Please suggest if this 
> approach looks fine
> 
> 
> Thanks
> Athira
> > 
> >> Currently, the perf tool infrastructure uses "--no-show-raw-insn" option
> >> with "objdump" while disassemble. Example from powerpc with this option
> >> for an instruction address is:
> > 
> > Yes and that makes sense because the purpose of objdump is to provide 
> > human readable annotations, not to perform automated analysis. Am I 
> > missing something ?
> > 
> >> 
> >> Snippet from:
> >> objdump  --start-address= --stop-address=  -d 
> >> --no-show-raw-insn -C 
> >> 
> >> c10224b4: lwz r10,0(r9)
> >> 
> >> This line "lwz r10,0(r9)" is parsed to extract instruction name,
> >> registers names and offset. Also to find whether there is a memory
> >> reference in the operands, "memory_ref_char" field of objdump is used.
> >> For x86, "(" is used as memory_ref_char to tackle instructions of the
> >> form "mov  (%rax), %rcx".
> >> 
> >> In case of powerpc, not all instructions using "(" are the only memory
> >> instructions. Example, above instruction can also be of extended form (X
> >> form) "lwzx r10,0,r19". Inorder to easy identify the instruction category
> >> and extract the source/t

Re: [PATCH V2 4/9] tools/perf: Add support to capture and parse raw instruction in objdump

2024-05-09 Thread Namhyung Kim
On Thu, May 9, 2024 at 10:27 AM Athira Rajeev
 wrote:
>
>
>
> > On 7 May 2024, at 3:05 PM, Christophe Leroy  
> > wrote:
> >
> >
> >
> > Le 06/05/2024 à 14:19, Athira Rajeev a écrit :
> >> Add support to capture and parse raw instruction in objdump.
> >
> > What's the purpose of using 'objdump' for reading raw instructions ?
> > Can't they be read directly without invoking 'objdump' ? It looks odd to
> > me to use objdump to provide readable text and then parse it back.
>
> Hi Christophe,
>
> Thanks for your review comments.
>
> Current implementation for data type profiling on X86 uses "objdump" tool to 
> get the disassembled code.
> And then the objdump result lines are parsed to get the instruction name and 
> register fields. The initial patchset I posted to enable the data type 
> profiling feature in powerpc was using the same way by getting disassembled 
> code from objdump and parsing the disassembled lines. But in V2, we are 
> introducing change for powerpc to use "raw instruction" and fetch opcode, reg 
> fields from the raw instruction.
>
> I tried to explain below that current objdump uses option 
> "--no-show-raw-insn" which doesn't capture raw instruction.  So to capture 
> raw instruction, V2 patchset has changes to use default option 
> "--show-raw-insn" and get the raw instruction [ for powerpc ] along with 
> human readable annotation [ which is used by other archs ]. Since perf tool 
> already has objdump implementation in place, I went in the direction to 
> enhance it to use "--show-raw-insn" for powerpc purpose.
>
> But as you mentioned, we can directly read raw instruction without using 
> "objdump" tool.
> perf has support to read object code. The dso open/read utilities and helper 
> functions are already present in "util/dso.c" And "dso__data_read_offset" 
> function reads data from dso file offset. We can use these functions and I 
> can make changes to directly read binary instruction without using objdump.
>
> Namhyung, Arnaldo, Christophe
> Looking for your valuable feedback on this approach. Please suggest if this 
> approach looks fine

Looks like you want to implement instruction decoding
like in arch/x86/lib/{insn,inat}.c.  I think it's ok to do that
but you need to decide which way is more convenient.

Also it works on the struct disasm_line so you need to
fill in the necessary info when not using objdump.  As
long as it produces the same output I don't care much
if you use objdump or not.  Actually it uses libcapstone
to disassemble x86 instructions if possible.  Maybe you
can use that on powerpc too.

Thanks,
Namhyung

>
>
> Thanks
> Athira
> >
> >> Currently, the perf tool infrastructure uses "--no-show-raw-insn" option
> >> with "objdump" while disassemble. Example from powerpc with this option
> >> for an instruction address is:
> >
> > Yes and that makes sense because the purpose of objdump is to provide
> > human readable annotations, not to perform automated analysis. Am I
> > missing something ?
> >
> >>
> >> Snippet from:
> >> objdump  --start-address= --stop-address=  -d 
> >> --no-show-raw-insn -C 
> >>
> >> c10224b4: lwz r10,0(r9)
> >>
> >> This line "lwz r10,0(r9)" is parsed to extract instruction name,
> >> registers names and offset. Also to find whether there is a memory
> >> reference in the operands, "memory_ref_char" field of objdump is used.
> >> For x86, "(" is used as memory_ref_char to tackle instructions of the
> >> form "mov  (%rax), %rcx".
> >>
> >> In case of powerpc, not all instructions using "(" are the only memory
> >> instructions. Example, above instruction can also be of extended form (X
> >> form) "lwzx r10,0,r19". Inorder to easy identify the instruction category
> >> and extract the source/target registers, patch adds support to use raw
> >> instruction. With raw instruction, macros are added to extract opcode
> >> and register fields.
> >>
> >> "struct ins_operands" and "struct ins" is updated to carry opcode and
> >> raw instruction binary code (raw_insn). Function "disasm_line__parse"
> >> is updated to fill the raw instruction hex value and opcode in newly
> >> added fields. There is no changes in existing code paths, which parses
> >> the disassembled code. The architecture using the instruction name and
> >> present approach is not altered. Since this approach targets powerpc,
> >> the macro implementation is added for powerpc as of now.
> >>
> >> Example:
> >> representation using --show-raw-insn in objdump gives result:
> >>
> >> 38 01 81 e8 ld  r4,312(r1)
> >>
> >> Here "38 01 81 e8" is the raw instruction representation. In powerpc,
> >> this translates to instruction form: "ld RT,DS(RA)" and binary code
> >> as:
> >> _
> >> | 58 |  RT  |  RA |  DS   | |
> >> -
> >> 06 1116  30 31
> >>
> >> Function "disasm_line__parse" is updated to capture:
> >>
> >> line:38 01 81 e8 ld  r4,312(r1)
> >> 

Re: [PATCH V2 4/9] tools/perf: Add support to capture and parse raw instruction in objdump

2024-05-09 Thread Athira Rajeev



> On 7 May 2024, at 3:05 PM, Christophe Leroy  
> wrote:
> 
> 
> 
> Le 06/05/2024 à 14:19, Athira Rajeev a écrit :
>> Add support to capture and parse raw instruction in objdump.
> 
> What's the purpose of using 'objdump' for reading raw instructions ? 
> Can't they be read directly without invoking 'objdump' ? It looks odd to 
> me to use objdump to provide readable text and then parse it back.

Hi Christophe,

Thanks for your review comments.

Current implementation for data type profiling on X86 uses "objdump" tool to 
get the disassembled code.
And then the objdump result lines are parsed to get the instruction name and 
register fields. The initial patchset I posted to enable the data type 
profiling feature in powerpc was using the same way by getting disassembled 
code from objdump and parsing the disassembled lines. But in V2, we are 
introducing change for powerpc to use "raw instruction" and fetch opcode, reg 
fields from the raw instruction.

I tried to explain below that current objdump uses option "--no-show-raw-insn" 
which doesn't capture raw instruction.  So to capture raw instruction, V2 
patchset has changes to use default option "--show-raw-insn" and get the raw 
instruction [ for powerpc ] along with human readable annotation [ which is 
used by other archs ]. Since perf tool already has objdump implementation in 
place, I went in the direction to enhance it to use "--show-raw-insn" for 
powerpc purpose.

But as you mentioned, we can directly read raw instruction without using 
"objdump" tool.
perf has support to read object code. The dso open/read utilities and helper 
functions are already present in "util/dso.c" And "dso__data_read_offset" 
function reads data from dso file offset. We can use these functions and I can 
make changes to directly read binary instruction without using objdump.

Namhyung, Arnaldo, Christophe
Looking for your valuable feedback on this approach. Please suggest if this 
approach looks fine


Thanks
Athira
> 
>> Currently, the perf tool infrastructure uses "--no-show-raw-insn" option
>> with "objdump" while disassemble. Example from powerpc with this option
>> for an instruction address is:
> 
> Yes and that makes sense because the purpose of objdump is to provide 
> human readable annotations, not to perform automated analysis. Am I 
> missing something ?
> 
>> 
>> Snippet from:
>> objdump  --start-address= --stop-address=  -d 
>> --no-show-raw-insn -C 
>> 
>> c10224b4: lwz r10,0(r9)
>> 
>> This line "lwz r10,0(r9)" is parsed to extract instruction name,
>> registers names and offset. Also to find whether there is a memory
>> reference in the operands, "memory_ref_char" field of objdump is used.
>> For x86, "(" is used as memory_ref_char to tackle instructions of the
>> form "mov  (%rax), %rcx".
>> 
>> In case of powerpc, not all instructions using "(" are the only memory
>> instructions. Example, above instruction can also be of extended form (X
>> form) "lwzx r10,0,r19". Inorder to easy identify the instruction category
>> and extract the source/target registers, patch adds support to use raw
>> instruction. With raw instruction, macros are added to extract opcode
>> and register fields.
>> 
>> "struct ins_operands" and "struct ins" is updated to carry opcode and
>> raw instruction binary code (raw_insn). Function "disasm_line__parse"
>> is updated to fill the raw instruction hex value and opcode in newly
>> added fields. There is no changes in existing code paths, which parses
>> the disassembled code. The architecture using the instruction name and
>> present approach is not altered. Since this approach targets powerpc,
>> the macro implementation is added for powerpc as of now.
>> 
>> Example:
>> representation using --show-raw-insn in objdump gives result:
>> 
>> 38 01 81 e8 ld  r4,312(r1)
>> 
>> Here "38 01 81 e8" is the raw instruction representation. In powerpc,
>> this translates to instruction form: "ld RT,DS(RA)" and binary code
>> as:
>> _
>> | 58 |  RT  |  RA |  DS   | |
>> -
>> 06 1116  30 31
>> 
>> Function "disasm_line__parse" is updated to capture:
>> 
>> line:38 01 81 e8 ld  r4,312(r1)
>> opcode and raw instruction "38 01 81 e8"
>> Raw instruction is used later to extract the reg/offset fields.
>> 
>> Signed-off-by: Athira Rajeev 
>> ---



Re: [PATCH V2 4/9] tools/perf: Add support to capture and parse raw instruction in objdump

2024-05-07 Thread Christophe Leroy


Le 06/05/2024 à 14:19, Athira Rajeev a écrit :
> Add support to capture and parse raw instruction in objdump.

What's the purpose of using 'objdump' for reading raw instructions ? 
Can't they be read directly without invoking 'objdump' ? It looks odd to 
me to use objdump to provide readable text and then parse it back.

> Currently, the perf tool infrastructure uses "--no-show-raw-insn" option
> with "objdump" while disassemble. Example from powerpc with this option
> for an instruction address is:

Yes and that makes sense because the purpose of objdump is to provide 
human readable annotations, not to perform automated analysis. Am I 
missing something ?

> 
> Snippet from:
> objdump  --start-address= --stop-address=  -d 
> --no-show-raw-insn -C 
> 
> c10224b4: lwz r10,0(r9)
> 
> This line "lwz r10,0(r9)" is parsed to extract instruction name,
> registers names and offset. Also to find whether there is a memory
> reference in the operands, "memory_ref_char" field of objdump is used.
> For x86, "(" is used as memory_ref_char to tackle instructions of the
> form "mov  (%rax), %rcx".
> 
> In case of powerpc, not all instructions using "(" are the only memory
> instructions. Example, above instruction can also be of extended form (X
> form) "lwzx r10,0,r19". Inorder to easy identify the instruction category
> and extract the source/target registers, patch adds support to use raw
> instruction. With raw instruction, macros are added to extract opcode
> and register fields.
> 
> "struct ins_operands" and "struct ins" is updated to carry opcode and
> raw instruction binary code (raw_insn). Function "disasm_line__parse"
> is updated to fill the raw instruction hex value and opcode in newly
> added fields. There is no changes in existing code paths, which parses
> the disassembled code. The architecture using the instruction name and
> present approach is not altered. Since this approach targets powerpc,
> the macro implementation is added for powerpc as of now.
> 
> Example:
> representation using --show-raw-insn in objdump gives result:
> 
> 38 01 81 e8 ld  r4,312(r1)
> 
> Here "38 01 81 e8" is the raw instruction representation. In powerpc,
> this translates to instruction form: "ld RT,DS(RA)" and binary code
> as:
> _
> | 58 |  RT  |  RA |  DS   | |
> -
> 06 1116  30 31
> 
> Function "disasm_line__parse" is updated to capture:
> 
> line:38 01 81 e8 ld  r4,312(r1)
> opcode and raw instruction "38 01 81 e8"
> Raw instruction is used later to extract the reg/offset fields.
> 
> Signed-off-by: Athira Rajeev 
> ---


Re: [PATCH V2 4/9] tools/perf: Add support to capture and parse raw instruction in objdump

2024-05-06 Thread Namhyung Kim
On Mon, May 6, 2024 at 5:21 AM Athira Rajeev
 wrote:
>
> Add support to capture and parse raw instruction in objdump.
> Currently, the perf tool infrastructure uses "--no-show-raw-insn" option
> with "objdump" while disassemble. Example from powerpc with this option
> for an instruction address is:
>
> Snippet from:
> objdump  --start-address= --stop-address=  -d 
> --no-show-raw-insn -C 
>
> c10224b4:   lwz r10,0(r9)
>
> This line "lwz r10,0(r9)" is parsed to extract instruction name,
> registers names and offset. Also to find whether there is a memory
> reference in the operands, "memory_ref_char" field of objdump is used.
> For x86, "(" is used as memory_ref_char to tackle instructions of the
> form "mov  (%rax), %rcx".
>
> In case of powerpc, not all instructions using "(" are the only memory
> instructions. Example, above instruction can also be of extended form (X
> form) "lwzx r10,0,r19". Inorder to easy identify the instruction category
> and extract the source/target registers, patch adds support to use raw
> instruction. With raw instruction, macros are added to extract opcode
> and register fields.
>
> "struct ins_operands" and "struct ins" is updated to carry opcode and
> raw instruction binary code (raw_insn). Function "disasm_line__parse"
> is updated to fill the raw instruction hex value and opcode in newly
> added fields. There is no changes in existing code paths, which parses
> the disassembled code. The architecture using the instruction name and
> present approach is not altered. Since this approach targets powerpc,
> the macro implementation is added for powerpc as of now.
>
> Example:
> representation using --show-raw-insn in objdump gives result:
>
> 38 01 81 e8 ld  r4,312(r1)
>
> Here "38 01 81 e8" is the raw instruction representation. In powerpc,
> this translates to instruction form: "ld RT,DS(RA)" and binary code
> as:
> _
> | 58 |  RT  |  RA |  DS   | |
> -
> 06 1116  30 31
>
> Function "disasm_line__parse" is updated to capture:
>
> line:38 01 81 e8 ld  r4,312(r1)
> opcode and raw instruction "38 01 81 e8"
> Raw instruction is used later to extract the reg/offset fields.
>
> Signed-off-by: Athira Rajeev 
> ---
>  tools/include/linux/string.h  |  2 +
>  tools/lib/string.c| 13 +++
>  tools/perf/arch/powerpc/util/dwarf-regs.c | 19 ++
>  tools/perf/util/disasm.c  | 46 +++
>  tools/perf/util/disasm.h  |  6 +++
>  tools/perf/util/include/dwarf-regs.h  |  9 +
>  6 files changed, 88 insertions(+), 7 deletions(-)
>
> diff --git a/tools/include/linux/string.h b/tools/include/linux/string.h
> index db5c99318c79..0acb1fc14e19 100644
> --- a/tools/include/linux/string.h
> +++ b/tools/include/linux/string.h
> @@ -46,5 +46,7 @@ extern char * __must_check skip_spaces(const char *);
>
>  extern char *strim(char *);
>
> +extern void remove_spaces(char *s);
> +
>  extern void *memchr_inv(const void *start, int c, size_t bytes);
>  #endif /* _TOOLS_LINUX_STRING_H_ */
> diff --git a/tools/lib/string.c b/tools/lib/string.c
> index 8b6892f959ab..21d273e69951 100644
> --- a/tools/lib/string.c
> +++ b/tools/lib/string.c
> @@ -153,6 +153,19 @@ char *strim(char *s)
> return skip_spaces(s);
>  }
>
> +/*
> + * remove_spaces - Removes whitespaces from @s
> + */
> +void remove_spaces(char *s)
> +{
> +   char *d = s;
> +   do {
> +   while (*d == ' ') {
> +   ++d;
> +   }
> +   } while ((*s++ = *d++));
> +}
> +
>  /**
>   * strreplace - Replace all occurrences of character in string.
>   * @s: The string to operate on.
> diff --git a/tools/perf/arch/powerpc/util/dwarf-regs.c 
> b/tools/perf/arch/powerpc/util/dwarf-regs.c
> index 0c4f4caf53ac..e60a71fd846e 100644
> --- a/tools/perf/arch/powerpc/util/dwarf-regs.c
> +++ b/tools/perf/arch/powerpc/util/dwarf-regs.c
> @@ -98,3 +98,22 @@ int regs_query_register_offset(const char *name)
> return roff->ptregs_offset;
> return -EINVAL;
>  }
> +
> +#definePPC_OP(op)  (((op) >> 26) & 0x3F)
> +#define PPC_RA(a)  (((a) >> 16) & 0x1f)
> +#define PPC_RT(t)  (((t) >> 21) & 0x1f)
> +
> +int get_opcode_insn(unsigned int raw_insn)
> +{
> +   return PPC_OP(raw_insn);
> +}
> +
> +int get_source_reg(unsigned int raw_insn)
> +{
> +   return PPC_RA(raw_insn);
> +}
> +
> +int get_target_reg(unsigned int raw_insn)
> +{
> +   return PPC_RT(raw_insn);
> +}
> diff --git a/tools/perf/util/disasm.c b/tools/perf/util/disasm.c
> index 2de66a092cab..85692f73e78f 100644
> --- a/tools/perf/util/disasm.c
> +++ b/tools/perf/util/disasm.c
> @@ -43,7 +43,7 @@ static int call__scnprintf(struct ins *ins, char *bf, 
> size_t size,
>struct ins_operands *ops, int max_ins_name);
>
>  static void ins__sort(st

[PATCH V2 4/9] tools/perf: Add support to capture and parse raw instruction in objdump

2024-05-06 Thread Athira Rajeev
Add support to capture and parse raw instruction in objdump.
Currently, the perf tool infrastructure uses "--no-show-raw-insn" option
with "objdump" while disassemble. Example from powerpc with this option
for an instruction address is:

Snippet from:
objdump  --start-address= --stop-address=  -d 
--no-show-raw-insn -C 

c10224b4:   lwz r10,0(r9)

This line "lwz r10,0(r9)" is parsed to extract instruction name,
registers names and offset. Also to find whether there is a memory
reference in the operands, "memory_ref_char" field of objdump is used.
For x86, "(" is used as memory_ref_char to tackle instructions of the
form "mov  (%rax), %rcx".

In case of powerpc, not all instructions using "(" are the only memory
instructions. Example, above instruction can also be of extended form (X
form) "lwzx r10,0,r19". Inorder to easy identify the instruction category
and extract the source/target registers, patch adds support to use raw
instruction. With raw instruction, macros are added to extract opcode
and register fields.

"struct ins_operands" and "struct ins" is updated to carry opcode and
raw instruction binary code (raw_insn). Function "disasm_line__parse"
is updated to fill the raw instruction hex value and opcode in newly
added fields. There is no changes in existing code paths, which parses
the disassembled code. The architecture using the instruction name and
present approach is not altered. Since this approach targets powerpc,
the macro implementation is added for powerpc as of now.

Example:
representation using --show-raw-insn in objdump gives result:

38 01 81 e8 ld  r4,312(r1)

Here "38 01 81 e8" is the raw instruction representation. In powerpc,
this translates to instruction form: "ld RT,DS(RA)" and binary code
as:
_
| 58 |  RT  |  RA |  DS   | |
-
06 1116  30 31

Function "disasm_line__parse" is updated to capture:

line:38 01 81 e8 ld  r4,312(r1)
opcode and raw instruction "38 01 81 e8"
Raw instruction is used later to extract the reg/offset fields.

Signed-off-by: Athira Rajeev 
---
 tools/include/linux/string.h  |  2 +
 tools/lib/string.c| 13 +++
 tools/perf/arch/powerpc/util/dwarf-regs.c | 19 ++
 tools/perf/util/disasm.c  | 46 +++
 tools/perf/util/disasm.h  |  6 +++
 tools/perf/util/include/dwarf-regs.h  |  9 +
 6 files changed, 88 insertions(+), 7 deletions(-)

diff --git a/tools/include/linux/string.h b/tools/include/linux/string.h
index db5c99318c79..0acb1fc14e19 100644
--- a/tools/include/linux/string.h
+++ b/tools/include/linux/string.h
@@ -46,5 +46,7 @@ extern char * __must_check skip_spaces(const char *);
 
 extern char *strim(char *);
 
+extern void remove_spaces(char *s);
+
 extern void *memchr_inv(const void *start, int c, size_t bytes);
 #endif /* _TOOLS_LINUX_STRING_H_ */
diff --git a/tools/lib/string.c b/tools/lib/string.c
index 8b6892f959ab..21d273e69951 100644
--- a/tools/lib/string.c
+++ b/tools/lib/string.c
@@ -153,6 +153,19 @@ char *strim(char *s)
return skip_spaces(s);
 }
 
+/*
+ * remove_spaces - Removes whitespaces from @s
+ */
+void remove_spaces(char *s)
+{
+   char *d = s;
+   do {
+   while (*d == ' ') {
+   ++d;
+   }
+   } while ((*s++ = *d++));
+}
+
 /**
  * strreplace - Replace all occurrences of character in string.
  * @s: The string to operate on.
diff --git a/tools/perf/arch/powerpc/util/dwarf-regs.c 
b/tools/perf/arch/powerpc/util/dwarf-regs.c
index 0c4f4caf53ac..e60a71fd846e 100644
--- a/tools/perf/arch/powerpc/util/dwarf-regs.c
+++ b/tools/perf/arch/powerpc/util/dwarf-regs.c
@@ -98,3 +98,22 @@ int regs_query_register_offset(const char *name)
return roff->ptregs_offset;
return -EINVAL;
 }
+
+#definePPC_OP(op)  (((op) >> 26) & 0x3F)
+#define PPC_RA(a)  (((a) >> 16) & 0x1f)
+#define PPC_RT(t)  (((t) >> 21) & 0x1f)
+
+int get_opcode_insn(unsigned int raw_insn)
+{
+   return PPC_OP(raw_insn);
+}
+
+int get_source_reg(unsigned int raw_insn)
+{
+   return PPC_RA(raw_insn);
+}
+
+int get_target_reg(unsigned int raw_insn)
+{
+   return PPC_RT(raw_insn);
+}
diff --git a/tools/perf/util/disasm.c b/tools/perf/util/disasm.c
index 2de66a092cab..85692f73e78f 100644
--- a/tools/perf/util/disasm.c
+++ b/tools/perf/util/disasm.c
@@ -43,7 +43,7 @@ static int call__scnprintf(struct ins *ins, char *bf, size_t 
size,
   struct ins_operands *ops, int max_ins_name);
 
 static void ins__sort(struct arch *arch);
-static int disasm_line__parse(char *line, const char **namep, char **rawp);
+static int disasm_line__parse(char *line, const char **namep, char **rawp, int 
*opcode, int *rawp_insn);
 
 static __attribute__((constructor)) void symbol__init_regexpr(void)
 {
@@ -512,7 +512,7 @@ static