xref: /xnu-10063.121.3/libkdd/README.md (revision 2c2f96dc2b9a4408a43d3150ae9c105355ca3daa)
1*2c2f96dcSApple OSS DistributionsKernel Data Descriptors
2*2c2f96dcSApple OSS Distributions=======================
3*2c2f96dcSApple OSS Distributions
4*2c2f96dcSApple OSS DistributionsThis project allows for dynamic data to be passed from the kernel to userspace tools without binding them to particular version of
5*2c2f96dcSApple OSS Distributionsstruct definition. The `libkdd` library provides convenient API for parsing and interpreting `kernel chunked data`.
6*2c2f96dcSApple OSS Distributions
7*2c2f96dcSApple OSS DistributionsThe libkdd APIs are defined in [kdd.h](./kdd.h)
8*2c2f96dcSApple OSS Distributions
9*2c2f96dcSApple OSS DistributionsThe `KCDATA` format
10*2c2f96dcSApple OSS Distributions===================
11*2c2f96dcSApple OSS Distributions
12*2c2f96dcSApple OSS DistributionsThe format for data is setup in a generic format as follows
13*2c2f96dcSApple OSS Distributions
14*2c2f96dcSApple OSS DistributionsLayout of data structure
15*2c2f96dcSApple OSS Distributions------------------------
16*2c2f96dcSApple OSS Distributions
17*2c2f96dcSApple OSS Distributions	|         8 - bytes         |
18*2c2f96dcSApple OSS Distributions	|---------------------------|  ------ offset = 00
19*2c2f96dcSApple OSS Distributions	|  type = MAGIC |  LENGTH   |  # BEGIN Header
20*2c2f96dcSApple OSS Distributions	|            0              |
21*2c2f96dcSApple OSS Distributions	|---------------------------|  ------ offset = 16
22*2c2f96dcSApple OSS Distributions	|      type     |  size     |  # chunk header
23*2c2f96dcSApple OSS Distributions	|          flags            |
24*2c2f96dcSApple OSS Distributions	|---------------------------|  ------ offset = 32
25*2c2f96dcSApple OSS Distributions	|           data            |  # arbitrary data (len=16)
26*2c2f96dcSApple OSS Distributions	|___________data____________|
27*2c2f96dcSApple OSS Distributions	|---------------------------|  ------ offset = 48
28*2c2f96dcSApple OSS Distributions	|      type     |   size    |  # chunk header
29*2c2f96dcSApple OSS Distributions	|          flags            |
30*2c2f96dcSApple OSS Distributions	|---------------------------|  ------ offset = 64
31*2c2f96dcSApple OSS Distributions	|           data            |  # arbitrary data (len=32)
32*2c2f96dcSApple OSS Distributions	|           data            |
33*2c2f96dcSApple OSS Distributions	|           data            |
34*2c2f96dcSApple OSS Distributions	|___________data____________|
35*2c2f96dcSApple OSS Distributions	|---------------------------|  ------ offset = 96
36*2c2f96dcSApple OSS Distributions	|  type = END   |  size=0   |  # chunk header
37*2c2f96dcSApple OSS Distributions	|            0              |
38*2c2f96dcSApple OSS Distributions
39*2c2f96dcSApple OSS Distributions
40*2c2f96dcSApple OSS DistributionsThe type field describes what kind of data is passed. For example type = `TASK_CRASHINFO_UUID` means the following data is a uuid.
41*2c2f96dcSApple OSS DistributionsThese types need to be defined in task_corpses.h for easy consumption by userspace inspection tools.
42*2c2f96dcSApple OSS Distributions
43*2c2f96dcSApple OSS DistributionsSome range of types is reserved for special types like ints, longs etc. A cool new functionality made possible with this
44*2c2f96dcSApple OSS Distributionsextensible data format is that kernel can decide to put more information as required without requiring user space tools to
45*2c2f96dcSApple OSS Distributionsre-compile to be compatible. The case of `rusage` struct versions could be introduced without breaking existing tools.
46*2c2f96dcSApple OSS Distributions
47*2c2f96dcSApple OSS DistributionsFeature description: Generic data with description
48*2c2f96dcSApple OSS Distributions-------------------
49*2c2f96dcSApple OSS DistributionsFurther more generic data with description is very much possible now. For example
50*2c2f96dcSApple OSS Distributions
51*2c2f96dcSApple OSS Distributions	- kcdata_add_uint64_with_description(cdatainfo, 0x700, "NUM MACH PORTS");
52*2c2f96dcSApple OSS Distributions	- and more functions that allow adding description.
53*2c2f96dcSApple OSS Distributions
54*2c2f96dcSApple OSS DistributionsThe userspace tools can then look at the description and print the data even if they are not compiled with knowledge of the field apriori.
55*2c2f96dcSApple OSS Distributions
56*2c2f96dcSApple OSS Distributions	Example data:
57*2c2f96dcSApple OSS Distributions	0000  57 f1 ad de 00 00 00 00 00 00 00 00 00 00 00 00  W...............
58*2c2f96dcSApple OSS Distributions	0010  01 00 00 00 00 00 00 00 30 00 00 00 00 00 00 00  ........0.......
59*2c2f96dcSApple OSS Distributions	0020  50 49 44 00 00 00 00 00 00 00 00 00 00 00 00 00  PID.............
60*2c2f96dcSApple OSS Distributions	0030  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
61*2c2f96dcSApple OSS Distributions	0040  9c 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
62*2c2f96dcSApple OSS Distributions	0050  01 00 00 00 00 00 00 00 30 00 00 00 00 00 00 00  ........0.......
63*2c2f96dcSApple OSS Distributions	0060  50 41 52 45 4e 54 20 50 49 44 00 00 00 00 00 00  PARENT PID......
64*2c2f96dcSApple OSS Distributions	0070  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
65*2c2f96dcSApple OSS Distributions	0080  01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
66*2c2f96dcSApple OSS Distributions	0090  ed 58 91 f1
67*2c2f96dcSApple OSS Distributions
68*2c2f96dcSApple OSS Distributions
69*2c2f96dcSApple OSS DistributionsFeature description: Container markers for compound data
70*2c2f96dcSApple OSS Distributions------------------
71*2c2f96dcSApple OSS Distributions
72*2c2f96dcSApple OSS DistributionsIf a given kernel data type is complex and requires adding multiple optional fields inside a container
73*2c2f96dcSApple OSS Distributionsobject for a consumer to understand arbitrary data, we package it using container markers.
74*2c2f96dcSApple OSS Distributions
75*2c2f96dcSApple OSS DistributionsFor example, the stackshot code gathers information and describes the state of a given task with respect
76*2c2f96dcSApple OSS Distributionsto many subsystems. It includes data such as io stats, vm counters, process names/flags and syscall counts.
77*2c2f96dcSApple OSS Distributions
78*2c2f96dcSApple OSS Distributions	kcdata_add_container_marker(kcdata_p, KCDATA_TYPE_CONTAINER_BEGIN, STACKSHOT_KCCONTAINER_TASK, task_uniqueid);
79*2c2f96dcSApple OSS Distributions	// add multiple data, or add_<type>_with_description()s here
80*2c2f96dcSApple OSS Distributions
81*2c2f96dcSApple OSS Distributions	kcdata_add_container_marker(kcdata_p, KCDATA_TYPE_CONTAINER_END, STACKSHOT_KCCONTAINER_TASK, task_uniqueid);
82*2c2f96dcSApple OSS Distributions
83*2c2f96dcSApple OSS Distributions
84*2c2f96dcSApple OSS DistributionsFeature description: Custom Data formats on demand
85*2c2f96dcSApple OSS Distributions--------------------
86*2c2f96dcSApple OSS Distributions
87*2c2f96dcSApple OSS DistributionsWith the self describing nature of format, the kernel provider can describe a data type (uniquely identified by a number) and use
88*2c2f96dcSApple OSS Distributionsit in the buffer for sending data. The consumer can parse the type information and have knowledge of describing incoming data.
89*2c2f96dcSApple OSS DistributionsFollowing is an example of how we can describe a kernel specific struct sample_disk_io_stats in buffer.
90*2c2f96dcSApple OSS Distributions
91*2c2f96dcSApple OSS Distributions	struct sample_disk_io_stats {
92*2c2f96dcSApple OSS Distributions	    uint64_t        disk_reads_count;
93*2c2f96dcSApple OSS Distributions	    uint64_t        disk_reads_size;
94*2c2f96dcSApple OSS Distributions	    uint64_t        io_priority_count[4];
95*2c2f96dcSApple OSS Distributions	    uint64_t        io_priority_size;
96*2c2f96dcSApple OSS Distributions	} __attribute__ ((packed));
97*2c2f96dcSApple OSS Distributions
98*2c2f96dcSApple OSS Distributions
99*2c2f96dcSApple OSS Distributions	struct kcdata_subtype_descriptor disk_io_stats_def[] = {
100*2c2f96dcSApple OSS Distributions	    {KCS_SUBTYPE_FLAGS_NONE, KC_ST_UINT64, 0 * sizeof(uint64_t), sizeof(uint64_t), "disk_reads_count"},
101*2c2f96dcSApple OSS Distributions	    {KCS_SUBTYPE_FLAGS_NONE, KC_ST_UINT64, 1 * sizeof(uint64_t), sizeof(uint64_t), "disk_reads_size"},
102*2c2f96dcSApple OSS Distributions	    {KCS_SUBTYPE_FLAGS_ARRAY, KC_ST_UINT64, 2 * sizeof(uint64_t), KCS_SUBTYPE_PACK_SIZE(4, sizeof(uint64_t)), "io_priority_count"},
103*2c2f96dcSApple OSS Distributions	    {KCS_SUBTYPE_FLAGS_ARRAY, KC_ST_UINT64, (2 + 4) * sizeof(uint64_t), sizeof(uint64_t), "io_priority_size"},
104*2c2f96dcSApple OSS Distributions	};
105*2c2f96dcSApple OSS Distributions
106*2c2f96dcSApple OSS DistributionsNow you can add this custom type definition into the buffer as
107*2c2f96dcSApple OSS Distributions	kcdata_add_type_definition(kcdata_p, KCTYPE_SAMPLE_DISK_IO_STATS, "sample_disk_io_stats",
108*2c2f96dcSApple OSS Distributions	         &disk_io_stats_def[0], sizeof(disk_io_stats_def)/sizeof(struct kcdata_subtype_descriptor));
109*2c2f96dcSApple OSS Distributions
110