All of lore.kernel.org
 help / color / mirror / Atom feed
* pahole and parsing data: --count
       [not found]                   ` <0eae329c-d448-4d04-c240-0850a93278a5-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
@ 2020-07-01 11:25                     ` Arnaldo Carvalho de Melo
       [not found]                       ` <20200701112534.GQ29008-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
  0 siblings, 1 reply; 3+ messages in thread
From: Arnaldo Carvalho de Melo @ 2020-07-01 11:25 UTC (permalink / raw)
  To: dwarves-u79uwXL29TY76Z2rM5mHXA; +Cc: Joe Lawrence

Hi,

	I've been implementing pretty printing in pahole:

[acme@quaco pahole]$ git log --oneline v1.17..
5631fdcea1bb (HEAD -> master, acme.korg/pretty, acme.korg/master) pahole: Introduce --count, just like dd's
272bc75024b4 man-pages: Add information about stdin raw data pretty printing
66835f9e190c pahole: Add support for base type arrays
1a67d6e70090 pahole: Factor out base_type__fprintf_value()
6fb98aa1209f pahole: Support char arrays when dumping from stdin
a231d00f8d08 pahole: Print comma at the end of field name + field value
1b2cdda38c0a dwarves: Introduce tag__is_array()
a83313fb2252 pahole: Pretty print base types in structs from stdin
cc65946e3068 dwarves: Adopt tag__is_base_type() from ctrace.c
d8079c6d373a pahole: Hex dump a type from stdio when it isn't a tty
38109ab45fe0 spec: Fix date
[acme@quaco pahole]$

	The latest changeset shows what this is about, see its example
below, please help testing and suggesting whatever needs you have
regarding pretty printing.

	Now to implement --skip.

Regards,

- Arnaldo

From 5631fdcea1bbe2bcb8c673ff0bb0fdc9fdc2875d Mon Sep 17 00:00:00 2001
From: Arnaldo Carvalho de Melo <acme-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
Date: Wed, 1 Jul 2020 08:14:58 -0300
Subject: [PATCH] pahole: Introduce --count, just like dd's

  $ objcopy -O binary --only-section=.altinstructions ~/git/build/v5.7-rc2+/vmlinux .altinstructions
  $ pahole --count 2 alt_instr  < .altinstructions
  {
  	.instr_offset = 0xffffffffffe0e690,
  	.repl_offset = 0x4873,
  	.cpuid = 0x70,
  	.instrlen = 0x5,
  	.replacementlen = 0x5,
  	.padlen = 0,
  },
  {
  	.instr_offset = 0xffffffffffe0e683,
  	.repl_offset = 0x486b,
  	.cpuid = 0x129,
  	.instrlen = 0x5,
  	.replacementlen = 0x5,
  	.padlen = 0,
  },
  $

Signed-off-by: Arnaldo Carvalho de Melo <acme-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
---
 dwarves.h          |  2 ++
 man-pages/pahole.1 |  8 +++++++-
 pahole.c           | 13 +++++++++++++
 3 files changed, 22 insertions(+), 1 deletion(-)

diff --git a/dwarves.h b/dwarves.h
index 0170f251bcd4..f224d05b28c3 100644
--- a/dwarves.h
+++ b/dwarves.h
@@ -54,6 +54,7 @@ struct conf_load {
 
 /** struct conf_fprintf - hints to the __fprintf routines
  *
+ * @count - Just like 'dd', stop pretty printing input after 'count' records
  * @flat_arrays - a->foo[10][2] becomes a->foo[20]
  * @classes_as_structs - class f becomes struct f, CTF doesn't have a "class"
  * @cachelinep - pointer to current cacheline, so that when expanding types we keep track of it,
@@ -68,6 +69,7 @@ struct conf_fprintf {
 	int32_t	   type_spacing;
 	int32_t	   name_spacing;
 	uint32_t   base_offset;
+	uint32_t   count;
 	uint32_t   *cachelinep;
 	uint8_t	   indent;
 	uint8_t	   expand_types:1;
diff --git a/man-pages/pahole.1 b/man-pages/pahole.1
index 26c14cb6fd2c..7e8207756432 100644
--- a/man-pages/pahole.1
+++ b/man-pages/pahole.1
@@ -60,6 +60,8 @@ See the EXAMPLES section for more usage suggestions.
 It also pretty prints whatever is fed to its standard input, according to the
 type specified, see the EXAMPLE session.
 
+Use --count to state how many records should be pretty printed.
+
 .SH OPTIONS
 pahole supports the following options.
 
@@ -72,6 +74,10 @@ or file URLs (e.g.: file://class_list.txt)
 .B \-c, \-\-cacheline_size=SIZE
 Set cacheline size to SIZE bytes.
 
+.TP
+.B \-\-count=COUNT
+Pretty print the first COUNT records from input.
+
 .TP
 .B \-E, \-\-expand_types
 Expand class members. Useful to find in what member of inner structs where an
@@ -482,7 +488,7 @@ $
 $ ls -la versions
 -rw-rw-r--. 1 acme acme 7616 Jun 25 11:33 versions
 $
-$ pahole -C modversion_info drivers/scsi/sg.ko < versions | head -12
+$ pahole --count 3 -C modversion_info drivers/scsi/sg.ko < versions
 {
       .crc = 0x8dabd84,
       .name = "module_layout",
diff --git a/pahole.c b/pahole.c
index 03909525bf15..1b84f5c2fa4a 100644
--- a/pahole.c
+++ b/pahole.c
@@ -802,6 +802,7 @@ ARGP_PROGRAM_VERSION_HOOK_DEF = dwarves_print_version;
 #define ARGP_suppress_packed	   308
 #define ARGP_just_unions	   309
 #define ARGP_just_structs	   310
+#define ARGP_count		   311
 
 static const struct argp_option pahole__options[] = {
 	{
@@ -822,6 +823,12 @@ static const struct argp_option pahole__options[] = {
 		.arg  = "CLASS_NAME",
 		.doc  = "Show just this class"
 	},
+	{
+		.name = "count",
+		.key  = ARGP_count,
+		.arg  = "COUNT",
+		.doc  = "Print only COUNT input records"
+	},
 	{
 		.name = "find_pointers_to",
 		.key  = 'f',
@@ -1145,6 +1152,8 @@ static error_t pahole__options_parser(int key, char *arg,
 		just_unions = true;			break;
 	case ARGP_just_structs:
 		just_structs = true;			break;
+	case ARGP_count:
+		conf.count = atoi(arg);			break;
 	default:
 		return ARGP_ERR_UNKNOWN;
 	}
@@ -1315,6 +1324,7 @@ static int tag__stdio_fprintf_value(struct tag *type, struct cu *cu, FILE *fp)
 {
 	int _sizeof = tag__size(type, cu), printed = 0;
 	void *instance = malloc(_sizeof);
+	uint32_t count = 0;
 
 	if (instance == NULL)
 		return -ENOMEM;
@@ -1322,6 +1332,9 @@ static int tag__stdio_fprintf_value(struct tag *type, struct cu *cu, FILE *fp)
 	while (fread(instance, _sizeof, 1, stdin) == 1) {
 		printed += tag__fprintf_value(type, cu, instance, _sizeof, fp);
 		printed += fprintf(fp, ",\n");
+
+		if (conf.count && ++count == conf.count)
+			break;
 	}
 
 	return printed;
-- 
2.21.3

^ permalink raw reply related	[flat|nested] 3+ messages in thread

* pahole and parsing data: --skip
       [not found]                       ` <20200701112534.GQ29008-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
