xref: /aosp_15_r20/external/zucchini/README.md (revision a03ca8b91e029cd15055c20c78c2e087c84792e4)
1*a03ca8b9SKrzysztof Kosiński
2*a03ca8b9SKrzysztof Kosiński## Basic Definitions for Patching
3*a03ca8b9SKrzysztof Kosiński
4*a03ca8b9SKrzysztof Kosiński**Binary**: Executable image and data. Binaries may persist in an archive
5*a03ca8b9SKrzysztof Kosiński(e.g., chrome.7z), and need to be periodically updated. Formats for binaries
6*a03ca8b9SKrzysztof Kosińskiinclude {PE files EXE / DLL, ELF, DEX}. Architectures binaries include
7*a03ca8b9SKrzysztof Kosiński{x86, x64, ARM, AArch64, Dalvik}. A binary is also referred to as an executable
8*a03ca8b9SKrzysztof Kosińskior an image file.
9*a03ca8b9SKrzysztof Kosiński
10*a03ca8b9SKrzysztof Kosiński**Patching**: Sending a "new" file to clients who have an "old" file by
11*a03ca8b9SKrzysztof Kosińskicomputing and transmitting a "patch" that can be used to transform "old" into
12*a03ca8b9SKrzysztof Kosiński"new". Patches are compressed for transmission. A key performance metric is
13*a03ca8b9SKrzysztof Kosińskipatch size, which refers to the size of compressed patch file. For our
14*a03ca8b9SKrzysztof Kosińskiexperiments we use 7z.
15*a03ca8b9SKrzysztof Kosiński
16*a03ca8b9SKrzysztof Kosiński**Patch generation**: Computation of a "patch" from "old" and "new". This can be
17*a03ca8b9SKrzysztof Kosińskiexpensive (e.g., ~15-20 min for Chrome, using 1 GB of RAM), but since patch
18*a03ca8b9SKrzysztof Kosińskigeneration is a run-once step on the server-side when releasing "new" binaries,
19*a03ca8b9SKrzysztof Kosińskithe expense is not too critical.
20*a03ca8b9SKrzysztof Kosiński
21*a03ca8b9SKrzysztof Kosiński**Patch application**: Transformation from "old" binaries to "new", using a
22*a03ca8b9SKrzysztof Kosiński(downloaded) "patch". This is executed on client side on updates, so resource
23*a03ca8b9SKrzysztof Kosińskiconstraints (e.g., time, RAM, disk space) is more stringent. Also, fault-
24*a03ca8b9SKrzysztof Kosińskitolerance is important. This is usually achieved by an update system by having
25*a03ca8b9SKrzysztof Kosińskia fallback method of directly downloading "new" in case of patching failure.
26*a03ca8b9SKrzysztof Kosiński
27*a03ca8b9SKrzysztof Kosiński**Offset**: Position relative to the start of a file.
28*a03ca8b9SKrzysztof Kosiński
29*a03ca8b9SKrzysztof Kosiński**Local offset**: An offset relative to the start of a region of a file.
30*a03ca8b9SKrzysztof Kosiński
31*a03ca8b9SKrzysztof Kosiński**Element**: A region in a file with associated executable type, represented by
32*a03ca8b9SKrzysztof Kosińskithe tuple (exe_type, offset, length). Every Element in new file is associated
33*a03ca8b9SKrzysztof Kosińskiwith an Element in old file and patched independently.
34*a03ca8b9SKrzysztof Kosiński
35*a03ca8b9SKrzysztof Kosiński**Reference**: A directed connection between two offsets in a binary. For
36*a03ca8b9SKrzysztof Kosińskiexample, consider jump instructions in x86:
37*a03ca8b9SKrzysztof Kosiński
38*a03ca8b9SKrzysztof Kosiński    00401000: E9 3D 00 00 00     jmp         00401042
39*a03ca8b9SKrzysztof Kosiński
40*a03ca8b9SKrzysztof KosińskiHere, the 4 bytes `[3D 00 00 00]` starting at address `00401001` point to
41*a03ca8b9SKrzysztof Kosińskiaddress `00401042` in memory. This forms a reference from `offset(00401001)`
42*a03ca8b9SKrzysztof Kosiński(length 4) to `offset(00401042)`, where `offset(addr)` indicates the disk
43*a03ca8b9SKrzysztof Kosińskioffset corresponding to `addr`. A reference has a location, length (implicitly
44*a03ca8b9SKrzysztof Kosińskidetermined by reference type), body, and target.
45*a03ca8b9SKrzysztof Kosiński
46*a03ca8b9SKrzysztof Kosiński**Location**: The starting offset of bytes that store a reference. In the
47*a03ca8b9SKrzysztof Kosińskipreceding example, `offset(00401001)` is a location. Each location is the
48*a03ca8b9SKrzysztof Kosińskibeginning of a reference body.
49*a03ca8b9SKrzysztof Kosiński
50*a03ca8b9SKrzysztof Kosiński**Body**: The span of bytes that encodes reference data, i.e.,
51*a03ca8b9SKrzysztof Kosiński[location, location + length) =
52*a03ca8b9SKrzysztof Kosiński[location, location + 1, ..., location + length - 1].
53*a03ca8b9SKrzysztof KosińskiIn the preceding example, `length = 4`, so the reference body is
54*a03ca8b9SKrzysztof Kosiński`[00401001, 00401001 + 4) = [00401001, 00401002, 00401003, 00401004]`.
55*a03ca8b9SKrzysztof KosińskiAll reference bodies in an image must not overlap, and often regions boundaries
56*a03ca8b9SKrzysztof Kosińskiare required to not straddle a reference body.
57*a03ca8b9SKrzysztof Kosiński
58*a03ca8b9SKrzysztof Kosiński**Target**: The offset that's the destination of a reference. In the preceding
59*a03ca8b9SKrzysztof Kosińskiexample, `offset(00401042)` is the target. Different references can share common
60*a03ca8b9SKrzysztof Kosińskitargets. For example, in
61*a03ca8b9SKrzysztof Kosiński
62*a03ca8b9SKrzysztof Kosiński    00401000: E9 3D 00 00 00     jmp         00401042
63*a03ca8b9SKrzysztof Kosiński    00401005: EB 3B              jmp         00401042
64*a03ca8b9SKrzysztof Kosiński
65*a03ca8b9SKrzysztof Kosińskiwe have two references with different locations and bodies, but same target
66*a03ca8b9SKrzysztof Kosińskiof `00401042`.
67*a03ca8b9SKrzysztof Kosiński
68*a03ca8b9SKrzysztof KosińskiBecause the bytes that encode a reference depend on its target, and potentially
69*a03ca8b9SKrzysztof Kosińskion its location, they are more likely to get modified from an old version of a
70*a03ca8b9SKrzysztof Kosińskibinary to a newer version. This is why "naive" patching does not do well on
71*a03ca8b9SKrzysztof Kosińskibinaries.
72*a03ca8b9SKrzysztof Kosiński
73*a03ca8b9SKrzysztof Kosiński**Target Key**: An alternative representation of a Target for a fixed pool, as its
74*a03ca8b9SKrzysztof Kosińskiindex in the sorted list of Target offsets. Keys are useful since:
75*a03ca8b9SKrzysztof Kosiński  * Their numerical index are smaller than offsets, allowing more efficient
76*a03ca8b9SKrzysztof Kosiński  storage of target correction data in patch.
77*a03ca8b9SKrzysztof Kosiński  * They simplify association from Targets to Labels.
78*a03ca8b9SKrzysztof Kosiński
79*a03ca8b9SKrzysztof Kosiński**Disassembler**: Architecture specific data and operations, used to extract and
80*a03ca8b9SKrzysztof Kosińskicorrect references in a binary.
81*a03ca8b9SKrzysztof Kosiński
82*a03ca8b9SKrzysztof Kosiński**Type of reference**: The type of a reference determines the binary
83*a03ca8b9SKrzysztof Kosińskirepresentation used to encode its target. This affects how references are parsed
84*a03ca8b9SKrzysztof Kosińskiand written by a disassembler. There can be many types of references in the same
85*a03ca8b9SKrzysztof Kosińskibinary.
86*a03ca8b9SKrzysztof Kosiński
87*a03ca8b9SKrzysztof KosińskiA reference is represented by the tuple (disassembler, location, target, type).
88*a03ca8b9SKrzysztof KosińskiThis tuple contains sufficient information to write the reference in a binary.
89*a03ca8b9SKrzysztof Kosiński
90*a03ca8b9SKrzysztof Kosiński**Pool of targets**: Collection of targets that is assumed to have some semantic
91*a03ca8b9SKrzysztof Kosińskirelationship. Each reference type belong to exactly one reference pool. Targets
92*a03ca8b9SKrzysztof Kosińskifor references in the same pool are shared.
93*a03ca8b9SKrzysztof Kosiński
94*a03ca8b9SKrzysztof KosińskiFor example, the following describes two pools defined for Dalvik Executable
95*a03ca8b9SKrzysztof Kosińskiformat (DEX). Both pools spawn multiple types of references.
96*a03ca8b9SKrzysztof Kosiński
97*a03ca8b9SKrzysztof Kosiński1. Index in string table.
98*a03ca8b9SKrzysztof Kosiński  - From bytecode to string index using 16 bits.
99*a03ca8b9SKrzysztof Kosiński  - From bytecode to string index using 32 bits.
100*a03ca8b9SKrzysztof Kosiński  - From field item to string index using 32 bits.
101*a03ca8b9SKrzysztof Kosiński2. Address in code.
102*a03ca8b9SKrzysztof Kosiński  - Relative 16 bits pointer.
103*a03ca8b9SKrzysztof Kosiński  - Relative 32 bits pointer.
104*a03ca8b9SKrzysztof Kosiński
105*a03ca8b9SKrzysztof KosińskiBoundaries between different pools can be ambiguous. Having all targets belong
106*a03ca8b9SKrzysztof Kosińskito the same pool can reduce redundancy, but will use more memory and might
107*a03ca8b9SKrzysztof Kosińskicause larger corrections to happen, so this is a trade-off that can be resolved
108*a03ca8b9SKrzysztof Kosińskiwith benchmarks.
109*a03ca8b9SKrzysztof Kosiński
110*a03ca8b9SKrzysztof Kosiński**Abs32 references**: References whose targets are adjusted by the OS during
111*a03ca8b9SKrzysztof Kosińskiprogram load. In an image, a **relocation table** typically provides locations
112*a03ca8b9SKrzysztof Kosińskiof abs32 references. At each abs32 location, the stored bytes then encode
113*a03ca8b9SKrzysztof Kosińskisemantic information about the target (e.g., as RVA).
114*a03ca8b9SKrzysztof Kosiński
115*a03ca8b9SKrzysztof Kosiński**Rel32 references**: References embedded within machine code, in which targets
116*a03ca8b9SKrzysztof Kosińskiare encoded as some delta relative to the reference's location. Typical examples
117*a03ca8b9SKrzysztof Kosińskiof rel32 references are branching instructions and instruction pointer-relative
118*a03ca8b9SKrzysztof Kosińskimemory access.
119*a03ca8b9SKrzysztof Kosiński
120*a03ca8b9SKrzysztof Kosiński**Equivalence**: A (src_offset, dst_offset, length) tuple describing a region of
121*a03ca8b9SKrzysztof Kosiński"old" binary, at an offset of |src_offset|, that is similar to a region of "new"
122*a03ca8b9SKrzysztof Kosińskibinary, at an offset of |dst_offset|.
123*a03ca8b9SKrzysztof Kosiński
124*a03ca8b9SKrzysztof Kosiński**Raw delta unit**: Describes a raw modification to apply on the new image, as a
125*a03ca8b9SKrzysztof Kosińskipair (copy_offset, diff), where copy_offset describes the position in new file
126*a03ca8b9SKrzysztof Kosińskias an offset in the data that was copied from the old file, and diff is the
127*a03ca8b9SKrzysztof Kosińskibytewise difference to apply.
128*a03ca8b9SKrzysztof Kosiński
129*a03ca8b9SKrzysztof Kosiński**Associated Targets**: A target in "old" binary is associated with a target in
130*a03ca8b9SKrzysztof Kosiński"new" binary if both targets:
131*a03ca8b9SKrzysztof Kosiński1. are part of similar regions from the same equivalence, and
132*a03ca8b9SKrzysztof Kosiński2. have the same local offset (relative to respective start regions), and
133*a03ca8b9SKrzysztof Kosiński3. are not part of any larger region from a different equivalence.
134*a03ca8b9SKrzysztof KosińskiNot all targets are necessarily associated with another target.
135*a03ca8b9SKrzysztof Kosiński
136*a03ca8b9SKrzysztof Kosiński**Target Affinity**: Level of confidence in the association between two targets.
137*a03ca8b9SKrzysztof KosińskiThe affinity between targets that are potentially associated is measured based
138*a03ca8b9SKrzysztof Kosińskion surrounding content, as well as reference type.
139*a03ca8b9SKrzysztof Kosiński
140*a03ca8b9SKrzysztof Kosiński**Label**: An integer assigned for each Target in "old" and "new" binary as part
141*a03ca8b9SKrzysztof Kosińskiof generating a patch, and used to alias targets when searching for similar
142*a03ca8b9SKrzysztof Kosińskiregions that will form equivalences. Labels are assigned such that
143*a03ca8b9SKrzysztof Kosińskiassociated targets in old and new binaries share the same Label. Unmatched
144*a03ca8b9SKrzysztof KosińskiTargets have a Label of 0. For example, given
145*a03ca8b9SKrzysztof Kosiński  * "Old" targets = [0x1111, 0x3333, 0x5555, 0x7777],
146*a03ca8b9SKrzysztof Kosiński  * "New" targets = [0x2222, 0x4444, 0x6666, 0x8888],
147*a03ca8b9SKrzysztof Kosińskito represent matchings 0x1111 <=> 0x6666,  0x3333 <=> 0x2222, we'd assign
148*a03ca8b9SKrzysztof Kosiński  * Label 1 to 0x1111 (in "old") and 0x6666 (in "new"),
149*a03ca8b9SKrzysztof Kosiński  * Label 2 to 0x3333 (in "old") and 0x2222 (in "new").
150*a03ca8b9SKrzysztof Kosiński Represented as arrays indexed over Target Keys, we'd have:
151*a03ca8b9SKrzysztof Kosiński  * "Old" labels = [1, 2, 0 ,0],
152*a03ca8b9SKrzysztof Kosiński  * "New" labels = [2, 0, 1, 0].
153*a03ca8b9SKrzysztof Kosiński
154*a03ca8b9SKrzysztof Kosiński**Encoded Image**: The result of projecting the content of an image to scalar
155*a03ca8b9SKrzysztof Kosińskivalues that describe content on a higher level of abstraction, masking away
156*a03ca8b9SKrzysztof Kosińskiundesirable noise in raw content. Notably, the projection encodes references
157*a03ca8b9SKrzysztof Kosińskibased on their associated label.
158*a03ca8b9SKrzysztof Kosiński
159*a03ca8b9SKrzysztof Kosiński## Interfaces
160*a03ca8b9SKrzysztof Kosiński
161*a03ca8b9SKrzysztof Kosińskizucchini_lib: Core Zucchini library that operate on buffers to generate and
162*a03ca8b9SKrzysztof Kosińskiapply patches.
163*a03ca8b9SKrzysztof Kosiński
164*a03ca8b9SKrzysztof Kosińskizucchini_io: Wrapper on zucchini_lib that handles file I/O, using memory-mapped
165*a03ca8b9SKrzysztof KosińskiI/O to interface with zucchini_lib.
166*a03ca8b9SKrzysztof Kosiński
167*a03ca8b9SKrzysztof Kosińskizucchini: Stand-alone executable that parses command-line arguments, and passes
168*a03ca8b9SKrzysztof Kosińskithe results to zucchini_io. Also implements various helper flows.
169*a03ca8b9SKrzysztof Kosiński
170*a03ca8b9SKrzysztof Kosiński## Zucchini Ensemble Patch Format
171*a03ca8b9SKrzysztof Kosiński
172*a03ca8b9SKrzysztof Kosiński### Types
173*a03ca8b9SKrzysztof Kosiński
174*a03ca8b9SKrzysztof Kosiński**int8**: 8-bit unsigned int.
175*a03ca8b9SKrzysztof Kosiński
176*a03ca8b9SKrzysztof Kosiński**uint32**: 32-bit unsigned int, little-endian.
177*a03ca8b9SKrzysztof Kosiński
178*a03ca8b9SKrzysztof Kosiński**int32**:  32-bit signed int, little-endian.
179*a03ca8b9SKrzysztof Kosiński
180*a03ca8b9SKrzysztof Kosiński**Varints**: This is a generic variable-length encoding for integer quantities
181*a03ca8b9SKrzysztof Kosińskithat strips away leading (most-significant) null bytes.
182*a03ca8b9SKrzysztof KosińskiThe Varints format is borrowed from protocol-buffers, see
183*a03ca8b9SKrzysztof Kosiński[documentation](https://developers.google.com/protocol-buffers/docs/encoding#varints)
184*a03ca8b9SKrzysztof Kosińskifor more info.
185*a03ca8b9SKrzysztof Kosiński
186*a03ca8b9SKrzysztof Kosiński**varuint32**: A uint32 encoded using Varints format.
187*a03ca8b9SKrzysztof Kosiński
188*a03ca8b9SKrzysztof Kosiński**varint32**: A int32 encoded using Varints format.
189*a03ca8b9SKrzysztof Kosiński
190*a03ca8b9SKrzysztof Kosiński### File Layout
191*a03ca8b9SKrzysztof Kosiński
192*a03ca8b9SKrzysztof KosińskiName | Format | Description
193*a03ca8b9SKrzysztof Kosiński--- | --- | ---
194*a03ca8b9SKrzysztof Kosińskiheader | PatchHeader | The header.
195*a03ca8b9SKrzysztof Kosińskielements_count | uint32 | Number of patch units.
196*a03ca8b9SKrzysztof Kosińskielements | PatchElement[elements_count] | List of all patch elements.
197*a03ca8b9SKrzysztof Kosiński
198*a03ca8b9SKrzysztof KosińskiPosition of elements in new file is ascending.
199*a03ca8b9SKrzysztof Kosiński
200*a03ca8b9SKrzysztof Kosiński### Structures
201*a03ca8b9SKrzysztof Kosiński
202*a03ca8b9SKrzysztof Kosiński**PatchHeader**
203*a03ca8b9SKrzysztof Kosiński
204*a03ca8b9SKrzysztof KosińskiName | Format | Description
205*a03ca8b9SKrzysztof Kosiński--- | --- | ---
206*a03ca8b9SKrzysztof Kosińskimagic | uint32 = kMagic | Magic value.
207*a03ca8b9SKrzysztof Kosińskimajor_version | uint16 | Major version number indicating breaking changes.
208*a03ca8b9SKrzysztof Kosińskiminor_version | uint16 | Minor version number indicating possibly breaking changes.
209*a03ca8b9SKrzysztof Kosińskiold_size | uint32 | Size of old file in bytes.
210*a03ca8b9SKrzysztof Kosińskiold_crc | uint32 | CRC32 of old file.
211*a03ca8b9SKrzysztof Kosińskinew_size | uint32 | Size of new file in bytes.
212*a03ca8b9SKrzysztof Kosińskinew_crc | uint32 | CRC32 of new file.
213*a03ca8b9SKrzysztof Kosiński
214*a03ca8b9SKrzysztof Kosiński**kMagic** == `'Z' | ('u' << 8) | ('c' << 16) | ('c' << 24)`
215*a03ca8b9SKrzysztof Kosiński
216*a03ca8b9SKrzysztof Kosiński**PatchElement**
217*a03ca8b9SKrzysztof KosińskiContains all the information required to produce a single element in new file.
218*a03ca8b9SKrzysztof Kosiński
219*a03ca8b9SKrzysztof KosińskiName | Format | Description
220*a03ca8b9SKrzysztof Kosiński--- | --- | ---
221*a03ca8b9SKrzysztof Kosińskiheader | PatchElementHeader | The header.
222*a03ca8b9SKrzysztof Kosińskiequivalences | EquivalenceList | List of equivalences.
223*a03ca8b9SKrzysztof Kosińskiraw_deltas | RawDeltaList | List of raw deltas.
224*a03ca8b9SKrzysztof Kosińskireference_deltas | ReferenceDeltaList | List of reference deltas.
225*a03ca8b9SKrzysztof Kosińskipool_count | uint32 | Number of pools.
226*a03ca8b9SKrzysztof Kosińskiextra_targets | ExtraTargetList[pool_count] | Lists of extra targets.
227*a03ca8b9SKrzysztof Kosiński
228*a03ca8b9SKrzysztof Kosiński**PatchElementHeader**
229*a03ca8b9SKrzysztof KosińskiDescribes a correspondence between an element in old and in new files. Some
230*a03ca8b9SKrzysztof Kosińskiredundancy arise from storing |new_offset|, but it is necessary to make
231*a03ca8b9SKrzysztof KosińskiPatchElement self contained.
232*a03ca8b9SKrzysztof Kosiński
233*a03ca8b9SKrzysztof KosińskiName | Format | Description
234*a03ca8b9SKrzysztof Kosiński--- | --- | ---
235*a03ca8b9SKrzysztof Kosińskiold_offset | uint32 | Starting offset of the element in old file.
236*a03ca8b9SKrzysztof Kosińskiold_length | uint32 | Length of the element in old file.
237*a03ca8b9SKrzysztof Kosińskinew_offset | uint32 | Starting offset of the element in new file.
238*a03ca8b9SKrzysztof Kosińskinew_length | uint32 | Length of the element in new file.
239*a03ca8b9SKrzysztof Kosińskiexe_type | uint32 | Executable type for this unit, see `enum ExecutableType`.
240*a03ca8b9SKrzysztof Kosińskiversion | uint16 | Version specific to the executable type for this unit.
241*a03ca8b9SKrzysztof Kosiński
242*a03ca8b9SKrzysztof Kosiński**EquivalenceList**
243*a03ca8b9SKrzysztof KosińskiEncodes a list of equivalences, where dst offsets (in new image) are ascending.
244*a03ca8b9SKrzysztof Kosiński
245*a03ca8b9SKrzysztof KosińskiName | Format | Description
246*a03ca8b9SKrzysztof Kosiński--- | --- | ---
247*a03ca8b9SKrzysztof Kosińskisrc_skip | Buffer<varint32> | Src offset for each equivalence, delta encoded.
248*a03ca8b9SKrzysztof Kosińskidst_skip | Buffer<varuint32> | Dst offset for each equivalence, delta encoded.
249*a03ca8b9SKrzysztof Kosińskicopy_count | Buffer<varuint32> | Length for each equivalence.
250*a03ca8b9SKrzysztof Kosiński
251*a03ca8b9SKrzysztof Kosiński**RawDeltaList**
252*a03ca8b9SKrzysztof KosińskiEncodes a list of raw delta units, with ascending copy offsets.
253*a03ca8b9SKrzysztof Kosiński
254*a03ca8b9SKrzysztof KosińskiName | Format | Description
255*a03ca8b9SKrzysztof Kosiński--- | --- | ---
256*a03ca8b9SKrzysztof Kosińskiraw_delta_skip | Buffer<varuint32> | Copy offset for each delta unit, delta encoded and biased by -1.
257*a03ca8b9SKrzysztof Kosińskiraw_delta_diff | Buffer<int8> | Bytewise difference for each delta unit.
258*a03ca8b9SKrzysztof Kosiński
259*a03ca8b9SKrzysztof Kosiński**ReferenceDeltaList**
260*a03ca8b9SKrzysztof KosińskiEncodes a list of reference deltas, in the order they appear in the new
261*a03ca8b9SKrzysztof Kosińskiimage file. A reference delta is a signed integer representing a jump through a
262*a03ca8b9SKrzysztof Kosińskilist of targets.
263*a03ca8b9SKrzysztof Kosiński
264*a03ca8b9SKrzysztof KosińskiName | Format | Description
265*a03ca8b9SKrzysztof Kosiński--- | --- | ---
266*a03ca8b9SKrzysztof Kosińskireference_delta | Buffer<varuint32> | Vector of reference deltas.
267*a03ca8b9SKrzysztof Kosiński
268*a03ca8b9SKrzysztof Kosiński**ExtraTargetList**
269*a03ca8b9SKrzysztof KosińskiEncodes a list of additional targets in the new image file, in ascending
270*a03ca8b9SKrzysztof Kosińskiorder.
271*a03ca8b9SKrzysztof Kosiński
272*a03ca8b9SKrzysztof KosińskiName | Format | Description
273*a03ca8b9SKrzysztof Kosiński--- | --- | ---
274*a03ca8b9SKrzysztof Kosińskipool_tag | uint8_t | Unique identifier for this pool of targets.
275*a03ca8b9SKrzysztof Kosińskiextra_targets | Buffer<varuint32> | Additional targets, delta encoded and biased by -1.
276*a03ca8b9SKrzysztof Kosiński
277*a03ca8b9SKrzysztof Kosiński**Buffer<T>**
278*a03ca8b9SKrzysztof KosińskiA generic vector of data.
279*a03ca8b9SKrzysztof Kosiński
280*a03ca8b9SKrzysztof KosińskiName | Format | Description
281*a03ca8b9SKrzysztof Kosiński--- | --- | ---
282*a03ca8b9SKrzysztof Kosińskisize |uint32 | Size of content in bytes.
283*a03ca8b9SKrzysztof Kosińskicontent |T[] | List of integers.
284*a03ca8b9SKrzysztof Kosiński
285*a03ca8b9SKrzysztof Kosiński# Format Changelog
286*a03ca8b9SKrzysztof KosińskiAll breaking changes to zucchini patch format will be documented in this
287*a03ca8b9SKrzysztof Kosińskisection.
288*a03ca8b9SKrzysztof Kosiński
289*a03ca8b9SKrzysztof KosińskiThe format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
290*a03ca8b9SKrzysztof Kosiński
291*a03ca8b9SKrzysztof Kosiński## [Unreleased]
292*a03ca8b9SKrzysztof Kosiński
293*a03ca8b9SKrzysztof Kosiński## [1.0] - 2021-10-27
294*a03ca8b9SKrzysztof Kosiński### Added
295*a03ca8b9SKrzysztof KosińskiMajor/Minor version is encoded in PatchHeader
296*a03ca8b9SKrzysztof KosińskiDisassembler version associated with an element version is encoded in PatchElementHeader.
297