@ 2020-07-01 11:44                         ` Arnaldo Carvalho de Melo
       [not found]                           ` <20200701114421.GR29008-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
  0 siblings, 1 reply; 3+ messages in thread
From: Arnaldo Carvalho de Melo @ 2020-07-01 11:44 UTC (permalink / raw)
  To: dwarves-u79uwXL29TY76Z2rM5mHXA; +Cc: Joe Lawrence, Jiri Olsa, Namhyung Kim

Em Wed, Jul 01, 2020 at 08:25:34AM -0300, Arnaldo Carvalho de Melo escreveu:
> 	The latest changeset shows what this is about, see its example
> below, please help testing and suggesting whatever needs you have
> regarding pretty printing.
> 
> 	Now to implement --skip.

Now to implement --seek, this time in bytes, so that we can, for
instance, pretty print perf.data records, looking at 'perf report -D'
and getting the offset of the start of a series of 'struct
perf_event_attr' or 'struct perf_event_header'.

- Arnaldo

commit 44af7c02b5d0a7f2b93fab9fda45907cd6fe0827
Author: Arnaldo Carvalho de Melo <acme-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
Date:   Wed Jul 1 08:36:28 2020 -0300

    pahole: Implement --skip, just like dd
    
      $ objcopy -O binary --only-section=__versions drivers/scsi/sg.ko versions
      $ pahole -C modversion_info drivers/scsi/sg.ko
      struct modversion_info {
            long unsigned int          crc;                  /*     0     8 */
            char                       name[56];             /*     8    56 */
    
            /* size: 64, cachelines: 1, members: 2 */
      };
      $ pahole --count 3 -C modversion_info drivers/scsi/sg.ko < versions
      {
            .crc = 0x8dabd84,
            .name = "module_layout",
      },
      {
            .crc = 0x45e4617b,
            .name = "no_llseek",
      },
      {
            .crc = 0xa23fae8c,
            .name = "param_ops_int",
      },
      $ pahole --skip 1 --count 2 -C modversion_info drivers/scsi/sg.ko < versions
      {
            .crc = 0x45e4617b,
            .name = "no_llseek",
      },
      {
            .crc = 0xa23fae8c,
            .name = "param_ops_int",
      },
      $
    
    Signed-off-by: Arnaldo Carvalho de Melo <acme-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>

diff --git a/dwarves.h b/dwarves.h
index f224d05b28c3..24f9c7c37843 100644
--- a/dwarves.h
+++ b/dwarves.h
@@ -55,6 +55,7 @@ struct conf_load {
 /** struct conf_fprintf - hints to the __fprintf routines
  *
  * @count - Just like 'dd', stop pretty printing input after 'count' records
+ * @skip - Just like 'dd', skip 'count' records when pretty printing input
  * @flat_arrays - a->foo[10][2] becomes a->foo[20]
  * @classes_as_structs - class f becomes struct f, CTF doesn't have a "class"
  * @cachelinep - pointer to current cacheline, so that when expanding types we keep track of it,
@@ -71,6 +72,7 @@ struct conf_fprintf {
 	uint32_t   base_offset;
 	uint32_t   count;
 	uint32_t   *cachelinep;
+	uint32_t   skip;
 	uint8_t	   indent;
 	uint8_t	   expand_types:1;
 	uint8_t	   expand_pointers:1;
diff --git a/man-pages/pahole.1 b/man-pages/pahole.1
index 7e8207756432..db820cca323f 100644
--- a/man-pages/pahole.1
+++ b/man-pages/pahole.1
@@ -78,6 +78,10 @@ Set cacheline size to SIZE bytes.
 .B \-\-count=COUNT
 Pretty print the first COUNT records from input.
 
+.TP
+.B \-\-skip=COUNT
+Skip COUNT input records.
+
 .TP
 .B \-E, \-\-expand_types
 Expand class members. Useful to find in what member of inner structs where an
@@ -502,6 +506,16 @@ $ pahole --count 3 -C modversion_info drivers/scsi/sg.ko < versions
       .name = "param_ops_int",
 },
 $
+$ pahole --skip 1 --count 2 -C modversion_info drivers/scsi/sg.ko < versions
+{
+      .crc = 0x45e4617b,
+      .name = "no_llseek",
+},
+{
+      .crc = 0xa23fae8c,
+      .name = "param_ops_int",
+},
+$
 .fi
 .P
 
diff --git a/pahole.c b/pahole.c
index 1b84f5c2fa4a..7d8431c64423 100644
--- a/pahole.c
+++ b/pahole.c
@@ -803,6 +803,7 @@ ARGP_PROGRAM_VERSION_HOOK_DEF = dwarves_print_version;
 #define ARGP_just_unions	   309
 #define ARGP_just_structs	   310
 #define ARGP_count		   311
+#define ARGP_skip		   312
 
 static const struct argp_option pahole__options[] = {
 	{
@@ -829,6 +830,12 @@ static const struct argp_option pahole__options[] = {
 		.arg  = "COUNT",
 		.doc  = "Print only COUNT input records"
 	},
+	{
+		.name = "skip",
+		.key  = ARGP_skip,
+		.arg  = "COUNT",
+		.doc  = "Skip COUNT input records"
+	},
 	{
 		.name = "find_pointers_to",
 		.key  = 'f',
@@ -1154,6 +1161,8 @@ static error_t pahole__options_parser(int key, char *arg,
 		just_structs = true;			break;
 	case ARGP_count:
 		conf.count = atoi(arg);			break;
+	case ARGP_skip:
+		conf.skip = atoi(arg);			break;
 	default:
 		return ARGP_ERR_UNKNOWN;
 	}
@@ -1325,11 +1334,17 @@ static int tag__stdio_fprintf_value(struct tag *type, struct cu *cu, FILE *fp)
 	int _sizeof = tag__size(type, cu), printed = 0;
 	void *instance = malloc(_sizeof);
 	uint32_t count = 0;
+	uint32_t skip = conf.skip;
 
 	if (instance == NULL)
 		return -ENOMEM;
 
 	while (fread(instance, _sizeof, 1, stdin) == 1) {
+		if (skip) {
+			--skip;
+			continue;
+		}
+
 		printed += tag__fprintf_value(type, cu, instance, _sizeof, fp);
 		printed += fprintf(fp, ",\n");
 

^ permalink raw reply related	[flat|nested] 3+ messages in thread

* pahole and parsing data: --seek_bytes, dissecting perf.data files
       [not found]                           ` <20200701114421.GR29008-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
@ 2020-07-01 12:46                             ` Arnaldo Carvalho de Melo
  0 siblings, 0 replies; 3+ messages in thread
From: Arnaldo Carvalho de Melo @ 2020-07-01 12:46 UTC (permalink / raw)
  To: dwarves-u79uwXL29TY76Z2rM5mHXA
  Cc: Joe Lawrence, Jiri Olsa, Namhyung Kim, Andrii Nakryiko, Song Liu

Em Wed, Jul 01, 2020 at 08:44:21AM -0300, Arnaldo Carvalho de Melo escreveu:
> Em Wed, Jul 01, 2020 at 08:25:34AM -0300, Arnaldo Carvalho de Melo escreveu:
> > 	The latest changeset shows what this is about, see its example
> > below, please help testing and suggesting whatever needs you have
> > regarding pretty printing.
> > 
> > 	Now to implement --skip.

> Now to implement --seek, this time in bytes, so that we can, for
> instance, pretty print perf.data records, looking at 'perf report -D'
> and getting the offset of the start of a series of 'struct
> perf_event_attr' or 'struct perf_event_header'.

Here it is with more complex examples dissecting perf.data file data
structures, including BPF related structs:

commit fe284221448c950d2ba17bce91d19c484d6580a0
Author: Arnaldo Carvalho de Melo <acme-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
Date:   Wed Jul 1 09:17:38 2020 -0300

    pahole: Introduce --seek_bytes
    
    Works with stdio, will work with files where we'll use plain lseek and
    allow for pretty printing trailer structs.
    
    E.g.:
    
      $ objcopy -O binary --only-section=__versions drivers/scsi/sg.ko versions
      $ pahole -C modversion_info drivers/scsi/sg.ko
      struct modversion_info {
              long unsigned int          crc;                  /*     0     8 */
              char                       name[56];             /*     8    56 */
    
              /* size: 64, cachelines: 1, members: 2 */
      };
      $ pahole --count 2 -C modversion_info drivers/scsi/sg.ko < versions
      {
            .crc = 0x8dabd84,
            .name = "module_layout",
      },
      {
            .crc = 0x45e4617b,
            .name = "no_llseek",
      },
      $ pahole --skip 1 --count 1 -C modversion_info drivers/scsi/sg.ko < versions
      {
            .crc = 0x45e4617b,
            .name = "no_llseek",
      },
    
    Then the equivalent, skipping sizeof(modversion_info) explicitely:
    
      $ pahole --seek_bytes 64 --count 1 -C modversion_info drivers/scsi/sg.ko < versions
      {
            .crc = 0x45e4617b,
            .name = "no_llseek",
      },
      $
    
    Using a perf.data file generated by 'perf record':
    
      $ perf report -D | head -18
      # To display the perf.data header info, please use --header/--header-only options.
      #
    
      0x130 [0x20]: event: 79
      .
      . ... raw event: size 32 bytes
      .  0000:  4f 00 00 00 00 00 20 00 1f 00 00 00 00 00 00 00  O..... .........
      .  0010:  31 30 9b 3c 00 00 00 00 2e 53 f8 0c 52 8c 01 00  10.<.....S�.R...
    
      0 0x130 [0x20]: PERF_RECORD_TIME_CONV: unhandled!
    
      0x150 [0x28]: event: 73
      .
      . ... raw event: size 40 bytes
      .  0000:  49 00 00 00 00 00 28 00 01 00 00 00 00 00 00 00  I.....(.........
      .  0010:  50 7e 00 00 00 00 00 00 00 00 00 00 00 00 00 00  P~..............
      .  0020:  00 00 00 00 00 00 00 00                          ........
    
      $ pahole --seek_bytes 0x130 --count 1 -C perf_event_header < perf.data
      {
            .type = 0x4f,
            .misc = 0,
            .size = 0x20,
      },
      $ printf "0x%x\n" 79
      0x4f
      $ pahole --seek_bytes 0x150 --count 1 -C perf_event_header < perf.data
      {
            .type = 0x49,
            .misc = 0,
            .size = 0x28,
      },
      $ printf "0x%x\n" 73
      0x49
      $
    
    Now to use more complex types, again using perf.data files.
    
      # perf record -a sleep 1
      [ perf record: Woken up 1 times to write data ]
      [ perf record: Captured and wrote 3.834 MB perf.data (31853 samples) ]
      # perf report -D | grep -m1 -B20 PERF_RECORD_BPF
      0x6aa0 [0x58]: event: 17
      .
      . ... raw event: size 88 bytes
      .  0020:  5f 37 62 65 34 39 65 33 39 33 34 61 31 32 35 62  _7be49e3934a125b
      .  0030:  61 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  a...............
      .  0040:  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
      .  0050:  00 00 00 00 00 00 00 00                          ........
    
      0 0 0x6aa0 [0x58]: PERF_RECORD_KSYMBOL addr ffffffffc03e0e90 len 203 type 1 flags 0x0 name bpf_prog_7be49e3934a125ba
    
      0x6af8 [0x38]: event: 18
      .
      . ... raw event: size 56 bytes
      .  0000:  12 00 00 00 00 00 38 00 01 00 00 00 11 00 00 00  ......8.........
      .  0020:  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
      .  0030:  00 00 00 00 00 00 00 00                          ........
    
      0 0 0x6af8 [0x38]: PERF_RECORD_BPF_EVENT type 1, flags 0, id 17
      Binary file (standard input) matches
      # pahole -C perf_record_bpf_event ~/bin/perf
      struct perf_record_bpf_event {
            struct perf_event_header   header;               /*     0     8 */
            __u16                      type;                 /*     8     2 */
            __u16                      flags;                /*    10     2 */
            __u32                      id;                   /*    12     4 */
            __u8                       tag[8];               /*    16     8 */
    
            /* size: 24, cachelines: 1, members: 5 */
            /* last cacheline: 24 bytes */
      };
      # pahole -C perf_record_bpf_event --seek_bytes 0x6af8 --count 1 ~/bin/perf < perf.data
      {
            .header = 0x12 0x00 0x00 0x00 0x00 0x00 0x38 0x00,
            .type = 0x1,
            .flags = 0,
            .id = 0x11,
            .tag = { 0, 0, 0, 0, 0, 0, 0, 0},
      },
      # printf "0x%x\n" 18
      0x12
      # pahole -C perf_record_ksymbol ~/bin/perf
      struct perf_record_ksymbol {
            struct perf_event_header   header;               /*     0     8 */
            __u64                      addr;                 /*     8     8 */
            __u32                      len;                  /*    16     4 */
            __u16                      ksym_type;            /*    20     2 */
            __u16                      flags;                /*    22     2 */
            char                       name[256];            /*    24   256 */
    
            /* size: 280, cachelines: 5, members: 6 */
            /* last cacheline: 24 bytes */
      };
      # pahole -C perf_record_ksymbol --seek_bytes 0x6aa0 --count 1 ~/bin/perf < perf.data
      {
            .header = 0x11 0x00 0x00 0x00 0x00 0x00 0x58 0x00,
            .addr = 0xffffffffc03e0e90,
            .len = 0xcb,
            .ksym_type = 0x1,
            .flags = 0,
            .name = "bpf_prog_7be49e3934a125ba",
      },
      # printf "0x%x\n" 17
      0x11
      #
    
    Need to recursively pretty print substructs, but all seems to work with
    the simple hexdump.
    
    Signed-off-by: Arnaldo Carvalho de Melo <acme-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>

diff --git a/dwarves.h b/dwarves.h
index 24f9c7c37843..1b118d03ec15 100644
--- a/dwarves.h
+++ b/dwarves.h
@@ -13,6 +13,7 @@
 #include <obstack.h>
 #include <dwarf.h>
 #include <elfutils/libdwfl.h>
+#include <sys/types.h>
 
 #include "dutil.h"
 #include "list.h"
@@ -56,6 +57,7 @@ struct conf_load {
  *
  * @count - Just like 'dd', stop pretty printing input after 'count' records
  * @skip - Just like 'dd', skip 'count' records when pretty printing input
+ * @seek_bytes - Number of bytes to seek, if stdin only from start, when we have --pretty FILE, then from the end as well with negative numbers
  * @flat_arrays - a->foo[10][2] becomes a->foo[20]
  * @classes_as_structs - class f becomes struct f, CTF doesn't have a "class"
  * @cachelinep - pointer to current cacheline, so that when expanding types we keep track of it,
@@ -72,6 +74,7 @@ struct conf_fprintf {
 	uint32_t   base_offset;
 	uint32_t   count;
 	uint32_t   *cachelinep;
+	off_t	   seek_bytes;
 	uint32_t   skip;
 	uint8_t	   indent;
 	uint8_t	   expand_types:1;
diff --git a/man-pages/pahole.1 b/man-pages/pahole.1
index db820cca323f..ad4e92d716cf 100644
--- a/man-pages/pahole.1
+++ b/man-pages/pahole.1
@@ -516,6 +516,14 @@ $ pahole --skip 1 --count 2 -C modversion_info drivers/scsi/sg.ko < versions
       .name = "param_ops_int",
 },
 $
+This is equivalent to:
+
+$ pahole --seek_bytes 64 --count 1 -C modversion_info drivers/scsi/sg.ko < versions
+{
+	.crc = 0x45e4617b,
+	.name = "no_llseek",
+},
+$
 .fi
 .P
 
diff --git a/pahole.c b/pahole.c
index 7d8431c64423..245a3f2f14f7 100644
--- a/pahole.c
+++ b/pahole.c
@@ -3,7 +3,7 @@
 
   Copyright (C) 2006 Mandriva Conectiva S.A.
   Copyright (C) 2006 Arnaldo Carvalho de Melo <acme-4qZELD6FgxhWk0Htik3J/w@public.gmane.org>
-  Copyright (C) 2007-2008 Arnaldo Carvalho de Melo <acme-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
+  Copyright (C) 2007- Arnaldo Carvalho de Melo <acme-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
 */
 
 #include <argp.h>
@@ -804,6 +804,7 @@ ARGP_PROGRAM_VERSION_HOOK_DEF = dwarves_print_version;
 #define ARGP_just_structs	   310
 #define ARGP_count		   311
 #define ARGP_skip		   312
+#define ARGP_seek_bytes		   313
 
 static const struct argp_option pahole__options[] = {
 	{
@@ -836,6 +837,12 @@ static const struct argp_option pahole__options[] = {
 		.arg  = "COUNT",
 		.doc  = "Skip COUNT input records"
 	},
+	{
+		.name = "seek_bytes",
+		.key  = ARGP_seek_bytes,
+		.arg  = "BYTES",
+		.doc  = "Seek COUNT input records"
+	},
 	{
 		.name = "find_pointers_to",
 		.key  = 'f',
@@ -1163,6 +1170,8 @@ static error_t pahole__options_parser(int key, char *arg,
 		conf.count = atoi(arg);			break;
 	case ARGP_skip:
 		conf.skip = atoi(arg);			break;
+	case ARGP_seek_bytes:
+		conf.seek_bytes = strtol(arg, NULL, 0);	break;
 	default:
 		return ARGP_ERR_UNKNOWN;
 	}
@@ -1329,6 +1338,25 @@ static int tag__fprintf_value(struct tag *type, struct cu *cu, void *instance, i
 	return tag__fprintf_hexdump_value(type, cu, instance, _sizeof, fp);
 }
 
+static int pipe_seek(FILE *fp, off_t offset)
+{
+	char bf[4096];
+	int chunk = sizeof(bf);
+
+	if (chunk > offset)
+		chunk = offset;
+
+	while (fread(bf, chunk, 1, stdin) == 1) {
+		offset -= chunk;
+		if (offset == 0)
+			return 0;
+		if (chunk > offset)
+			chunk = offset;
+	}
+
+	return offset == 0 ? 0 : -1;
+}
+
 static int tag__stdio_fprintf_value(struct tag *type, struct cu *cu, FILE *fp)
 {
 	int _sizeof = tag__size(type, cu), printed = 0;
@@ -1339,6 +1367,12 @@ static int tag__stdio_fprintf_value(struct tag *type, struct cu *cu, FILE *fp)
 	if (instance == NULL)
 		return -ENOMEM;
 
+	if (conf.seek_bytes && pipe_seek(stdin, conf.seek_bytes) < 0) {
+		int err = --errno;
+		fprintf(stderr, "Couldn't --seek_bytes %ld\n", conf.seek_bytes);
+		return err;
+	}
+
 	while (fread(instance, _sizeof, 1, stdin) == 1) {
 		if (skip) {
 			--skip;

^ permalink raw reply related	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2020-07-01 12:46 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <20200623165646.GA2251@redhat.com>
     [not found] ` <e52cf45d-311f-85c7-d358-5592d3666092@redhat.com>
     [not found]   ` <20200624173038.GC20203@kernel.org>
     [not found]     ` <20200624185748.GA16165@redhat.com>
     [not found]       ` <20200624190716.GA4139@redhat.com>
     [not found]         ` <a5238972-e36e-3abe-aa14-5dcca58c46fb@redhat.com>
     [not found]           ` <20200625113816.GA29008@kernel.org>
     [not found]             ` <20200625114129.GB29008@kernel.org>
     [not found]               ` <20200625160326.GA10325@kernel.org>
     [not found]                 ` <0eae329c-d448-4d04-c240-0850a93278a5@redhat.com>
     [not found]                   ` <0eae329c-d448-4d04-c240-0850a93278a5-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
2020-07-01 11:25                     ` pahole and parsing data: --count Arnaldo Carvalho de Melo
     [not found]                       ` <20200701112534.GQ29008-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
2020-07-01 11:44                         ` pahole and parsing data: --skip Arnaldo Carvalho de Melo
     [not found]                           ` <20200701114421.GR29008-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
2020-07-01 12:46                             ` pahole and parsing data: --seek_bytes, dissecting perf.data files Arnaldo Carvalho de Melo

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.